An introduction to how transformations and matrix multiplication work is beyond the scope of the answer. There are many online resources for this.
And you can read about how SVG transforms work in the SVG specification:
http://www.w3.org/TR/SVG/coords.html
But basically, to rotate an angle (a) around a certain point (cx, cy), you need to combine (with matrix multiplication) three operations:
- move the center back to the origin (-cx, -cy)
- turn (a)
- move back to the starting position
[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]
When you multiply these three matrices together, you get a shape matrix:
[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]
or in the form of SVG:
matrix( ca, sa, -sa, ca, (-ca * x + sa * y + x), (-sa * x - ca * y + y) )
Where:
ca = cos(angle) sa = sin(angle)
Here is a demo. The green rectangle uses transform="rotate(a,x,y)" , and the red rectangle uses our computed equivalent.
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(' ') + ")"; }
<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>
source share