generate-icons.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /**
  2. * 图标生成脚本
  3. * 从 SVG 生成各种尺寸的 PNG 图标
  4. *
  5. * 使用方法:
  6. * cd client
  7. * npm install sharp --save-dev
  8. * node scripts/generate-icons.js
  9. */
  10. const fs = require('fs');
  11. const path = require('path');
  12. // 检查是否安装了 sharp
  13. let sharp;
  14. try {
  15. sharp = require('sharp');
  16. } catch (e) {
  17. console.error('请先安装 sharp: npm install sharp --save-dev');
  18. process.exit(1);
  19. }
  20. const SVG_PATH = path.join(__dirname, '../public/favicon.svg');
  21. const OUTPUT_DIR = path.join(__dirname, '../public/icons');
  22. const BUILD_DIR = path.join(__dirname, '../build');
  23. // 需要生成的图标尺寸
  24. const ICON_SIZES = {
  25. // 应用图标
  26. 'icon-16.png': 16,
  27. 'icon-24.png': 24,
  28. 'icon-32.png': 32,
  29. 'icon-48.png': 48,
  30. 'icon-64.png': 64,
  31. 'icon-128.png': 128,
  32. 'icon-256.png': 256,
  33. 'icon-512.png': 512,
  34. // 托盘图标 (Windows 需要 16x16 或 32x32)
  35. 'tray-icon.png': 32,
  36. 'tray-icon@2x.png': 64,
  37. // README logo
  38. 'logo.png': 128,
  39. };
  40. async function generateIcons() {
  41. // 确保输出目录存在
  42. if (!fs.existsSync(OUTPUT_DIR)) {
  43. fs.mkdirSync(OUTPUT_DIR, { recursive: true });
  44. }
  45. if (!fs.existsSync(BUILD_DIR)) {
  46. fs.mkdirSync(BUILD_DIR, { recursive: true });
  47. }
  48. // 读取 SVG 文件
  49. const svgBuffer = fs.readFileSync(SVG_PATH);
  50. console.log('开始生成图标...\n');
  51. // 生成各尺寸 PNG
  52. for (const [filename, size] of Object.entries(ICON_SIZES)) {
  53. const outputPath = path.join(OUTPUT_DIR, filename);
  54. await sharp(svgBuffer)
  55. .resize(size, size)
  56. .png()
  57. .toFile(outputPath);
  58. console.log(`✓ ${filename} (${size}x${size})`);
  59. }
  60. // 复制主图标到 build 目录
  61. const icon256Path = path.join(OUTPUT_DIR, 'icon-256.png');
  62. const buildIconPath = path.join(BUILD_DIR, 'icon.png');
  63. fs.copyFileSync(icon256Path, buildIconPath);
  64. console.log(`\n✓ 复制 icon.png 到 build 目录`);
  65. // 复制 logo 到根目录用于 README
  66. const logoPath = path.join(OUTPUT_DIR, 'logo.png');
  67. const readmeLogoPath = path.join(__dirname, '../../docs/logo.png');
  68. const docsDir = path.join(__dirname, '../../docs');
  69. if (!fs.existsSync(docsDir)) {
  70. fs.mkdirSync(docsDir, { recursive: true });
  71. }
  72. fs.copyFileSync(logoPath, readmeLogoPath);
  73. console.log(`✓ 复制 logo.png 到 docs 目录`);
  74. console.log('\n图标生成完成!');
  75. console.log('\n生成的文件:');
  76. console.log(` - client/public/icons/ (应用图标)`);
  77. console.log(` - client/build/icon.png (打包用图标)`);
  78. console.log(` - docs/logo.png (README logo)`);
  79. console.log('\n下一步:');
  80. console.log(' 1. 使用在线工具将 icon-256.png 转换为 icon.ico (Windows)');
  81. console.log(' 推荐: https://convertio.co/png-ico/');
  82. console.log(' 2. 将生成的 icon.ico 放到 client/build/ 目录');
  83. }
  84. generateIcons().catch(console.error);