简体   繁体   English

SVG多边形比例和相应设置点

[英]SVG polygon scale and set points accordingly

Hi Stack overflowers :) 嗨堆栈溢出:)

I'm struggling with a svg polygon object which I need to be able to resize (proportionally), and save/set the new points values. 我正在与svg多边形对象作斗争,我需要能够调整大小(按比例),并保存/设置新的点值。 At the moment I can do this by applying CSS transform to the SVG object, but that doesn't change the points attribute values. 目前,我可以通过将CSS转换应用于SVG对象来实现此目的,但这不会更改points属性值。 Is this possible somehow? 这有可能吗? My SVG polygon looks like this: 我的SVG多边形如下所示:

 <svg viewBox="0 0 100 100" style="width: 100px; height: 100px;"> <polygon fill="black" points="0,0 50,0 100,100 0,100" /> </svg> 

Thanks in advance :) 提前致谢 :)

Well, you can expand/contract a polygon via an offset(+/-) pixel value, and that will change its points values. 好了,您可以通过偏移(+/-)像素值来扩展/收缩多边形,这将改变其点值。 The polygon in question must be convex. 所讨论的多边形必须是凸的。 Also, the example below can scale the polygon and then recompute its points following the scale transform, using matrix transforms. 同样,下面的示例可以缩放多边形,然后在缩放后使用矩阵变换重新计算其点。

Give the following a try 尝试以下

 <!DOCTYPE HTML> <html> <head> <title>Resize Convex Polygon</title> </head> <body> <center> Offset(+/-)&nbsp;px.<input type="text" style="width:50px" id=offsetValue value=10 /><button onClick=resizeMyPolygon()>Resize Polygon</button> <br> <button onClick=scalePolygon() >Scale Polygon</button> <br> <svg xmlns="http://www.w3.org/2000/svg" id="mySVG" width="600" height="600"> <polygon id="myPolygon" fill="yellow" stroke="black" stroke-width="1" points="380,80 200,10 40,80 100,320 300,350"></polygon> <svg> </center> <script> //---button--- function scalePolygon() { //---scale from center of polygon-- var bb=myPolygon.getBBox() var bbx=bb.x var bby=bb.y var bbw=bb.width var bbh=bb.height var cx=bbx+.5*bbw var cy=bby+.5*bbh myPolygon.setAttribute("transform","translate("+cx+" "+cy+")scale(1.2)translate("+(-cx)+" "+(-cy)+")") screenPolygon(myPolygon) console.log(myPolygon.getAttribute("points")) } function screenPolygon(myPoly) { var sCTM = myPoly.getCTM() var svgRoot = myPoly.ownerSVGElement var pointsList = myPoly.points; var n = pointsList.numberOfItems; for(var m=0; m < n; m++) { var mySVGPoint = svgRoot.createSVGPoint(); mySVGPoint.x = pointsList.getItem(m).x mySVGPoint.y = pointsList.getItem(m).y mySVGPointTrans = mySVGPoint.matrixTransform(sCTM) pointsList.getItem(m).x=mySVGPointTrans.x pointsList.getItem(m).y=mySVGPointTrans.y }; //---force removal of transform-- myPoly.setAttribute("transform","") myPoly.removeAttribute("transform") } //---button--- function resizeMyPolygon() { var pointList=myPolygon.points //---clockwise or counterclockwise-- function polygonArea() { var area = 0; for (var i = 0; i < pointList.length; i++) { j = (i + 1) % pointList.length; area += pointList.getItem(i).x * pointList.getItem(j).y; area -= pointList.getItem(j).x * pointList.getItem(i).y; } return area / 2; } var clockwise = polygonArea() > 0; //---false is ccw points-- var offset=parseFloat(offsetValue.value) if((offset>0&& clockwise==true)||(offset<0&&clockwise==false)) { //--reverse polygon points--- var pointArray=[] for(var k=pointList.numberOfItems-1;k>=0;k--) { var lastPnt=pointList.getItem(k) pointArray.push([lastPnt.x,lastPnt.y]) } myPolygon.setAttribute("points",pointArray.join() ) pointList=myPolygon.points } var changedPoints=resizePolygon(pointList,offset,mySVG) myPolygon.setAttribute("points",changedPoints.join() ) console.log(myPolygon.getAttribute("points")) } function resizePolygon(pointsList,offset,rootSVG) { var m=pointsList.numberOfItems //---first find centroid--- var total_area = 0; var centroid = [0, 0]; var a = pointsList.getItem(0); for (i = 0; i < m - 2; i++) { var b = pointsList.getItem(i + 1) var c = pointsList.getItem(i + 2); var area = 0.5 * Math.abs((ax - cx) * (by - ay) - (ax - bx) * (cy - ay)); total_area += area; centroid[0] += area * (ax + bx + cx); centroid[1] += area * (ay + by + cy); } centroid[0] /= total_area * 3; centroid[1] /= total_area * 3; var points_offset = []; for (i = 0; i < m; i++) { //--- ab is a line segment on the convex polygon--- var a = pointsList.getItem(i); var b = pointsList.getItem(i == m - 1 ? 0 : i + 1); //---Determine the normal to the line segment--- var slope = -1 / ((by - ay) / (bx - ax)); //---Construct a new line d--e that is the line a--b shifted 'offset'--- //---units in the direction of the normal--- var w, h; if (ay == by) w = 0; else w = (ay < by ? -1 : 1) * Math.sqrt(offset * offset / (1 + slope * slope)); if (w == 0) h = (ax > bx ? -1 : 1) * offset; else h = slope * w; //---root svg element--- var d=rootSVG.createSVGPoint() var e=rootSVG.createSVGPoint() dx = ax + w dy = ay + h if (slope == 0) { ex = dx ey=dy + 10 } else { ex = dx + 10, ey=dy - 10 / slope } //---Intersect the line d--e with centroid--a, which is the point on--- //---the inflated convex polygon--- //---http://en.wikipedia.org/wiki/Line-line_intersection--- points_offset.push([ ((dx * ey - dy * ex) * (centroid[0] - ax) - (dx - ex) * (centroid[0] * ay - centroid[1] * ax)) / ((dx - ex) * (centroid[1] - ay) - (dy - ey) * (centroid[0] - ax)), ((dx * ey - dy * ex) * (centroid[1] - ay) - (dy - ey) * (centroid[0] * ay - centroid[1] * ax)) / ((dx - ex) * (centroid[1] - ay) - (dy - ey) * (centroid[0] - ax)) ]); } return points_offset } </script> </body> </html> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM