2012-03-13 95 views
7

据我所知,目前没有办法在Raphael Javascript库中显示SVG多边形。我正在构建一个需要读取SVG的应用程序,并将它们显示在Raphael中,但是,其中很多SVG使用多边形。在Raphael中渲染SVG多边形Javascript库

例如,我在SVG阅读与此格式的多边形:

<polygon points="260.5,627.75 259.563,628.313 258.625,628.563 258.25... 

所以,我不知道......是有办法的多边形点转换成路径,其我可以拉斐尔?我见过一些使用python和PHP的应用程序,但到目前为止我找不到任何严格的javascript。

任何帮助将不胜感激。 感谢

+0

你想要一个JavaScript的解决方案吗?什么是您的源数据:一个包含''元素的实际SVG文件?结果你只需要返回路径的'd'属性值?或者你想将多边形就地转换为新的''元素? – Phrogz 2012-03-13 19:12:18

回答

13

Paper.path。你可以指定你自己的路径。例如。红色三角形:

paper.path('M 50 0 L 100 100 L 0 100 Z').attr('fill', 'red') 

在回答您的编辑

你应该能够拿分属性,作为一个字符串,并更换所有的坐标格式x,yL x,y - - 这将为SVG创建一条有效的路径。最初你可能需要一个moveTo命令。所以,这样的:

260.5,627.75 259.563,628.313 258.625,628.563 

将成为:

M 260.5,627.75 L 259.563,628.313 L 258.625,628.563 

拉斐尔似乎想整数,小数没有。因此,它必须是:

M 260,627 L 259,628 L 258,628 

要做到这一点:

var polygonPoints = '260.5,627.75 259.563,628.313 258.625,628.563'; 
var convertedPath = polygonPoints.replace(/([0-9.]+),([0-9.]+)/g, function($0, x, y) { 
    return 'L ' + Math.floor(x) + ',' + Math.floor(y) + ' '; 
}).replace(/^L/, 'M'); // replace first L with M (moveTo) 
+0

我编辑了这个问题。我正在寻找更多的方法来将多边形点转换成Raphael路径。 – Munzilla 2012-03-13 19:12:35

+2

不要忘记你的正则表达式中的负值。另请注意,多边形/多段线点之间不需要有逗号;他们可能会使用空格。为什么“地板”而不是“圆”?在SVG Path数据中,第一次出现后不需要重复命令名称。最后,由于多边形会自行关闭(而不是折线),所以在数据的末尾需要一个“Z”或“z”。 – Phrogz 2012-03-13 19:51:26

+0

如何将折线转换为点数组? – NevenHuynh 2014-03-31 07:39:06

0

如果你只是希望它的工作:

var polys = document.querySelectorAll('polygon,polyline'); 
Array.prototype.forEach.call(polys,convertPolyToPath); 

function convertPolyToPath(poly){ 
    var path = document.createElementNS('http://www.w3.org/2000/svg','path'); 
    var points = poly.getAttribute('points').split(/\s+|,/); 
    var x0=points.shift(), y0=points.shift(); 
    var pathdata = 'M'+x0+','+y0+'L'+points.join(); 
    if (poly.tagName=='polygon') pathdata+='z'; 
    path.setAttribute('d',pathdata); 
    poly.parentNode.replaceChild(poly,path); 
    return path; 
} 

如果你想在SVG打滚DOM:

function convertPolyToPath(poly){ 
    var path = document.createElementNS(poly.ownerSVGElement.namespaceURI,'path'); 
    var segs = path.pathSegList; 
    var pts = poly.points; 
    for (var i=0,len=pts.numberOfItems;i<len;++i){ 
    var pt = pts.getItem(i); 
    var func = i==0 ? 'createSVGPathSegMovetoAbs' : 'createSVGPathSegLinetoAbs'; 
    segs.appendItem(path[func](pt.x,pt.y)) 
    } 
    if (poly.tagName=='polygon') segs.appendItem(path.createSVGPathSegClosePath()); 
    poly.parentNode.replaceChild(poly,path); 
    return path; 
} 

编辑:最后
http://phrogz.net/svg/convert_polys_to_paths.svg

,如果你有这样的点视为一个字符串(.getAttribute('points')),只想路径数据:在这里的行动见两个以上的

function svgPolyPointsToPathData(points,closePath){ 
    points = points.split(/\s+|,/); 
    var pathdata = 'M'+points.shift()+','+points.shift()+'L'+points.join(); 
    if (closePath) pathdata+='z'; 
    return pathdata; 
} 
3

最简单的(和最紧凑)的解决方案可能是这样的事情,因为在多边形/折线点始终是绝对的:

多边形:

var pathstr = "M" + yourPolygonElm.getAttribute("points") + "Z"; 

折线:

var pathstr = "M" + yourPolylineElm.getAttribute("points"); 

这是因为,是不是真的需要在路径字符串( “d” 属性) “L”。 “M”表示首先是一个绝对的moveto,然后所有的坐标都是隐式的绝对linetos(或者如果你以“m”开头,那么你会得到相对的linetos)。

0

我想出了一个解决方案,希望这有助于:

this.createPolygon(304,0,0,500,912,500,608,0,'red'); 

createPolygon: function(x1,y1,x2,y2,x3,y3,x4,y4,color){ 
    return this.stage.path('M '+x1+' '+y1+' L '+x2+' '+y2+' L '+x3+' '+y3+' L '+x4+' '+y4+' Z').attr('fill',color); 
}