给定SVG Path元素,如何将所有路径命令转换为绝对坐标?例如,转换此路径:
<path d="M17,42 l100,0 v100 h-100 z"/>
进入此等效路径:
<path d="M17,42 L117,42 V142 H17 Z"/>
此问题的动机是this question。
答案 0 :(得分:11)
这是我提出的JavaScript代码:
function convertToAbsolute(path){
var x0,y0,x1,y1,x2,y2,segs = path.pathSegList;
for (var x=0,y=0,i=0,len=segs.numberOfItems;i<len;++i){
var seg = segs.getItem(i), c=seg.pathSegTypeAsLetter;
if (/[MLHVCSQTA]/.test(c)){
if ('x' in seg) x=seg.x;
if ('y' in seg) y=seg.y;
}else{
if ('x1' in seg) x1=x+seg.x1;
if ('x2' in seg) x2=x+seg.x2;
if ('y1' in seg) y1=y+seg.y1;
if ('y2' in seg) y2=y+seg.y2;
if ('x' in seg) x+=seg.x;
if ('y' in seg) y+=seg.y;
switch(c){
case 'm': segs.replaceItem(path.createSVGPathSegMovetoAbs(x,y),i); break;
case 'l': segs.replaceItem(path.createSVGPathSegLinetoAbs(x,y),i); break;
case 'h': segs.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x),i); break;
case 'v': segs.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y),i); break;
case 'c': segs.replaceItem(path.createSVGPathSegCurvetoCubicAbs(x,y,x1,y1,x2,y2),i); break;
case 's': segs.replaceItem(path.createSVGPathSegCurvetoCubicSmoothAbs(x,y,x2,y2),i); break;
case 'q': segs.replaceItem(path.createSVGPathSegCurvetoQuadraticAbs(x,y,x1,y1),i); break;
case 't': segs.replaceItem(path.createSVGPathSegCurvetoQuadraticSmoothAbs(x,y),i); break;
case 'a': segs.replaceItem(path.createSVGPathSegArcAbs(x,y,seg.r1,seg.r2,seg.angle,seg.largeArcFlag,seg.sweepFlag),i); break;
case 'z': case 'Z': x=x0; y=y0; break;
}
}
// Record the start of a subpath
if (c=='M' || c=='m') x0=x, y0=y;
}
}
这样使用问题的路径:
var path = document.querySelector('path');
convertToAbsolute(path);
console.log(path.getAttribute('d'));
// M 17 42 L 117 42 V 142 H 17 Z
编辑:这是一个测试页面,其中包含一个包含每个命令(绝对和相对)交错的路径,并显示转换在IE,Chrome,FF和Safari的当前版本中有效。
http://phrogz.net/svg/convert_path_to_absolute_commands.svg
答案 1 :(得分:8)
如果您有Raphaël,则同时拥有Raphael.pathToRelative
和Raphael._pathToAbsolute
。
Raphael._pathToAbsolute
不在文档(like pathToRelative)中,并且在内部的Raphael源中的许多地方都使用过。但是,如果您以这种方式在函数名之前添加_
,它也可以在外部使用:Raphael._pathToAbsolute
。
在线转化: http://jsbin.com/mudusiseta
用法与相对用法相同:
<script src="raphael.js"></script>
<script>
// ...
var paper = Raphael(10, 50, 320, 200);
var path_string = "M10 10 L 20 20 L 100 10"; // Original coordinates
var path = paper.path(path_string);
// To relative coordinates
var path_string_rel = Raphael.pathToRelative(path_string);
console.log(path_string_rel);
// To absolute coordinates
var path_string_abs = Raphael._pathToAbsolute(path_string_rel);
console.log(path_string_abs);
// ...
</script>
我不知道为什么pathToAbsolute不在文档中。它应该。
如果你想在Web Workers中使用它(加速代码),很容易从Raphael中获取所需的功能(许可证应该允许)并将其用作DOM免费方法。 Raphael是一个DOM操作库(以及jQuery),它不能在Workers中使用,因为在Worker中不支持DOM。如果您的路径非常复杂,浏览器可能会挂起并阻止此Web Workers在现代浏览器中提供解决方案。
答案 2 :(得分:1)
这是svg路径(d
attr)操作的库:https://github.com/fontello/svgpath。