iconfont图标集合下载器

自动获取整个iconfont集合的完整图标包,目前仅支持图标,不支持3D等其他类型。

  1. // ==UserScript==
  2. // @name iconfont图标集合下载器
  3. // @namespace https.com.github.shenjingmayi
  4. // @version 1.0
  5. // @description 自动获取整个iconfont集合的完整图标包,目前仅支持图标,不支持3D等其他类型。
  6. // @author sjmy
  7. // @match *://www.iconfont.cn/collections/detail*
  8. // @require https://cdn.jsdelivr.net/npm/jszip@3.2.2/dist/jszip.min.js
  9. // @grant GM_xmlhttpRequest
  10. // @grant GM_addStyle
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16. const createControlPanel = () => {
  17. const panel = document.createElement('div');
  18. GM_addStyle(`
  19. #sjmy-dl-panel {
  20. position: fixed;
  21. top: 20px;
  22. left: 20px;
  23. z-index: 9999;
  24. background: rgba(255,255,255,0.0);
  25. padding: 10px !important;
  26. min-width: 150px;
  27. border-radius: 8px;
  28. box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  29. }
  30. #sjmy-dl-btn {
  31. background: #1890ff;
  32. color: white;
  33. border: none;
  34. border-radius: 4px;
  35. cursor: pointer;
  36. transition: all 0.3s;
  37. padding: 6px 12px !important;
  38. font-size: 13px !important;
  39. width: auto !important;
  40. box-shadow: 0 1px 2px rgba(0,0,0,0.1);
  41. }
  42. #sjmy-dl-btn:disabled {
  43. background: #8c8c8c;
  44. cursor: not-allowed;
  45. }
  46. #sjmy-dl-btn:after {
  47. content: '';
  48. display: inline-block;
  49. margin-left: 8px;
  50. width: 8px;
  51. height: 8px;
  52. border-radius: 50%;
  53. }
  54. #sjmy-dl-btn[disabled]:after {
  55. background: #ff4d4f;
  56. }
  57. #sjmy-dl-btn:not([disabled]):after {
  58. background: #52c41a;
  59. }
  60. `);
  61. panel.id = 'sjmy-dl-panel';
  62. return panel;
  63. };
  64. const sanitizeFilename = (name) => {
  65. return name.replace(/[\\/:"*?<> |]/g, '_');
  66. };
  67. const createAuthorLinkFile = (creator) => {
  68. const content = [
  69. '[InternetShortcut]',
  70. `URL=https://www.iconfont.cn/user/detail?userViewType=collections&uid=${creator.id}&nid=${creator.nid}`
  71. ].join('\n');
  72. return {
  73. name: `作者主页-${sanitizeFilename(creator.nickname)}.url`,
  74. content: content
  75. };
  76. };
  77. const createCollectionInfoFile = (data, cid) => {
  78. const meta = data.collection;
  79. const creator = data.creator || {};
  80. const infoContent = [
  81. `集合链接:https://www.iconfont.cn/collections/detail?cid=${cid}`,
  82. `集合名称:${meta.name || '未命名集合'}`,
  83. `作者:${creator.nickname || '匿名作者'}`,
  84. `作者简介:${(creator.bio || '暂无简介').replace(/\n/g, ' ')}`,
  85. `集合内图片数量:${meta.icons_count || '未获取到信息'}`,
  86. `版权类型:${meta.copyright === 'original' ? '原创' : '非原创'}`,
  87. `是否收费:${meta.fees === 'free' ? '免费' : '付费'}`
  88. ].join('\n\n');
  89. return {
  90. name: '集合基本信息.txt',
  91. content: infoContent
  92. };
  93. };
  94. const main = async () => {
  95. const panel = createControlPanel();
  96. const btn = document.createElement('button');
  97. btn.id = 'sjmy-dl-btn';
  98. btn.innerHTML = '初始化中...';
  99. btn.disabled = true;
  100. panel.appendChild(btn);
  101. document.body.appendChild(panel);
  102. try {
  103. const cid = new URLSearchParams(window.location.search).get('cid') || location.pathname.split('/').pop();
  104. if (!cid) throw new Error('CID_NOT_FOUND');
  105. btn.innerHTML = '准备下载';
  106. btn.disabled = false;
  107. btn.onclick = async () => {
  108. btn.innerHTML = '获取数据中...';
  109. btn.disabled = true;
  110. try {
  111. const response = await fetch(`https://www.iconfont.cn/api/collection/detail.json?id=${cid}`);
  112. if (!response.ok) throw new Error('API_ERROR');
  113. const { data } = await response.json();
  114. const collectionName = sanitizeFilename(data.collection?.name || `collection-${cid}`);
  115. const feeStatus = data.collection?.fees === 'free' ? '免费' : '付费';
  116. const fileName = `${collectionName}-${feeStatus}`;
  117. const zip = new JSZip();
  118. data.icons.forEach((icon, index) => {
  119. zip.file(`${sanitizeFilename(icon.name || `icon-${index}`)}.svg`, icon.show_svg);
  120. });
  121. if (data.creator) {
  122. const authorFile = createAuthorLinkFile(data.creator);
  123. zip.file(authorFile.name, authorFile.content);
  124. }
  125. const infoFile = createCollectionInfoFile(data, cid);
  126. zip.file(infoFile.name, infoFile.content);
  127. btn.innerHTML = '打包中...';
  128. const content = await zip.generateAsync({ type: 'blob' });
  129. const link = document.createElement('a');
  130. link.download = `${fileName}.zip`;
  131. link.href = URL.createObjectURL(content);
  132. link.click();
  133.  
  134. btn.innerHTML = '下载完成✔';
  135. setTimeout(() => {
  136. btn.innerHTML = '重新下载';
  137. btn.disabled = false;
  138. }, 2000);
  139. } catch (e) {
  140. console.error('[ 下载器错误]', e);
  141. btn.innerHTML = `失败: ${e.message}`;
  142. setTimeout(() => {
  143. btn.innerHTML = '重试下载';
  144. btn.disabled = false;
  145. }, 2000);
  146. }
  147. };
  148. } catch (e) {
  149. btn.innerHTML = '初始化失败';
  150. console.error('[ 初始化错误]', e);
  151. }
  152. };
  153. if (typeof JSZip !== 'undefined') {
  154. main();
  155. } else {
  156. window.addEventListener('load', main);
  157. }
  158. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址