gpt4 book ai didi

javascript - 在 Javascript 中从 SVG 对象中提取所有行

转载 作者:行者123 更新时间:2023-12-03 10:34:54 24 4
gpt4 key购买 nike

我试图从 SVG 对象中提取所有线条,以便可以通过特殊的光栅器渲染它们,但事实证明这比我想象的要复杂得多。

主要挑战是:

  • svg <line><polyline>元素有时可以包含在 <defs> 中组,由元素呈现。这些需要展平。

  • <path>元素还需要转换为线元素。我很乐意扔掉花哨的曲线,只坚持直线。

是否有一种简单的方法可以做到这一点,或者是否有一些已经存在的代码可以避免重新发明轮子?我正在使用 Javascript 工作。

谢谢!

最佳答案

首先是第二点:
将弯曲路径转变为直线路径:
此时,它不会将其转换为 <line>元素,但这样做应该不会太困难,而且我不确定您是否真的需要这个。

function simplifyPathes(svg) {
var pathes = svg.querySelectorAll('path');
for (i = 0; i < pathes.length; i++) {
for (var j = 0; j < pathes[i].pathSegList.numberOfItems; j++) {
var segment = pathes[i].pathSegList.getItem(j);
if (segment.pathSegType > 4) {
if (segment.pathSegType & 1) {
var newSeg = pathes[i].createSVGPathSegLinetoRel(segment.x, segment.y);
} else {
var newSeg = pathes[i].createSVGPathSegLinetoAbs(segment.x, segment.y);
}
pathes[i].pathSegList.replaceItem(newSeg, j);
}
}
}
}

setTimeout(function(){simplifyPathes(document.querySelector('svg'))}, 1500);
<svg width="600" height="300" viewBox="0 0 600 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="path" fill="none" stroke="#000000" stroke-miterlimit="10" d="M286,81c-70.7,14-134.3-57.3-91.3-2.7s145,74.7,53,74.3 C155.7,152.3,150,16,164.3,93c14.3,77-33.7,68.7,53,87s-23.7,31.7-123,6.3-52,86-150,0" />
</defs>
<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M161,88.7c-3.3,44-58.4-5.7-58.4-5.7s-41-31,49.4-31.7 c90.3-0.7,86-61.3,83.7,2.7c-2.3,64,54.3,57.3-19.3,71.6S-27,47.7,89,110.7s107.7,152.7,106.7,65.7" />
<use xlink:href="#path" transform="translate(75, 25)" />
</svg>

可能有更好的方法,但我还没有。
Some readings here
您可能想将它与一些库结合起来,例如 simplify.js

现在,问题的第一部分。
我假设如果 <use>元素是一个问题,那是因为 Gecko's restrictive rules on external resources in svg Images .
如果不是这种情况,我很好奇为什么需要“扁平化”。

我写了一个可怕的 hack,它可能会向您展示一种解决方法。

function cloneUses(svg) {
var uses = svg.querySelectorAll('use')
for (i = 0; i < uses.length; i++) {
var elem = uses[i],
id = elem.getAttributeNS('http://www.w3.org/1999/xlink', 'href').substring(1),
c = svg.getElementById(id).cloneNode(true),
b = elem.transform.baseVal,
a = elem.attributes;
if(b.length>1){
b.consolidate();
c.transform.baseVal.appendItem(b.getItem(0));
c.transform.baseVal.consolidate();
}
for (j = 0; j < a.length; j++) {
if (a[j].value !== ('#' + id) && a[j].value !== "transform") {
c.setAttribute(a[j].name, a[j].value);
}
}
elem.parentNode.insertBefore(c, elem);
elem.parentNode.removeChild(elem);
}
}
setTimeout(function(){cloneUses(document.querySelector('svg'))}, 1500);
<svg width="600" height="300" viewBox="0 0 600 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<line id="line" stroke="black" x1="72" y1="120" x2="25" y2="25" />
<path id="path" fill="none" stroke="#000000" stroke-miterlimit="10" d="M286,81c-70.7,14-134.3-57.3-91.3-2.7s145,74.7,53,74.3 C155.7,152.3,150,16,164.3,93c14.3,77-33.7,68.7,53,87s-23.7,31.7-123,6.3-52,86-150,0" />
</defs>
<use xlink:href="#path" transform="translate(75, 25)" />
<use xlink:href="#line" transform="translate(125, 0)" />
</svg>
通过浏览器的检查器查看 svg

Ps:我让你想办法改造<circle>进入<line>靠你自己。

关于javascript - 在 Javascript 中从 SVG 对象中提取所有行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29044631/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com