2014-04-07 22 views
2

说我有以下SVG:SVG - 获取未转换的点?

<g id="g1" transform="translate(100, 250) rotate(90)" > 
    <path id="path1" d="M 100,100 c... 

有没有办法让d属性的实际坐标?理想的情况是我想要一些功能,如下面untransform

var transform = $("g1").getAttribute("transform"); 
var d = $("path1").getAttribute("d"); 
var dUntransformed = untransform(d, transform); 
$("g1").removeAttribute("transform"); 
$("path1").setAttribute("d", dUntransformed); 

的想法是,如果我跑这个脚本生成的图像会等同于以前的形象。

我想这样做的原因是因为我有一个动画遵循此路径。但由于转换动画关闭。如果我将变换添加到animateMotion对象,动画仍然关闭。所以我的想法是删除路径并将它放回到原来的位置。这样我就可以使动画起作用。 (AnimateMotion与此演示类似:https://mdn.mozillademos.org/files/3261/animateMotion.svg

+0

http://stackoverflow.com/questions/6858479/rectangle-coordinates-after-transform –

回答

2

以下是返回变形后的屏幕点的示例:多边形,路径,折线。该路径示例不起作用或弧线。此外,在某些情况下,相关点可能不会返回。这使用getCTMmatrixTransform。有可能创建一个数组来'记住'不同时间点的点。

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Return Screen Points After Tranformations</title> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
</head> 
<body style='padding:0px;font-family:arial'> 
<center> 
<h4>Return Screen Points After Tranformations : polygon, path, polyline</h4> 
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:10px;'> 
In many cases it is meaningful to return certain svg elements(polygon, polyline, and path) to their screen x,y values following transformations. This is accomplished using <b>getCTM</b>, and <b>matrixTransform</b> 
Note: Use vector-effect="non-scaling-stroke" for elements with stroke(*not available in IE). 
</div> 
<div id="svgDiv" style="background-color:lightgreen;width:500px;height:500px;"> 
<svg id="mySVG" width="500" height="500"> 
    <path id="myPath" vector-effect="non-scaling-stroke" transform="scale(.8)translate(120 50)skewY(15)rotate(-15)" fill="yellow" stroke="black" stroke-width="2" 
    d="M50,50 Q-30,100 50,150 100,230 150,150 230,100 150,50 100,-30 50,50"/> 
    <polyline vector-effect="non-scaling-stroke" id="myPolyline" transform="scale(.3)translate(700 620)" fill="red" stroke="black" stroke-width="3" points="122 60 150 450 500 400" /> 
    <polygon vector-effect="non-scaling-stroke" id="myPolygon" transform="scale(3)translate(122 132)" fill="purple" stroke="white" stroke-width="3"points="15,0 10.6066,-10.6066 9.18486e-016,-15 -10.6066,-10.6066 -15,-1.83697e-015 -10.6066,10.6066 -2.75545e-015,15 10.6066,10.6066" /> 
</svg> 
</div> 
<button onClick=change2Screen()>change to screen values</button> 
<br />SVG Source:<br /> 
<textarea id=mySVGValue style='font-size:120%;font-family:lucida console;width:90%;height:200px'></textarea> 
    <br />Javascript:<br /> 
<textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea> 
</center> 
<div id='browserDiv' style='padding:3px;position:absolute;top:5px;left:5px;background-color:gainsboro;'></div> 
<script id=myScript> 

//--button--- 
function change2Screen() 
{ 
    screenPolyline(myPolyline) 
    screenPolygon(myPolygon) 
    screenPath(myPath) 
    mySVGValue.value=svgDiv.innerHTML 
} 
function screenPolyline(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") 
} 
//---except arc/relative paths--- 
function screenPath(path) 
{ 
    var sCTM = path.getCTM() 
    var svgRoot = path.ownerSVGElement 

    var segList=path.pathSegList 
    var segs=segList.numberOfItems 
    //---change segObj values 
    for(var k=0;k<segs;k++) 
    { 
     var segObj=segList.getItem(k) 

     if(segObj.x && segObj.y) 
     { 
      var mySVGPoint = svgRoot.createSVGPoint(); 
      mySVGPoint.x = segObj.x 
      mySVGPoint.y = segObj.y 
      mySVGPointTrans = mySVGPoint.matrixTransform(sCTM) 
      segObj.x=mySVGPointTrans.x 
      segObj.y=mySVGPointTrans.y 
     } 

     if(segObj.x1 && segObj.y1) 
     { 
      var mySVGPoint1 = svgRoot.createSVGPoint(); 
      mySVGPoint1.x = segObj.x1 
      mySVGPoint1.y = segObj.y1 
      mySVGPointTrans1 = mySVGPoint1.matrixTransform(sCTM) 
      segObj.x1=mySVGPointTrans1.x 
      segObj.y1=mySVGPointTrans1.y 
     } 
     if(segObj.x2 && segObj.y2) 
     { 
      var mySVGPoint2 = svgRoot.createSVGPoint(); 
      mySVGPoint2.x = segObj.x2 
      mySVGPoint2.y = segObj.y2 
      mySVGPointTrans2 = mySVGPoint2.matrixTransform(sCTM) 
      segObj.x2=mySVGPointTrans2.x 
      segObj.y2=mySVGPointTrans2.y 
     } 
    } 
    //---force removal of transform-- 
    path.setAttribute("transform","") 
    path.removeAttribute("transform") 
} 

//---changes all transformed points to screen 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","") 
} 
</script> 
<script> 
document.addEventListener("onload",init(),false) 

function init() 
{ 
    mySVGValue.value=svgDiv.innerHTML 
    jsValue.value=myScript.text 
} 
</script> 
</body> 

</html>