Skip to content

解析 SVG 中的颜色

此函数属于 Iconify Tools 中的 图标操作函数 的一部分。

函数 parseColors() 用于解析 SVG 中的颜色。

它可以:

  • 查找所有颜色。
  • 替换颜色。
  • 添加缺失的默认颜色。

该函数会解析以下位置的颜色:

  • 样式表。
  • 内联样式。
  • 形状,包括渐变和滤镜。
  • 对颜色属性进行动画处理的 SVG 动画。

该函数不会解析以下位置的颜色:

  • 遮罩。

用法

该函数包含以下参数:

  • svgSVG。图标实例。
  • optionsobject。选项。

函数返回颜色数组。

颜色

回调函数中使用以及函数返回的颜色可以是以下两种类型:

  • Color 对象,与 Iconify Utils 中的相同。
  • string。如果颜色无法解析,则值为字符串。

选项

options 对象包含以下属性:

  • defaultColorColor|string。添加到使用系统默认颜色的形状上的默认颜色。见下文。
  • callbackfunction。为每种颜色调用的回调函数。见下文。

默认颜色

某些图标使用系统颜色。例如:

xml<svg viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" width="1200" height="400">
   <path d="M300 200H150A150 150 0 10300 50z"/>
</svg>

在该图标中,路径使用了默认填充。在 Iconify 中,所有图标都应使用由 color 属性设置的颜色,这意味着形状应使用 "currentColor" 进行填充。

如果设置了 defaultColor 选项,解析器将自动为使用默认颜色的形状设置颜色。

示例:

default-color.ts
tsimport { SVG, parseColors } from '@iconify/tools';

(async () => {
   const svg = new SVG(
       '<svg viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" width="1200" height="400"><path d="M300 200H150A150 150 0 10300 50z"/></svg>'
   );

   // Add 'currentColor' to shapes that use default color
   await parseColors(svg, {
       defaultColor: 'currentColor',
   });

   console.log(svg.toMinifiedString());
})();
Result:
svg<svg viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" width="1200" height="400"><path d="M300 200H150A150 150 0 10300 50z" fill="currentColor"/></svg>

替换颜色

通过 callback 选项,您可以替换颜色。

回调函数包含以下参数:

  • attrstring。使用颜色的属性,例如 "fill" 或 "stroke"。
  • colorStrstring。字符串形式的颜色值。
  • colorColor|null。解析后的颜色值。如果颜色可解析,回调将收到 Color 值。如果颜色不可解析,回调将收到 null 值。
  • tagNamestring。可选参数。找到颜色的标签名称。如果在样式表中找到颜色,该参数将为 undefined

回调函数应返回:

  • Colorstring 以设置新颜色。如果您不想更改颜色,请返回传递给回调的颜色(colorStr 或非空的 color 对象)。
  • "remove" 以移除当前元素。这用于移除某些编辑器留下的白色背景矩形等内容。
  • "unset" 以移除颜色。

示例

example.ts
tsimport { compareColors, stringToColor } from '@iconify/utils/lib/colors';
import { IconSet, parseColors, isEmptyColor } from '@iconify/tools';

const iconSet = new IconSet({
   prefix: 'codicon',
   icons: {
       'add': {
           body: '<path d="M14 7v1H8v6H7V8H1V7h6V1h1v6h6z"/>',
       },
       'debug-pause': {
           body: '<path d="M4.5 3H6v10H4.5V3zm7 0v10H10V3h1.5z" fill="#000"/>',
           hidden: true,
       },
       'triangle-left': {
           body: '<path d="M10.44 2l.56.413v11.194l-.54.393L5 8.373v-.827L10.44 2z" fill="#000"/>',
       },
   },
   aliases: {
       'plus': {
           parent: 'add',
       },
       'triangle-right': {
           parent: 'triangle-left',
           hFlip: true,
       },
   },
});

// Parse all icons in icon set
iconSet.forEach((name, type) => {
   if (type !== 'icon') {
       // Ignore aliases and variations: they inherit content from parent icon, so there is nothing to change
       return;
   }

   // Get icon as SVG class instance
   const svg = iconSet.toSVG(name);
   if (svg) {
       // Parse colors in SVG instance
       parseColors(svg, {
           // Change default color to 'currentColor'
           defaultColor: 'currentColor',

           // Callback to parse each color
           callback: (attr, colorStr, color) => {
               if (!color) {
                   // color === null, so color cannot be parsed
                   // Return colorStr to keep old value
                   return colorStr;
               }

               if (isEmptyColor(color)) {
                   // Color is empty: 'none' or 'transparent'
                   // Return color object to keep old value
                   return color;
               }

               // Black color: change to 'currentColor'
               if (compareColors(color, stringToColor('black'))) {
                   return 'currentColor';
               }

               // White color: belongs to white background rectangle: remove rectangle
               if (compareColors(color, stringToColor('white'))) {
                   return 'remove';
               }

               // Unexpected color. Add code to check for it
               throw new Error(
                   `Unexpected color "${colorStr}" in attribute ${attr}`
               );
           },
       });

       // Update icon in icon set
       iconSet.fromSVG(name, svg);
   }
});

// Export icon set
console.log(iconSet.export());
Result:
json{
   "prefix": "codicon",
   "icons": {
       "add": {
           "body": "<path d=\"M14 7v1H8v6H7V8H1V7h6V1h1v6h6z\" fill=\"currentColor\"/>"
       },
       "debug-pause": {
           "body": "<path d=\"M4.5 3H6v10H4.5V3zm7 0v10H10V3h1.5z\" fill=\"currentColor\"/>",
           "hidden": true
       },
       "triangle-left": {
           "body": "<path d=\"M10.44 2l.56.413v11.194l-.54.393L5 8.373v-.827L10.44 2z\" fill=\"currentColor\"/>"
       }
   },
   "aliases": {
       "plus": {
           "parent": "add"
       },
       "triangle-right": {
           "parent": "triangle-left",
           "hFlip": true
       }
   }
}