RGB logo

RGB Studios.org

A web development company

April 26, 2024

How to Scale a SVG Element Around a Transform Origin

Justin Golden

webdev
svg
Photo credit @joshuas on Unsplash

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>

Transform Origin SVG Docs

I hope this helps someone!


More Blog Articles
  Share   Tweet   Pin   Share   Post   Post   Share   Email