使用矩阵在中心周围旋转Svg路径

时间:2015-07-16 06:20:26

标签: javascript matrix svg

我有很多不同尺寸的svg形状,我必须动态地用不同角度旋转它们。我想用矩阵中心旋转它们,我在计算矩阵的e,f时遇到问题。如何计算矩阵(a,b,c,d,e,f)中的e,f。我有一个角度,但不知道计算新的位置,所以看起来它是在中心旋转。这是一个我旋转45度的示例形状, enter image description here

     <rect x="0" y="0" width="50" height="50" style="stroke: #3333cc;fill:none;" transform="matrix(1,0,0,1,100,100)"></rect>

   <rect x="0" y="0" width="50" height="50" style="fill: #3333cc" transform="matrix(0.707,-0.707,0.707,0.707,100,100)"></rect>

2 个答案:

答案 0 :(得分:3)

转换和矩阵乘法如何工作的介绍超出了Stack Overflow答案的范围。有很多在线资源。

您可以阅读有关SVG转换如何在SVG规范中工作的内容:

http://www.w3.org/TR/SVG/coords.html

但基本上围绕特定点(cx,cy)旋转角度(a),你必须结合(用矩阵乘法)三个操作:

  1. 将中心翻译回原点(-cx,-cy)
  2. 执行旋转(a)
  3. 转回原来的位置
  4. [1 0 cx] [cos(a) -sin(a) 0] [1 0 -cx]
    [0 1 cy] [sin(a)  cos(a) 0] [0 1 -cy]
    [0 0 1 ] [  0       0    1] [0 0  1 ]
    

    当你将这三个矩阵相乘时,你会得到一个形式的矩阵:

    [cos(a) -sin(a) (-cos(a) * x + sin(a) * y + x)]
    [sin(a)  cos(a) (-sin(a) * x - cos(a) * y + y)]
    [0         0               1          ]
    

    或以SVG形式:

    matrix( ca, sa, -sa, ca, (-ca * x + sa * y + x), (-sa * x - ca * y + y) )
    

    其中:

    ca = cos(angle)
    sa = sin(angle)
    

    这是一个演示。绿色矩形使用transform="rotate(a,x,y)",红色矩形使用我们计算的等效值。

    &#13;
    &#13;
    var matrix = getMatrixForRotation(45, 250, 250);
    
    document.getElementById("myrect").setAttribute("transform", matrix);
    
    
    
    function getMatrixForRotation(a, cx, cy)
    {
      var ca = Math.cos(a * Math.PI / 180);
      var sa = Math.sin(a * Math.PI / 180);
    
      var a = ca.toFixed(4);
      var b = sa.toFixed(4);
      var c = (-sa).toFixed(4);
      var d = ca.toFixed(4);
      var e = (-ca * cx + sa * cy + cx).toFixed(4);
      var f = (-sa * cx - ca * cy + cy).toFixed(4);
    
      return "matrix(" + [a,b,c,d,e,f].join(' ') + ")";
    }
    &#13;
    <svg width="500" height="500">
      
      <rect x="100" y="150" width="300" height="200" fill="#eee"/>
      
      <rect x="100" y="150" width="300" height="200" fill="none"
            stroke="green" stroke-width="10"
            transform="rotate(45 250 250)"/>
      
      <rect x="100" y="150" width="300" height="200" fill="none"
            stroke="red" stroke-width="4"
            id="myrect"/>
      
    </svg>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:0)

基本上你需要做的就是加上你的X位置,否定你的Y位置。 例如

如果您有此代码

    

    <rect x="0" y="0" width="50" height="50" style="stroke: #3333cc;          fill:none;" transform="matrix(1,0,0,1,100,100)"></rect>

    <rect x="25" y="-25" width="50" height="50" style="fill: #3333cc" transform="matrix(0.5,0.5,-0.5,0.5,100,100)"></rect>

</svg>

第一个矩形是未旋转的正常直线。要在第一个矩形的中心旋转它,您需要先

Divide the width by your x transform (0.5) : 50 / 0.5 = 25
Divide the height by your y transform (0.5) : 50 / 0.5 = 25

然后只需在第二个矩形中使用这些值,这样新的X位置将为25,新的Y位置将为-25