Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling scale, but SVG element also translating

I have this fiddle where I am trying to scale the orange circle around its center (using javascript), that is, it must expand with origin set to its center. However, something is causing it to scale and also move, i.e. causes translation.

While the same thing would work fine in pure CSS environment as shown for the green circle

In both cases, I've fixed the transform-origin using CSS like this:

#Orange, #Orange *{
  transform-origin:140px 300px;
}  

Can anyone help? I want to scale it from the script for a larger animation sequence and the amount of scaling is dynamic (like a transition in 2 seconds).

like image 971
Anshul Avatar asked Oct 18 '25 15:10

Anshul


1 Answers

Your sample code was a bit long so I've simplified things a little.

The problem here is that when you apply a scale transform to an SVG element, what you're basically doing is multiplying all the element's coordinates by the scale factor. If the element is offset from the origin before scaling, this offset will be scaled too.

If you want things to scale about their centres, you need to adjust the local coordinates so that their centres are situated at the origin. You can do this by wrapping them in <g> elements with a suitable transform attribute.

For example, here's an SVG containing two circles. The orange one is centred at (100,125) and has centre coordinates of cx=cy=0. When this circle is scaled, it stays exactly where it is.

The blue circle has its origin set at (200,125) (shown by the blue cross), but with an additional offset of 100 in the centre x coordinate (cx=100). When this circle is scaled, the value of cx is doubled, causing it to fly out to the right.

svg path {
    pointer-events:visibleFill;
}

svg circle {
    -moz-transform: scale(1);
    -webkit-transform: scale(1);
    -o-transform: scale(1);
    -ms-transform: scale(1);
    transform: scale(1);
}

svg circle:hover {
    -moz-transform: scale(2);
    -webkit-transform: scale(2);
    -o-transform: scale(2);
    -ms-transform: scale(2);
    transform: scale(2);
    opacity:0.5;
}
  
<svg viewBox="0 0 400 250" width="400" height="250">
    <rect x="0" y="0" width="400" height="250" fill="#ffa" />
    <g transform="translate(100,125)">
        <circle cx="0" cy="0" r="50" fill="#f90" />
        <path d="M0-10V10ZM10 0H-10" stroke="#a60" stroke-width="2" />
    </g>
    <g transform="translate(200,125)">
        <circle cx="100" cy="0" r="50" fill="#69f" />
        <path d="M0-10V10ZM10 0H-10" stroke="#46a" stroke-width="2" />
    </g>
</svg>
like image 57
r3mainer Avatar answered Oct 21 '25 05:10

r3mainer