简化任何 SVG 路径以创建纯黑色形状(已更新)

问题描述 投票:0回答:3

是否可以通过简化路径以自动方式(以 JavaScript 或其他方式)将任何 SVG 转换为纯黑色形状?

有图书馆可以做到这一点,还是有其他方法?

我们以这个SVG为例:

<svg height="512" viewBox="0 0 16.933 16.933" width="512" xmlns="http://www.w3.org/2000/svg"><path d="M12.289 10.724a.265.265 0 0 0-.168.066 5.555 5.555 0 0 1-2.74 1.303.265.265 0 0 0-.2.363l1.597 3.806a.265.265 0 0 0 .489-.004l.732-1.825 1.852.743a.265.265 0 0 0 .342-.348l-1.653-3.942a.265.265 0 0 0-.251-.162zm-7.897.165-1.652 3.94a.265.265 0 0 0 .343.348l1.851-.744.732 1.825c.089.22.398.222.49.004l1.598-3.81a.265.265 0 0 0-.2-.363 5.556 5.556 0 0 1-2.743-1.297.265.265 0 0 0-.419.097z" fill="#ff5757"/><path d="M8.467.529C5.109.529 2.38 3.257 2.38 6.615s2.728 6.084 6.086 6.084 6.086-2.726 6.086-6.084S11.825.529 8.467.529z" fill="#ffcb3c"/><path d="M8.467 1.851a4.767 4.767 0 0 0-4.762 4.764c0 2.627 2.135 4.762 4.762 4.762s4.762-2.135 4.762-4.762A4.767 4.767 0 0 0 8.467 1.85z" fill="#ffea54"/><path d="M8.465 3.576a.265.265 0 0 0-.229.172l-.7 1.857-1.987.06a.265.265 0 0 0-.156.471L6.94 7.38l-.554 1.906a.265.265 0 0 0 .4.295l1.658-1.09 1.643 1.117a.265.265 0 0 0 .404-.289L9.97 7.402l1.568-1.215a.265.265 0 0 0-.148-.475L9.404 5.62l-.672-1.87a.265.265 0 0 0-.267-.175z" fill="#feaa2b"/></svg>

这就是我想要实现的目标:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 362.76 480.62"><g ><path d="m307.02,320.09C411.21,221.17,369.32,3.28,181.41,0-6.38,3.3-48.38,220.77,55.44,319.82l-47.2,112.57c-1.7,4.08.23,8.78,4.31,10.48.97,4.42,59.38-22.24,62.03-22.45l22.13,55.18c2.69,6.65,12.03,6.71,14.82.12l45.88-109.4c7.71.95,15.69,1.52,23.97,1.67,8.29-.14,16.28-.72,23.99-1.67,9.72,23.16,45.91,109.4,45.91,109.4,1.74,4.07,6.45,5.96,10.52,4.22,3.97,2.43,24.7-57.52,26.4-59.52l56,22.47c6.34,2.72,13.15-4.25,10.34-10.52-2.54-1.46-31.18-81.18-47.53-112.26Z"/></g></svg>

更新

我认为我的要求不够具体。

我的目标是让形状真正融入路径中。

目标是随后能够“贴纸化”任何 SVG 形状(主形状周围的白色轮廓)。

实现这一目标的第一步是能够合并 SVP 的不同路径以创建一种掩码。

javascript svg image-processing vector-graphics svg.js
3个回答
0
投票

如果 SVG 渲染为黑色就足够了,您可以结合 CSS 和 JavaScript 使用 Clip-path。

这里的核心方法是将 SVG 路径包装在

<clipPath>
中,并使用 CSS 的
clip-path
然后将
<div>
的形状更改为 SVG 的形状。

这些片段假设您的 SVG 是一个字符串。但是如果您的 SVG 已经在 html 中,您可以使用

querySelector
来选择
<svg>
元素。

这还假设只有一个 SVG 适用。如果这是不正确的,则必须对每个 SVG 使用

clipNodePath.id = randomId
并改用
element.style.clipPath = url("#`${randomId}`");
。这种方法可以在折叠的代码片段中找到。

