我使用SVG绘制了两条路径线,并将这些元素保存到了我的javascript代码中的两个变量'Line1'和'Line2'中,我需要将这两条线合并成一个单独的路径元素。是否有一种方法可以实现这一点?
我使用SVG绘制了两条路径线,并将这些元素保存到了我的javascript代码中的两个变量'Line1'和'Line2'中,我需要将这两条线合并成一个单独的路径元素。是否有一种方法可以实现这一点?
你定义的路径是相对路径(小写字母)还是绝对路径(大写字母)?如果是绝对路径,连接两个路径很简单,只需附加d
属性的值。如果你有这样的两条路径:
<path id="Line1" d="M50,50
A30,30 0 0,1 35,20
L100,100"
style="stroke:#660000; fill:none;"/>
<path id="Line2" d="M110,110
L100,0"
style="stroke:#660000; fill:none;"/>
然后这段JavaScript代码:
var Line1 = document.getElementById("Line1");
var Line2 = document.getElementById("Line2");
//Add paths together
Line1.setAttribute('d', Line1.getAttribute('d') + ' ' + Line2.getAttribute('d'));
//Remove unnecessary second path
Line2.parentNode.removeChild(Line2);
会导致你只有这样一个单一的路径:<path id="Line1" d="M50,50
A30,30 0 0,1 35,20
L100,100 M110,110
L100,0"
style="stroke:#660000; fill:none;"/>
这是一个 jsFiddle,它在 Firefox 4 中可用(需要HTML5解析器才能使用内联SVG)。
如果你的路径是相对的,那么你需要在附加路径之间添加一些内容,以便第二个路径从正确的位置开始。
d
属性通常,您可以将几个<path>
元素的路径数据d
属性连接起来以获得组合路径。
不幸的是,您可能会遇到一些使用M
或m
作为可互换命令的不良实践。
M
或m
的常见误解:M
(moveto)可以是绝对的或相对的。z
(closepath)命令(小写/大写-无关紧要)不同。m
命令可以用于复合路径,例如字母“o”的内部“孔”,指的是前一个命令的结束坐标。m
或M
命令使用绝对坐标-因为没有先前的点。M
命令可以是大写或小写-无所谓m
命令引入了一行隐式的相对l
lineto命令。(但您可以/应该避免这种情况)m
命令开头的路径svg{
border:1px solid #ccc;
width:25%;
}
path{
fill:#555;
}
<p>Seperate paths</p>
<svg viewBox="0 0 50 10">
<path id="path1" d="m 20 0 l 10 0 l 0 10 l -10 0z" />
<path id="path2" d="m 40 0 l 10 0 l 0 10 l -10 0z" />
<path id="path3" d="m 0 0 l 10 0 l 0 10 l -10 0z" />
</svg>
<p>Merged paths</p>
<svg viewBox="0 0 50 10">
<path id="pathConcat"
d="
m 20 0 l 10 0 l 0 10 l -10 0z
m 40 0 l 10 0 l 0 10 l -10 0z
m 0 0 l 10 0 l 0 10 l -10 0z
" />
</svg>
<p>Merged paths - fixed</p>
<svg viewBox="0 0 50 10">
<path id="pathConcat"
d="
M 20 0 l 10 0 l 0 10 l -10 0z
M 40 0 l 10 0 l 0 10 l -10 0z
M 0 0 l 10 0 l 0 10 l -10 0z
" />
</svg>
修复方法:只需将每个起始的m
替换为绝对M
m
命令用于相邻的linetos例外情况是后面跟着坐标的m
命令-用作后续l
(相对linetos)的简写。 (也请参见w3c规格。)
svg{
border:1px solid #ccc;
width:25%;
}
path{
fill:#555;
}
<p>Seperate paths</p>
<svg viewBox="0 0 50 10">
<path id="path1" d="m 20 0 10 0 0 10 -10 0z" />
<path id="path2" d="m 40 0 10 0 0 10 -10 0z" />
<path id="path3" d="m 0 0 10 0 0 10 -10 0z" />
</svg>
<p>Merged paths</p>
<svg viewBox="0 0 50 10">
<path id="pathConcat"
d="
m 20 0 10 0 0 10 -10 0z
m 40 0 10 0 0 10 -10 0z
m 0 0 10 0 0 10 -10 0z
" />
</svg>
<p>Merged paths - fixed</p>
<svg viewBox="0 0 50 10">
<path id="pathConcat"
d="
m 20 0 10 0 0 10 -10 0z
M 40 0 l 10 0 0 10 -10 0z
M 0 0 l 10 0 0 10 -10 0z
" />
</svg>
修复:插入 l
命令
<path d="m 20 0 10 0 0 10 -10 0z" />
equals
<path d="M 20 0 l 10 0 l 0 10 l -10 0z" />
或者
<path d="M 20 0 l 10 0 0 10 -10 0z" />
getPathData()
修复伪相对m
命令目前仍是草案,并未得到主要浏览器的本地支持。
但是您可以使用Jarek Foksa的polyfill。
getPathData()
将返回一个命令对象数组,并规范化重复的命令,如下所示:
[
{type: 'm', values:[20, 0] },
{type: 'l', values:[10, 0]},
{type: 'l', values:[0, 10]},
{type: 'l', values:[-10, 0]}
]
function concatSimple(){
let d1= path1.getAttribute('d')
let d2= path2.getAttribute('d')
let d3= path3.getAttribute('d')
pathConcat.setAttribute('d', d1+d2)
}
function concatPathData(){
let pathData1= fixFirstM(path1.getPathData());
let pathData2= fixFirstM(path2.getPathData());
let pathData3= fixFirstM(path3.getPathData());
let pathDataConcat = pathData1.concat(pathData2).concat(pathData3);
pathConcat.setPathData(pathDataConcat);
}
// change first m to absolute M
function fixFirstM(pathData){
pathData[0].type='M';
return pathData;
}
svg{
border:1px solid #ccc;
width:25%;
}
path{
fill:#555;
}
<p><button onclick="concatSimple()">concat d simple</button>
<button onclick="concatPathData()">concat d pathData</button>
</p>
<svg viewBox="0 0 50 10">
<path id="path1" d="m 20 0 10 0 0 10 -10 0z" />
<path id="path2" d="m 40 0 10 0 0 10 -10 0z" />
<path id="path3" d="m 0 0 10 0 0 10 -10 0z" />
</svg>
<svg viewBox="0 0 50 10">
<path id="pathConcat" d="" />
</svg>
<script src="https://cdn.jsdelivr.net/npm/path-data-polyfill@1.0.4/path-data-polyfill.min.js"></script>
pathData[0].type='M';
m
命令:l
命令(比如m 20 0 10 0 0 10 -10 0z
)如果您需要合并形状-paper.js拥有一些强大的路径操作,如联合、减去等。
在这里解释:"将两个基于贝塞尔曲线的形状合并成一个以创建新轮廓"