解析 SVG 中的颜色
此函数属于 Iconify Tools 中的 图标操作函数 的一部分。
函数 parseColors() 用于解析 SVG 中的颜色。
它可以:
- 查找所有颜色。
- 替换颜色。
- 添加缺失的默认颜色。
该函数会解析以下位置的颜色:
- 样式表。
- 内联样式。
- 形状,包括渐变和滤镜。
- 对颜色属性进行动画处理的 SVG 动画。
该函数不会解析以下位置的颜色:
- 遮罩。
用法
该函数包含以下参数:
- svg,SVG。图标实例。
- options,object。选项。
函数返回颜色数组。
颜色
回调函数中使用以及函数返回的颜色可以是以下两种类型:
- Color 对象,与 Iconify Utils 中的相同。
- string。如果颜色无法解析,则值为字符串。
选项
options 对象包含以下属性:
- defaultColor,Color|string。添加到使用系统默认颜色的形状上的默认颜色。见下文。
- callback,function。为每种颜色调用的回调函数。见下文。
默认颜色
某些图标使用系统颜色。例如:
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
ts
import { 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 选项,您可以替换颜色。
回调函数包含以下参数:
- attr,string。使用颜色的属性,例如 "fill" 或 "stroke"。
- colorStr,string。字符串形式的颜色值。
- color,Color|null。解析后的颜色值。如果颜色可解析,回调将收到 Color 值。如果颜色不可解析,回调将收到 null 值。
- tagName,string。可选参数。找到颜色的标签名称。如果在样式表中找到颜色,该参数将为 undefined。
回调函数应返回:
- Color 或 string 以设置新颜色。如果您不想更改颜色,请返回传递给回调的颜色(colorStr 或非空的 color 对象)。
- "remove" 以移除当前元素。这用于移除某些编辑器留下的白色背景矩形等内容。
- "unset" 以移除颜色。
示例
example.ts
ts
import { 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
}
}
}