SVG-获取未转换的点?

SVG-获取未转换的点?,svg,transformation,Svg,Transformation,假设我有以下SVG: <g id="g1" transform="translate(100, 250) rotate(90)" > <path id="path1" d="M 100,100 c... 这个想法是,如果我运行这个脚本,生成的图像将与前一个图像相同 我之所以要这样做,是因为我有一个动画遵循这条路径。但是,由于变换,动画处于禁用状态。如果我将变换添加到animateMotion对象,动画仍然处于关闭状态。所以我的想法是移除路径并将其放回原处。这样我就可以

假设我有以下SVG:

<g id="g1" transform="translate(100, 250) rotate(90)" >
    <path id="path1" d="M 100,100 c...
这个想法是,如果我运行这个脚本,生成的图像将与前一个图像相同


我之所以要这样做,是因为我有一个动画遵循这条路径。但是,由于变换,动画处于禁用状态。如果我将变换添加到animateMotion对象,动画仍然处于关闭状态。所以我的想法是移除路径并将其放回原处。这样我就可以让动画工作了。(动画类似于此演示:)

下面是一个在转换后返回屏幕点的示例:多边形、路径、多段线。路径示例不起作用或不存在圆弧。此外,在某些情况下,相对点可能不会返回。这使用
getCTM
matrixTransform
。可以创建一个数组来“记住”不同时间线的点

<!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>

转换后返回屏幕点
转换后返回屏幕点:多边形、路径、多段线
在许多情况下,在转换后将某些svg元素(多边形、多段线和路径)返回到其屏幕x、y值是有意义的。这是使用getCTM和matrixTransform实现的
注意:对于带有笔划(*在IE中不可用)的元素,使用vector effect=“非缩放笔划”。
更改为屏幕值

SVG源代码:

Javascript:
//--钮扣--- 函数change2Screen() { 屏幕多段线(myPolyline) 屏幕多边形(myPolygon) 屏幕路径(myPath) mySVGValue.value=svgDiv.innerHTML } 函数屏幕多段线(myPoly) { var sCTM=myPoly.getCTM() var svgRoot=myPoly.ownerSVGElement var pointsList=myPoly.points; var n=pointsList.numberOfItems; 对于(var m=0;m
<!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>