2016-07-22 17 views
0

Hallo Stapel overflowers :)SVG Polygon Skala und Sollwerte entsprechend

ich mit einem svg Polygon-Objekt bin zu kämpfen, die ich brauche (proportional) in der Lage sein, um die Größe und speichern/stellen Sie die neuen Punkte-Werte. Im Moment kann ich dies tun, indem ich CSS-Transformation auf das SVG-Objekt anwende, aber das ändert nichts an den Punkten-Attributwerten. Ist das irgendwie möglich? Mein SVG Polygon sieht wie folgt aus:

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

Vielen Dank im Voraus :)

+0

versuchen Was ist der Sinn davon? SVG ist eine Vektorgrafik, so dass es möglich ist, die Größe zu ändern, ohne die Punkte zu ändern. Können Sie bitte Ihren Verwendungszweck angeben? – mxlse

+0

Die Punkte müssen in einer Datenbank gespeichert werden, damit ich ein anderes Frontend rendere, deshalb brauche ich diese Polygonkoordinaten :) –

Antwort

1

Nun können Sie ein Polygon über einen Offset (+/-) Pixelwert ausfahren/einfahren, und Das wird seine Punktewerte ändern. Das betreffende Polygon muss konvex sein. Das folgende Beispiel kann auch das Polygon skalieren und dann seine Punkte nach der Skalierungstransformation mithilfe von Matrixtransformationen neu berechnen.

Geben Sie folgendes ein

<!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) 
 
{ 
 
\t var sCTM = myPoly.getCTM() 
 
\t var svgRoot = myPoly.ownerSVGElement 
 

 
\t var pointsList = myPoly.points; 
 
\t var n = pointsList.numberOfItems; 
 

 

 
\t for(var m=0; m < n; m++) 
 
\t { 
 
\t \t var mySVGPoint = svgRoot.createSVGPoint(); 
 
\t \t mySVGPoint.x = pointsList.getItem(m).x 
 
\t \t mySVGPoint.y = pointsList.getItem(m).y 
 
\t \t mySVGPointTrans = mySVGPoint.matrixTransform(sCTM) 
 
\t \t pointsList.getItem(m).x=mySVGPointTrans.x 
 
\t \t pointsList.getItem(m).y=mySVGPointTrans.y 
 
\t }; 
 
\t //---force removal of transform-- 
 
\t myPoly.setAttribute("transform","") 
 
\t 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) 
 
{ 
 
\t var m=pointsList.numberOfItems 
 
\t //---first find centroid--- 
 
\t var total_area = 0; 
 
\t var centroid = [0, 0]; 
 
\t var a = pointsList.getItem(0); 
 
\t for (i = 0; i < m - 2; i++) 
 
\t { 
 
\t \t var b = pointsList.getItem(i + 1) 
 
\t \t var c = pointsList.getItem(i + 2); 
 
\t \t var area = 0.5 * Math.abs((a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y)); 
 
\t \t total_area += area; 
 
\t \t centroid[0] += area * (a.x + b.x + c.x); 
 
\t \t centroid[1] += area * (a.y + b.y + c.y); 
 
\t } 
 
\t centroid[0] /= total_area * 3; 
 
\t centroid[1] /= total_area * 3; 
 

 
\t var points_offset = []; 
 
\t for (i = 0; i < m; i++) 
 
\t { 
 
\t \t //--- a-b is a line segment on the convex polygon--- 
 
\t \t var a = pointsList.getItem(i); 
 
\t \t var b = pointsList.getItem(i == m - 1 ? 0 : i + 1); 
 

 
\t \t //---Determine the normal to the line segment--- 
 
\t \t var slope = -1/((b.y - a.y)/(b.x - a.x)); 
 

 
\t \t //---Construct a new line d--e that is the line a--b shifted 'offset'--- 
 
\t \t //---units in the direction of the normal--- 
 
\t \t var w, h; 
 
\t \t if (a.y == b.y) 
 
\t \t \t w = 0; 
 
\t \t else 
 
\t  \t \t w = (a.y < b.y ? -1 : 1) * Math.sqrt(offset * offset/(1 + slope * slope)); 
 

 
\t \t if (w == 0) 
 
\t \t \t h = (a.x > b.x ? -1 : 1) * offset; 
 
\t \t else 
 
\t \t \t h = slope * w; 
 

 
\t \t //---root svg element--- 
 
\t \t var d=rootSVG.createSVGPoint() 
 
\t \t var e=rootSVG.createSVGPoint() 
 
\t \t d.x = a.x + w 
 
\t \t d.y = a.y + h 
 

 
\t \t if (slope == 0) 
 
\t \t { 
 
\t \t \t e.x = d.x 
 
\t \t \t e.y=d.y + 10 
 
\t \t } 
 
\t \t else 
 
\t \t { 
 
\t \t \t e.x = d.x + 10, 
 
\t \t \t e.y=d.y - 10/slope 
 
\t \t } 
 

 
\t \t //---Intersect the line d--e with centroid--a, which is the point on--- 
 
\t \t //---the inflated convex polygon--- 
 
\t \t //---http://en.wikipedia.org/wiki/Line-line_intersection--- 
 
\t \t points_offset.push([ 
 
\t \t ((d.x * e.y - d.y * e.x) * (centroid[0] - a.x) - (d.x - e.x) * (centroid[0] * a.y - centroid[1] * a.x)) 
 
\t \t/((d.x - e.x) * (centroid[1] - a.y) - (d.y - e.y) * (centroid[0] - a.x)), 
 
\t \t ((d.x * e.y - d.y * e.x) * (centroid[1] - a.y) - (d.y - e.y) * (centroid[0] * a.y - centroid[1] * a.x)) 
 
\t \t/((d.x - e.x) * (centroid[1] - a.y) - (d.y - e.y) * (centroid[0] - a.x)) 
 
\t \t ]); 
 
\t } 
 
\t return points_offset 
 
} 
 

 
</script> 
 
</body> 
 
</html>

+0

Danke @francis, du lässt mich auf dem richtigen Weg :) –