IconUtils.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import DefaultIcons from "../data/DefaultIcon.json";
  2. export type IconItem = {
  3. type: 'iconfont'|'image'|'svg'|'none',
  4. value: string,
  5. rawSvg?: string,
  6. fontFamily?: string,
  7. };
  8. type IconMap = Record<string, IconItem>;
  9. //图标集
  10. const iconMap = {} as IconMap;
  11. export const IconUtils = {
  12. /**
  13. * 设置 Icon 组件的图标名称映射。
  14. * 如果已存在同名数据,则会覆盖之前的。
  15. *
  16. * key是图标的名字,value 可以是以下几种情况:
  17. * * 是一个 iconfont:name 字符,则会渲染为字体形式的图标,通过 : 分割,前面是字体名称,后面是图标名称。
  18. * * 是一个 `data:***` 或者 http/https URL,则会尝试使用 Image 渲染为图片
  19. * * 是一个 `&lt;svg` 开头的字符串,会渲染为 svg
  20. * * 否则,作为默认字体 iconfont 渲染为字体形式的图标。
  21. */
  22. configIconMap(map: Record<string, string>) {
  23. for (const key in map) {
  24. let result : IconItem;
  25. const v = map[key];
  26. if (v.startsWith('http') || v.startsWith('data:') || v.startsWith('/')) {
  27. result = {
  28. type: 'image',
  29. value: v,
  30. }
  31. } else if (v.startsWith('<svg') || v.includes('<svg')) {
  32. result = {
  33. type: 'svg',
  34. rawSvg: v,
  35. value: toDataSvg(v),
  36. }
  37. } else if (v.includes(':')) {
  38. const vv = v.split(':');
  39. result = {
  40. type: 'iconfont',
  41. value: vv[1],
  42. fontFamily: vv[0],
  43. }
  44. } else {
  45. result = {
  46. type: 'iconfont',
  47. value: v,
  48. }
  49. }
  50. iconMap[key] = result;
  51. }
  52. },
  53. getColoredSvg(svg: string, color: string) {
  54. return toDataSvg(
  55. svg.includes('fill=') ? svg : svg.replace(/<path /g, `<path fill="${color}" `)
  56. );
  57. },
  58. /**
  59. * 获取图标名称映射集
  60. * @returns
  61. */
  62. getIconMap() {
  63. return iconMap;
  64. },
  65. /**
  66. * 从图标名称映射中获取指定名称的图标数据。
  67. * @param key 图标名称
  68. * @returns 返回图标数据,如果找不到,返回 undefined。
  69. */
  70. getIconDataFromMap(key: string) {
  71. return iconMap[key];
  72. },
  73. }
  74. function toDataSvg(str: string) {
  75. if (!str.includes('xmlns'))
  76. str = str.replace("<svg ", "<svg xmlns='http://www.w3.org/2000/svg' ");
  77. return `data:image/svg+xml,${encodeURIComponent(str.replace(/\'/g, '"'))}`.replace(/\#/g, '%23');
  78. }
  79. IconUtils.configIconMap(DefaultIcons);