From 827b793b9da98e4b81c77d7831a34fd2f1ec525a Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 24 Oct 2025 16:32:24 +0800 Subject: [PATCH] feat: update icon --- example/lib/icons.dart | 69 ++++++++------- example/pubspec.lock | 28 +++---- fonts/iconfont.ttf | Bin 13856 -> 15744 bytes generate.sh | 21 +++++ generate/icons.dart | 107 ++++++++++++++++++++++++ iconfont.json | 135 ++++++++++++++++++++++-------- lib/src/yx_icon_fonts_data.dart | 115 +++++++++++++++++-------- pubspec.lock | 26 +++--- pubspec.yaml | 2 +- scripts/generate_wrapper.dart | 144 ++++++++++++++++++++++++++++++++ 10 files changed, 518 insertions(+), 129 deletions(-) mode change 100644 => 100755 generate.sh create mode 100644 generate/icons.dart create mode 100644 scripts/generate_wrapper.dart diff --git a/example/lib/icons.dart b/example/lib/icons.dart index 64c62f1..7225f1d 100644 --- a/example/lib/icons.dart +++ b/example/lib/icons.dart @@ -5,24 +5,25 @@ import 'package:yx_icon_fonts_example/example_icon.dart'; final icons = [ // 其他图标 - ExampleIcon(YXIconFonts.iconVoicepause, 'icon voicepause'), + ExampleIcon(YXIconFonts.icon44Search, 'icon 44 search'), + ExampleIcon(YXIconFonts.icon36ClearPeople, 'icon 36 clear people'), + ExampleIcon(YXIconFonts.icon32Publish, 'icon 32 publish'), + ExampleIcon(YXIconFonts.icon32Close, 'icon 32 close'), + ExampleIcon(YXIconFonts.icon32Output, 'icon 32 output'), + ExampleIcon(YXIconFonts.icon24Download, 'icon 24 download'), + ExampleIcon(YXIconFonts.iconVoicePause, 'icon voice pause'), ExampleIcon(YXIconFonts.iconVoice, 'icon voice'), - ExampleIcon(YXIconFonts.Subtract, 'Subtract'), + ExampleIcon(YXIconFonts.iconSubtract, 'icon subtract'), + ExampleIcon(YXIconFonts.icon44CancelAccount, 'icon 44 cancel account'), ExampleIcon(YXIconFonts.icon24Search, 'icon 24 search'), ExampleIcon(YXIconFonts.icon24Up, 'icon 24 up'), - - // 编辑相关图标 - ExampleIcon(YXIconFonts.icon44Edit, 'icon 44 edit'), - ExampleIcon(YXIconFonts.icon36Editline, 'icon 36 editline'), - ExampleIcon(YXIconFonts.icon24Edit, 'icon 24 edit'), - - // 删除相关图标 - ExampleIcon(YXIconFonts.icon44Delete, 'icon 44 delete'), - ExampleIcon(YXIconFonts.icon36Delete, 'icon 36 delete'), - ExampleIcon(YXIconFonts.icon24Delete, 'icon 24 delete'), + ExampleIcon(YXIconFonts.icon24Minus, 'icon 24 minus'), + ExampleIcon(YXIconFonts.icon36OnlySee, 'icon 36 only see'), + ExampleIcon(YXIconFonts.icon24Plus, 'icon 24 plus'), // 个人中心相关图标 - ExampleIcon(YXIconFonts.icon44MeQuit, 'icon 44 me quit'), + ExampleIcon(YXIconFonts.icon44MeLogOut, 'icon 44 me log out'), + ExampleIcon(YXIconFonts.icon44MeSwitch, 'icon 44 me switch'), ExampleIcon(YXIconFonts.icon44MePassword, 'icon 44 me password'), ExampleIcon(YXIconFonts.icon44MeHelp, 'icon 44 me help'), ExampleIcon(YXIconFonts.icon44MeVersion, 'icon 44 me version'), @@ -31,27 +32,39 @@ final icons = [ ExampleIcon(YXIconFonts.icon44MeSafe, 'icon 44 me safe'), ExampleIcon(YXIconFonts.icon44MePhone, 'icon 44 me phone'), + // 分享相关图标 + ExampleIcon(YXIconFonts.icon44WechatShareWhite, 'icon 44 wechat share white'), + ExampleIcon(YXIconFonts.icon44Share, 'icon 44 share'), + + // 编辑相关图标 + ExampleIcon(YXIconFonts.icon44Edit, 'icon 44 edit'), + ExampleIcon(YXIconFonts.icon36EditLine, 'icon 36 edit line'), + ExampleIcon(YXIconFonts.icon24Edit, 'icon 24 edit'), + + // 删除相关图标 + ExampleIcon(YXIconFonts.icon44Delete, 'icon 44 delete'), + ExampleIcon(YXIconFonts.icon36Delete, 'icon 36 delete'), + ExampleIcon(YXIconFonts.icon24Delete, 'icon 24 delete'), + // 消息相关图标 ExampleIcon(YXIconFonts.iconMsgContacts, 'icon msg contacts'), - ExampleIcon(YXIconFonts.iconMsgViedo, 'icon msg viedo'), + ExampleIcon(YXIconFonts.iconMsgVideo, 'icon msg video'), ExampleIcon(YXIconFonts.iconMsgSearch, 'icon msg search'), ExampleIcon(YXIconFonts.iconMsgCall, 'icon msg call'), ExampleIcon(YXIconFonts.iconMsgPhoto, 'icon msg photo'), ExampleIcon(YXIconFonts.iconMsgImg, 'icon msg img'), ExampleIcon(YXIconFonts.iconMsgFile, 'icon msg file'), - ExampleIcon(YXIconFonts.icon56Msgadd, 'icon 56 msgadd'), - ExampleIcon(YXIconFonts.icon56Msgface, 'icon 56 msgface'), - ExampleIcon(YXIconFonts.icon56Msgvoice, 'icon 56 msgvoice'), + ExampleIcon(YXIconFonts.icon56MsgAdd, 'icon 56 msg add'), + ExampleIcon(YXIconFonts.icon56MsgFace, 'icon 56 msg face'), + ExampleIcon(YXIconFonts.icon56MsgVoice, 'icon 56 msg voice'), // 箭头相关图标 - ExampleIcon(YXIconFonts.icon32Arrowright, 'icon 32 arrowright'), - ExampleIcon(YXIconFonts.icon44Arrowleft, 'icon 44 arrowleft'), - ExampleIcon(YXIconFonts.icon44Arrowright, 'icon 44 arrowright'), - ExampleIcon(YXIconFonts.icon24Arrowleft, 'icon 24 arrowleft'), - ExampleIcon(YXIconFonts.icon24Arrowdown, 'icon 24 arrowdown'), - - // 特殊字符图标 - ExampleIcon(YXIconFonts.icon24, 'icon 24 -'), + ExampleIcon(YXIconFonts.icon32ArrowRight, 'icon 32 arrow right'), + ExampleIcon(YXIconFonts.icon44ArrowLeft, 'icon 44 arrow left'), + ExampleIcon(YXIconFonts.icon44ArrowRight, 'icon 44 arrow right'), + ExampleIcon(YXIconFonts.icon44ArrowDownLine, 'icon 44 arrow down line'), + ExampleIcon(YXIconFonts.icon24ArrowRight, 'icon 24 arrow right'), + ExampleIcon(YXIconFonts.icon24ArrowDown, 'icon 24 arrow down'), // 团队和用户相关图标 ExampleIcon(YXIconFonts.icon36Team, 'icon 36 team'), @@ -60,12 +73,11 @@ final icons = [ // 功能图标 ExampleIcon(YXIconFonts.icon32Filter, 'icon 32 filter'), ExampleIcon(YXIconFonts.icon36Question, 'icon 36 question'), - ExampleIcon(YXIconFonts.icon36Onlysee, 'icon 36 onlysee'), ExampleIcon(YXIconFonts.icon36Hint, 'icon 36 hint'), ExampleIcon(YXIconFonts.icon24Switch, 'icon 24 switch'), // 退出相关图标 - ExampleIcon(YXIconFonts.icon44Quitlite, 'icon 44 quitlite'), + ExampleIcon(YXIconFonts.icon44QuitLite, 'icon 44 quit lite'), ExampleIcon(YXIconFonts.icon32Quit, 'icon 32 quit'), ExampleIcon(YXIconFonts.icon44Quit, 'icon 44 quit'), @@ -79,9 +91,6 @@ final icons = [ // 日历相关图标 ExampleIcon(YXIconFonts.icon44Calendar, 'icon 44 calendar'), - // 分享相关图标 - ExampleIcon(YXIconFonts.icon44Share, 'icon 44 share'), - // 添加相关图标 ExampleIcon(YXIconFonts.icon24Add, 'icon 24 add'), ExampleIcon(YXIconFonts.icon44Add, 'icon 44 add'), diff --git a/example/pubspec.lock b/example/pubspec.lock index 8c14e31..bd0c5ee 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -71,26 +71,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" url: "https://pub.flutter-io.cn" source: hosted - version: "10.0.9" + version: "11.0.2" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -180,33 +180,33 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.4" + version: "0.7.6" vector_math: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: name: vm_service - sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" url: "https://pub.flutter-io.cn" source: hosted - version: "15.0.0" + version: "15.0.2" yx_icon_fonts: dependency: "direct main" description: path: ".." relative: true source: path - version: "1.0.4" + version: "1.0.5" sdks: - dart: ">=3.7.0-0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/fonts/iconfont.ttf b/fonts/iconfont.ttf index 4207b56c0c0218ddaa5112e2995319b8eb0be838..5da9adfaad14143d179974f5d563527dd3842f5d 100644 GIT binary patch delta 3262 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 i&v`hN>}meje(K1hS}8BLQ>kqoq=3.7.0-0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index 269fad5..6c1accb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: yx_icon_fonts description: 学习官OA系统图标字体库,基于iconfont.ttf和iconfont.json生成 -version: 1.0.4 +version: 1.0.5 homepage: https://gitea.23544.com/wangyang/yx_icon_fonts_flutter environment: diff --git a/scripts/generate_wrapper.dart b/scripts/generate_wrapper.dart new file mode 100644 index 0000000..5b87fba --- /dev/null +++ b/scripts/generate_wrapper.dart @@ -0,0 +1,144 @@ +import 'dart:io'; +import 'utils.dart'; + +/// 自动生成外部使用的图标封装文件 +/// +/// 从 iconfont.json 文件读取图标信息,生成 FontIcons 封装类 +/// 生成位置:项目根目录的 icons.dart +void main() { + final iconData = readIconFontJson(); + final glyphs = getGlyphs(iconData); + final definedIcons = getDefinedIconNames(); + + _generateWrapperFile(glyphs, definedIcons); + + print('✅ 外部图标封装文件生成成功: \x1B[32mgenerate/icons.dart\x1B[0m'); + print('📊 共生成 ${definedIcons.length} 个图标常量'); +} + +/// 生成 icons.dart 文件 +void _generateWrapperFile(List glyphs, Set definedIcons) { + final buffer = StringBuffer(); + + // 文件头部 + buffer.writeln("// ignore_for_file: constant_identifier_names"); + buffer.writeln(); + buffer.writeln("import 'package:flutter/material.dart';"); + buffer.writeln("import 'package:yx_icon_fonts/yx_icon_fonts.dart';"); + buffer.writeln(); + buffer.writeln("class FontIcons {"); + buffer.writeln(" // 私有构造函数,防止实例化"); + buffer.writeln(" FontIcons._();"); + buffer.writeln(); + + // 按类别分组图标 + final categories = _categorizeIcons(glyphs, definedIcons); + + // 定义类别显示顺序 + final categoryOrder = [ + '其他图标', + '编辑相关图标', + '删除相关图标', + '个人中心相关图标', + '消息相关图标', + '箭头相关图标', + '特殊字符图标', + '团队和用户相关图标', + '功能图标', + '退出相关图标', + '更多和菜单相关图标', + '复制相关图标', + '日历相关图标', + '分享相关图标', + '添加相关图标', + '键盘相关图标', + ]; + + // 按顺序生成图标 + for (final category in categoryOrder) { + if (categories.containsKey(category) && categories[category]!.isNotEmpty) { + buffer.writeln(" // $category"); + for (final iconName in categories[category]!) { + buffer.writeln(" static const IconData $iconName = YXIconFonts.$iconName;"); + } + buffer.writeln(); + } + } + + buffer.writeln("}"); + + // 确保 generate 目录存在 + final dir = Directory('generate'); + if (!dir.existsSync()) { + dir.createSync(recursive: true); + } + + // 写入文件 + final file = File('generate/icons.dart'); + file.writeAsStringSync(buffer.toString()); +} + +/// 将图标按类别分组 +Map> _categorizeIcons(List glyphs, Set definedIcons) { + final categories = >{}; + + for (final glyph in glyphs) { + final name = glyph['font_class'] as String; + final camelCaseName = toLegalDartName(name); + + // 跳过未定义的图标 + if (!definedIcons.contains(camelCaseName)) continue; + + // 确定类别 + String category = _getCategory(name); + + categories.putIfAbsent(category, () => []); + categories[category]!.add(camelCaseName); + } + + return categories; +} + +/// 根据图标名称确定类别 +String _getCategory(String name) { + final lowerName = name.toLowerCase(); + + if (lowerName.contains('edit')) { + return '编辑相关图标'; + } else if (lowerName.contains('delete')) { + return '删除相关图标'; + } else if (lowerName.contains('me_')) { + return '个人中心相关图标'; + } else if (lowerName.contains('msg')) { + return '消息相关图标'; + } else if (lowerName.contains('arrow')) { + return '箭头相关图标'; + } else if (lowerName == '24_-' || lowerName.contains('subtract')) { + return '特殊字符图标'; + } else if (lowerName.contains('team') || lowerName.contains('student')) { + return '团队和用户相关图标'; + } else if (lowerName.contains('filter') || + lowerName.contains('question') || + lowerName.contains('onlysee') || + lowerName.contains('hint') || + lowerName.contains('switch')) { + return '功能图标'; + } else if (lowerName.contains('quit')) { + return '退出相关图标'; + } else if (lowerName.contains('more')) { + return '更多和菜单相关图标'; + } else if (lowerName.contains('copy')) { + return '复制相关图标'; + } else if (lowerName.contains('calendar')) { + return '日历相关图标'; + } else if (lowerName.contains('share')) { + return '分享相关图标'; + } else if (lowerName.contains('add') || lowerName.contains('+') || lowerName.contains('plus')) { + return '添加相关图标'; + } else if (lowerName.contains('keyboard')) { + return '键盘相关图标'; + } else { + return '其他图标'; + } +} +