1
votes

I'm a bit lost computing matrix transform (rotate / translate)

I'm applying a svg transform to a svg rect (r1)

<svg width="400" height="400" viewBox="0 0 400 400" 
  xmlns="http://www.w3.org/2000/svg">
    <g id="r1" transform="translate(20,100) rotate(30, 175, 85)">
        <rect width="350" height="170" fill="#69c" fill-opacity=".1" />
    </g>
    <g id="r2" transform="">
        <rect width="150" height="100" fill="green" fill-opacity=".1" />
    </g>
    <g id="r3" transform="">
        <rect width="150" height="100" fill="red" fill-opacity=".1" />
    </g>
</svg>

this give me the following transform matrix SVGMatrix { a: 0.8660253882408142, b: 0.5, c: -0.5, d: 0.8660253882408142, e: 85.945556640625, f: 23.887840270996094 }

if I apply this transform matrix to another rectangle (r2) the rectangle will move to the exact same position of the first one but I lost the initial x,y position before applying the rotation

How can I get these x, y values from the transform matrix ?

translate(x,y) rotate(a, x+rect.w, y+rect.height)

I've made a jsbin to illustrate my problem

https://jsbin.com/luvome/edit?html,js,output

I'm would be very grateful if you can help. thanks.

1
What are you trying to do? - CoderPi
for resizing, I change the width / height of my rectangle (which is translated and rotated). I update width,height. it appear I also need to update x,y because after refreshing, my rectangle slightly jump to another position. on refresh, I redrawn rectangle using (translate(x,y), rotate(a, width/2, height/2) and since I dont update x, y, the rectangle is moving - lionelB

1 Answers

0
votes

Using this answer https://stackoverflow.com/a/15134993/2125385

I found this function

function computePosition(m, dim, angle){  
  var rad = angle*Math.PI/180;
  var tx = m.e - dim.width/2 + Math.cos(rad)*dim.width/2 - dim.height/2*Math.sin(rad);
  var ty = m.f - dim.height/2 + dim.width/2*Math.sin(rad) + dim.height/2*Math.cos(rad);
  return {x:tx, y:ty}
}

I can now create a new transform matrix and apply to the rect r3.

var angle = 30;
var m = r1.transform.baseVal.consolidate().matrix;
var dim = r3.getBBox();

var pos = computePosition(m, dim, angle);

r3.transform.baseVal.initialize(
  svg.createSVGTransformFromMatrix(
    svg.createSVGMatrix()
      .translate(pos.x, pos.y)
      .translate(dim.width/2, dim.height/2)
      .rotate(30)
      .translate(-dim.width/2, -dim.height/2)
  )
)