I need to resize and rotate certain elements in SVG document using javascript. The problem is, by default, it always applies the transform around the origin at (0, 0)
– top left.
How can I re-define this transform anchor point?
I tried using the transform-origin
attribute, but it does not affect anything.
This is how I did it:
svg.getDocumentById('someId').setAttribute('transform-origin', '75 240');
It does not seem to set the pivotal point to the point I specified although I can see in Firefox that the attribute is correctly set. I tried things like center bottom
and 50% 100%
with and without parenthesis. Nothing worked so far.
Can anyone help?
If you can use a fixed value (not "center" or "50%"), you can use CSS instead:
Some browsers (like Firefox) won't handle relative values correctly.
To rotate use
transform="rotate(deg, cx, cy)"
, where deg is the degree you want to rotate and (cx, cy) define the centre of rotation.For scaling/resizing, you have to translate by (-cx, -cy), then scale and then translate back to (cx, cy). You can do this with a matrix transform:
Where sx is the scaling factor in the x-axis, sy in the y-axis.
For scaling without having to use the
matrix
transformation:And here it is in CSS:
I had a similar issue. But I was using D3 to position my elements, and wanted the transform and transition to be handled by CSS. This was my original code, which I got working in Chrome 65:
This allowed me to set the
cx
,cy
, andtransform-origin
values in javascript using the same data.BUT this didn't work in Firefox! What I had to do was wrap the
circle
in theg
tag andtranslate
it using the same positioning formula from above. I then appended thecircle
in theg
tag, and set itscx
andcy
values to0
. From there,transform: scale(2)
would scale from the center as expected. The final code looked like this.After making this change, I changed my CSS to target the
circle
instead of the.dot
, to add thetransform: scale(2)
. I didn't even need usetransform-origin
.NOTES:
I am using
d3-selection-multi
in the second example. This allows me to pass an object to.attrs
instead of repeating.attr
for every attribute.When using a string template literal, be aware of line-breaks as illustrated in the first example. This will include a newline in the output and may break your code.
If you're like me and want to pan and then zoom with transform-origin, you'll need a little more.
Here it is working: http://forresto.github.io/dataflow-prototyping/react/