【问题标题】:SVG matrix transformation around point x,y围绕点 x,y 的 SVG 矩阵变换
【发布时间】:2014-01-25 17:46:22
【问题描述】:

我尝试在svg 中创建矩阵rotationscaleskew,但根据/围绕指向(x,y)

我尝试Make a SVG transform matrix rotate around its center,但当对象矩阵为[1,0,0,1,0,0] = 尚未编辑时,它对我有用。在我第一次申请rotation 之后,第二次是不可预测的,并且到处旋转。

当矩阵已经转换并且都依赖于原点x,y时,有没有人可以帮助我对矩阵进行简单的rotation(ANGLE)scaleX(NUMBER)scaleX(NUMBER)skewX(NUMBER)skewY(NUMBER) 操作?

请记住,矩阵已经转换,下一次修改将来自修改后的下一个新矩阵。

matrix ( a: 0.9816080331802368, b:-0.1909615695476532, c: 0.1909615695476532, d: 0.9816080331802368, e: 120.33283996582031,f: -21.905738830566406)

  • 那么如何通过围绕某个点旋转来变换矩阵(x,y)
  • 如何使用点(x,y)skewX, skewY 以及特定(x,y) 中的原始变换来缩放X、缩放Y?

感谢您的帮助。

【问题讨论】:

    标签: matrix svg transform


    【解决方案1】:

    元素的缩放、旋转、倾斜最方便的点是获取其边界框的中心。使用该点首先平移元素,使其中心点位于原点,然后应用缩放、倾斜或旋转,然后将元素平移回其原始位置。

    要通过矩阵实现这一点,请使用:

    1. 一个矩阵对象,包含所有转换请求。
    2. 附加到要转换的元素(本例中为多边形)的转换列表
    3. 每次转换后,consolidate() 将转换列表转换为矩阵。

    此方法使用对象生成的方法来应用值,而不是构建基于文本的属性值……更简洁。

    试试这个例子:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    </head>
    <body style='font-family:arial'>
    <center>
    (This example tested in: IE11/CH31/FF23)
    <div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:8px;'>
    Sequentially Transform an element about a fixed 'center point' in the element.
    For this example, use the initial center of its bounding box.
    </div>
    <div id="svgDiv" style='background-color:lightblue;width:400px;height:400px;'>
    <svg id="mySVG" width="400" height="400">
    <polygon id="myPolygon" fill="red" points="140,60 100,300 300,200 340,140" />
    <circle id="centerPoint" r="4" fill="lime" stroke="black" stroke-width="1" />
    </svg>
    </div>
    <button onClick=rotate()>rotate</button>
    <button onClick=scaleXY()>scaleXY</button>
    <button onClick=skewX()>skewX</button>
    <button onClick=skewY()>skewY</button>
    <button onClick=startOver()>start over</button>
     <br />SVG Source:<br />
    <textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:400px'></textarea>
    </center>
    </body>
    <script>
    document.addEventListener("onload",init(),false)
    function init()
    {
        initTransform()
        svgSourceValue.value=svgDiv.innerHTML
    }
    
    var Cx,Cy
    var TransformRequestObj
    var TransformList
    //---onload---
    function initTransform()
    {
        var bb=myPolygon.getBBox()
        var bbx=bb.x
        var bby=bb.y
        var bbw=bb.width
        var bbh=bb.height
        Cx=bbx+.5*bbw
        Cy=bby+.5*bbh
        centerPoint.setAttribute("cx",Cx)
        centerPoint.setAttribute("cy",Cy)
    
        TransformRequestObj=mySVG.createSVGTransform()
        var animTransformList=myPolygon.transform
        TransformList=animTransformList.baseVal
    }
    //--button--
    function rotate()
    {
        var angle=10
    
        TransformRequestObj.setRotate(10,Cx,Cy)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
    
        svgSourceValue.value=svgDiv.innerHTML
    }
    //---button---
    function scaleXY()
    {
        var scaleX=1.05
        var scaleY=1.05
    
        TransformRequestObj.setTranslate(Cx,Cy)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
        TransformRequestObj.setScale(scaleX,scaleY)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
        TransformRequestObj.setTranslate(-Cx,-Cy)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
    
        svgSourceValue.value=svgDiv.innerHTML
    
    }
    //---button---
    function skewX()
    {
        var skwX=5 //---deg
    
        TransformRequestObj.setTranslate(Cx,Cy)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
    
        TransformRequestObj.setSkewX(skwX)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
    
        TransformRequestObj.setTranslate(-Cx,-Cy)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
    
       svgSourceValue.value=svgDiv.innerHTML
    }
    //---button---
    function skewY()
    {
        var skwY=10 //---deg
        TransformRequestObj.setTranslate(Cx,Cy)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
    
        TransformRequestObj.setSkewY(skwY)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
    
        TransformRequestObj.setTranslate(-Cx,-Cy)
        TransformList.appendItem(TransformRequestObj)
        TransformList.consolidate()
    
        svgSourceValue.value=svgDiv.innerHTML
    }
    //---button---
    function startOver()
    {
        myPolygon.removeAttribute("transform")
        TransformRequestObj=mySVG.createSVGTransform()
        var animTransformList=myPolygon.transform
        TransformList=animTransformList.baseVal
    }
    
    </script>
    </html>
    

    【讨论】:

    • 天才,绝对是天才,我花了一个多星期的时间,并没有达到你在 10 小时内达到的水平!!!!!!我是 SVG 和 Matrix 修改的新手——但它非常强大——我喜欢它。非常感谢,只需要稍微调整一下我需要的套件,但看起来一切正常!:)))
    • 有没有机会存储TransformList,然后根据这个保存的TransformList进行修改不改变只改变最后一个位置?就像旋转是 20' 我想添加 35 和 44 所以第一次显示 55 但第二次旋转不是 55+44 而是回到 20 并这次添加 44 = 64。希望很清楚!?问候并谢谢你
    • 您应该能够操作列表中的值。列表对象有以下方法(见 new answer()
    【解决方案2】:
    MyList.numberOfItems-Gets or sets the number of items in a list.
    MyList.appendItem(newItem)-Inserts a new item at the end of the list.
    MyList.clear()-Clears all existing items from the list, which creates an empty list.
    MyList.getItem(index)-Returns the specified item from a list.
    MyList.initialize(myItem)-Clears current items from the list and re-initializes the list to contain the specified item.
    MyList.insertItemBefore(newItem,index)-Inserts a new item into a list at a specified position.
    MyList.removeItem(myItem)-Removes an existing item from the list.
    MyList.replaceItem(newItem,index)-Replaces a specified existing item in the list with a specified new item.
    

    变换是相加的,非矩阵变换只是一个长字符串。要查看它是如何工作的,请不要使用 consolidate(),您会看到列表是一串请求的转换

    【讨论】:

    • 因为我正在使用 TransformList.consolidate() 不再是我相信的列表,但是由于我有单独的矩阵保存,我可以强制矩阵到 animTransformList TransformRequestObj=mySVG.createSVGTransform() var animTransformList= { a:1,b:0,c:0,d:1,e:50,f:50} TransformList=animTransformList.baseVal
    • 是的,我看到你正在理解这个过程......祝你的应用好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多