const rawSvg = '<svg height="512" viewBox="0 0 16.933 16.933" width="512" xmlns="http://www.w3.org/2000/svg"><path d="M12.289 10.724a.265.265 0 0 0-.168.066 5.555 5.555 0 0 1-2.74 1.303.265.265 0 0 0-.2.363l1.597 3.806a.265.265 0 0 0 .489-.004l.732-1.825 1.852.743a.265.265 0 0 0 .342-.348l-1.653-3.942a.265.265 0 0 0-.251-.162zm-7.897.165-1.652 3.94a.265.265 0 0 0 .343.348l1.851-.744.732 1.825c.089.22.398.222.49.004l1.598-3.81a.265.265 0 0 0-.2-.363 5.556 5.556 0 0 1-2.743-1.297.265.265 0 0 0-.419.097z" fill="#ff5757"/><path d="M8.467.529C5.109.529 2.38 3.257 2.38 6.615s2.728 6.084 6.086 6.084 6.086-2.726 6.086-6.084S11.825.529 8.467.529z" fill="#ffcb3c"/><path d="M8.467 1.851a4.767 4.767 0 0 0-4.762 4.764c0 2.627 2.135 4.762 4.762 4.762s4.762-2.135 4.762-4.762A4.767 4.767 0 0 0 8.467 1.85z" fill="#ffea54"/><path d="M8.465 3.576a.265.265 0 0 0-.229.172l-.7 1.857-1.987.06a.265.265 0 0 0-.156.471L6.94 7.38l-.554 1.906a.265.265 0 0 0 .4.295l1.658-1.09 1.643 1.117a.265.265 0 0 0 .404-.289L9.97 7.402l1.568-1.215a.265.265 0 0 0-.148-.475L9.404 5.62l-.672-1.87a.265.265 0 0 0-.267-.175z" fill="#feaa2b"/></svg>';

const parsed = new DOMParser().parseFromString(rawSvg, 'image/svg+xml');
const svgNode = parsed.rootElement;

// Or if applicable
// const svgNode = document.querySelector('#some-id');

const clipPathNode = parsed.createElementNS("http://www.w3.org/2000/svg", "clipPath");
clipPathNode.id = 'abc';
clipPathNode.append(...svgNode.children);
svgNode.append(clipPathNode);
document.body.append(svgNode);
div {
  clip-path: url("#abc");
  background: black;
  width: 5em;
  height: 5em;
}

body {
  display: flex;
  align-items: start;
  justify-content: start;
}
<div></div>

或者如果每页有多个黑色 SVG,则使用随机 ID:

const rawSvg = '<svg height="512" viewBox="0 0 16.933 16.933" width="512" xmlns="http://www.w3.org/2000/svg"><path d="M12.289 10.724a.265.265 0 0 0-.168.066 5.555 5.555 0 0 1-2.74 1.303.265.265 0 0 0-.2.363l1.597 3.806a.265.265 0 0 0 .489-.004l.732-1.825 1.852.743a.265.265 0 0 0 .342-.348l-1.653-3.942a.265.265 0 0 0-.251-.162zm-7.897.165-1.652 3.94a.265.265 0 0 0 .343.348l1.851-.744.732 1.825c.089.22.398.222.49.004l1.598-3.81a.265.265 0 0 0-.2-.363 5.556 5.556 0 0 1-2.743-1.297.265.265 0 0 0-.419.097z" fill="#ff5757"/><path d="M8.467.529C5.109.529 2.38 3.257 2.38 6.615s2.728 6.084 6.086 6.084 6.086-2.726 6.086-6.084S11.825.529 8.467.529z" fill="#ffcb3c"/><path d="M8.467 1.851a4.767 4.767 0 0 0-4.762 4.764c0 2.627 2.135 4.762 4.762 4.762s4.762-2.135 4.762-4.762A4.767 4.767 0 0 0 8.467 1.85z" fill="#ffea54"/><path d="M8.465 3.576a.265.265 0 0 0-.229.172l-.7 1.857-1.987.06a.265.265 0 0 0-.156.471L6.94 7.38l-.554 1.906a.265.265 0 0 0 .4.295l1.658-1.09 1.643 1.117a.265.265 0 0 0 .404-.289L9.97 7.402l1.568-1.215a.265.265 0 0 0-.148-.475L9.404 5.62l-.672-1.87a.265.265 0 0 0-.267-.175z" fill="#feaa2b"/></svg>';

const parsed = new DOMParser().parseFromString(rawSvg, 'image/svg+xml');
const svgNode = parsed.rootElement;

const randomId = 'abc'; // replace with random id generator

const clipPathNode = parsed.createElementNS("http://www.w3.org/2000/svg", "clipPath");
clipPathNode.id = randomId;
clipPathNode.append(...svgNode.children);
svgNode.append(clipPathNode);
document.body.append(svgNode);

const targetNode = document.createElement('div');
targetNode.className = 'black-shape';
targetNode.style.clipPath = `url("#${randomId}"`;
document.body.append(targetNode);
.black-shape {
  background: black;
  width: 5em;
  height: 5em;
}

body {
  display: flex;
  align-items: start;
  justify-content: start;
}


0
投票

我不知道您是否觉得这个解决方案太简单了,但您可以使用 !important 关键字将所有填充设为黑色。

