April 26, 2024
How to Scale a SVG Element Around a Transform Origin
Justin Golden
The Problem
You want to scale part of a SVG using <animateTransform>
, but when trying to scale, it scales from the top left corner, not the center.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g>
<circle fill="#EAB308" cx="8" cy="8" r="4"></circle>
<path d="m8 16v-16m-7 4 14 8m0-8-14 8" fill="none" stroke="#EAB308" stroke-width="1">
</path>
<animateTransform
attributeName="transform"
type="scale"
values="0.5; 1.5; 0.5"
dur="6s"
repeatCount="indefinite"></animateTransform>
</g>
</svg>
One would think the scale
command would have options for the from
/to
/values
to not just set scaleX
and scaleY
, but also a point to transform around.
Rotate works this way. For example, if you want to rotate from 0deg to 360deg, around the point 8,8, then you can just add 8 8
:
<animateTransform
attributeName="transform"
type="rotate"
from="0 8 8"
to="360 8 8"
dur="12s"
repeatCount="indefinite" />
And it works fine:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g>
<circle fill="#EAB308" cx="8" cy="8" r="4"></circle>
<path d="m8 16v-16m-7 4 14 8m0-8-14 8" fill="none" stroke="#EAB308" stroke-width="1">
</path>
<animateTransform
attributeName="transform"
type="rotate"
from="0 8 8"
to="360 8 8"
dur="12s"
repeatCount="indefinite"></animateTransform>
</g>
</svg>
Without centering around 8,8:
The Answer
I searched for a long time for the answer, on StackOverflow and dozens of forumns with hundreds of replies. I looked at the SVG docs and docs on Mozilla and elsewhere and could not find the answer.
However, the answer is quite simple, and it simply requires setting the transform-origin
in the item you’re animating:
<g transform-origin="8 8">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g transform-origin="8 8">
<circle fill="#EAB308" cx="8" cy="8" r="4"></circle>
<path d="m8 16v-16m-7 4 14 8m0-8-14 8" fill="none" stroke="#EAB308" stroke-width="1">
</path>
<animateTransform
attributeName="transform"
type="scale"
values="0.5; 1.5; 0.5"
dur="6s"
repeatCount="indefinite"></animateTransform>
</g>
</svg>
For fun, combining with our rotation:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g transform-origin="8 8">
<circle fill="#EAB308" cx="8" cy="8" r="4"></circle>
<path d="m8 16v-16m-7 4 14 8m0-8-14 8" fill="none" stroke="#EAB308" stroke-width="1">
<animateTransform
attributeName="transform"
type="rotate"
from="0 8 8"
to="360 8 8"
dur="12s"
repeatCount="indefinite"></animateTransform>
</path>
<animateTransform
attributeName="transform"
type="scale"
values="0.5; 1.5; 0.5"
dur="6s"
repeatCount="indefinite"></animateTransform>
</g>
</svg>
I hope this helps someone!
More Blog Articles