Search code examples
htmlcsssvgsvg-animate

SVG animation - growing and shrinking circle moving along line


I've been pulling my hair our with this SVG issue, I'm sure it's an attribute or something I'm missing but can't figure it out

I basically want to build a custom loader with a circle that starts from the left of the svg and moved to the right, scaling in the middle so it starts off small maybe 0.5 scale, increases to maybe 3 scale in the middle then shrinks back down to 0.5 on the other side and then repeats this, moving left-right, left-right

So far I can get the circle to go from the left to the right, I can also scale it, but when i try to combine both animations it goes all over the place.

https://jsfiddle.net/0odvwna4/18/

 <svg width="800px" height="100px">

   <circle 
     cx="0" 
     cy="50" 
     r="15" 
     fill="blue" 
     stroke="black" 
     stroke-width="1" 
     transform="scale(0.0801245 0.0801245)">

     <animateTransform     
                       attributeName="transform" 
                       type="scale" 
                       begin="0s"
                       calcMode="spline" 
                       keySplines="0.3 0 0.7 1;0.3 0 0.7 1"
                       values="0;1;0" 
                       keyTimes="0;0.5;1"
                       dur="5s"
                       repeatCount="indefinite"></animateTransform>

     <animate 
              attributeName="cx" 
              from="0" 
              to="800" 
              dur="5s" 
              repeatCount="indefinite" 
              />
    </circle>
 </svg>

Solution

  • By animating the cx attribute, you are changing the position of the circle in the SVG. And since the origin of all transforms is at the top left of the SVG (0,0), your scale is causing the circle to move back and forth relative to the origin.

    Anyway, why bother with a scale transform anyway? Why not just animate the radius?

    <svg width="800px" height="100px">
    
       <circle 
         cx="0" 
         cy="50" 
         r="0" 
         fill="blue" 
         stroke="black" 
         stroke-width="1">
    
         <animate
                 attributeName="r" 
                 begin="0s"
                 calcMode="spline" 
                 keySplines="0.3 0 0.7 1;0.3 0 0.7 1"
                 values="0;15;0" 
                 keyTimes="0;0.5;1"
                 dur="5s"
                 repeatCount="indefinite"/>
    
         <animate 
                  attributeName="cx" 
                  from="0" 
                  to="800" 
                  dur="5s" 
                  repeatCount="indefinite"/>
        </circle>
     </svg>