svg *  {
  fill: black !important;
}
<svg height="512" viewBox="0 0 16.933 16.933" width="512" xmlns="http://www.w3.org/2000/svg"><path d="M12.289 10.724a.265.265 0 0 0-.168.066 5.555 5.555 0 0 1-2.74 1.303.265.265 0 0 0-.2.363l1.597 3.806a.265.265 0 0 0 .489-.004l.732-1.825 1.852.743a.265.265 0 0 0 .342-.348l-1.653-3.942a.265.265 0 0 0-.251-.162zm-7.897.165-1.652 3.94a.265.265 0 0 0 .343.348l1.851-.744.732 1.825c.089.22.398.222.49.004l1.598-3.81a.265.265 0 0 0-.2-.363 5.556 5.556 0 0 1-2.743-1.297.265.265 0 0 0-.419.097z" fill="#ff5757"/><path d="M8.467.529C5.109.529 2.38 3.257 2.38 6.615s2.728 6.084 6.086 6.084 6.086-2.726 6.086-6.084S11.825.529 8.467.529z" fill="#ffcb3c"/><path d="M8.467 1.851a4.767 4.767 0 0 0-4.762 4.764c0 2.627 2.135 4.762 4.762 4.762s4.762-2.135 4.762-4.762A4.767 4.767 0 0 0 8.467 1.85z" fill="#ffea54"/><path d="M8.465 3.576a.265.265 0 0 0-.229.172l-.7 1.857-1.987.06a.265.265 0 0 0-.156.471L6.94 7.38l-.554 1.906a.265.265 0 0 0 .4.295l1.658-1.09 1.643 1.117a.265.265 0 0 0 .404-.289L9.97 7.402l1.568-1.215a.265.265 0 0 0-.148-.475L9.404 5.62l-.672-1.87a.265.265 0 0 0-.267-.175z" fill="#feaa2b"/></svg>


0
投票

SVG 是一个 XML 文档,因此您可以制作一个 XSLTProcessor 来转换整个 SVG。我知道这仍然是四种不同的道路。好吧,您也可以使用 XSL 将它们连接成一个路径,但该路径仍将具有与原始四个路径相同的轮廓。

在示例中,有一个特殊的 XSL 模板,它采用 fill 属性并为其赋予值“black”。

const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();

const xslText = `<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/2000/svg"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="*">
    <xsl:element name="{name()}">
      <xsl:apply-templates select="attribute::*" />
      <xsl:apply-templates select="*" />
    </xsl:element>
  </xsl:template>
  <xsl:template match="attribute::fill">
    <!--if a fill attribute, make the value "black"-->
    <xsl:attribute name="{name()}">
      <xsl:value-of select="'black'"/>
    </xsl:attribute>
  </xsl:template>
  <xsl:template match="attribute::*">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>`;
const xslStylesheet = parser.parseFromString(xslText, "application/xml");
xsltProcessor.importStylesheet(xslStylesheet);

const svgElm = document.querySelector('svg');
const xmlDoc = parser.parseFromString(svgElm.outerHTML, 'image/svg+xml');

const newXmlDoc = xsltProcessor.transformToDocument(xmlDoc, document);
document.body.innerHTML += newXmlDoc.documentElement.outerHTML;
<svg viewBox="0 0 16.933 16.933" width="100" xmlns="http://www.w3.org/2000/svg">
  <path d="M12.289 10.724a.265.265 0 0 0-.168.066 5.555 5.555 0 0 1-2.74 1.303.265.265 0 0 0-.2.363l1.597 3.806a.265.265 0 0 0 .489-.004l.732-1.825 1.852.743a.265.265 0 0 0 .342-.348l-1.653-3.942a.265.265 0 0 0-.251-.162zm-7.897.165-1.652 3.94a.265.265 0 0 0 .343.348l1.851-.744.732 1.825c.089.22.398.222.49.004l1.598-3.81a.265.265 0 0 0-.2-.363 5.556 5.556 0 0 1-2.743-1.297.265.265 0 0 0-.419.097z" fill="#ff5757"/>
  <path d="M8.467.529C5.109.529 2.38 3.257 2.38 6.615s2.728 6.084 6.086 6.084 6.086-2.726 6.086-6.084S11.825.529 8.467.529z" fill="#ffcb3c"/>
  <path d="M8.467 1.851a4.767 4.767 0 0 0-4.762 4.764c0 2.627 2.135 4.762 4.762 4.762s4.762-2.135 4.762-4.762A4.767 4.767 0 0 0 8.467 1.85z" fill="#ffea54"/>
  <path d="M8.465 3.576a.265.265 0 0 0-.229.172l-.7 1.857-1.987.06a.265.265 0 0 0-.156.471L6.94 7.38l-.554 1.906a.265.265 0 0 0 .4.295l1.658-1.09 1.643 1.117a.265.265 0 0 0 .404-.289L9.97 7.402l1.568-1.215a.265.265 0 0 0-.148-.475L9.404 5.62l-.672-1.87a.265.265 0 0 0-.267-.175z" fill="#feaa2b"/>
</svg>

© www.soinside.com 2019 - 2024. All rights reserved.