DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 963,274 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Animating SVGs
Siddhant Jaiswal
Siddhant Jaiswal

Posted on • Updated on

Animating SVGs

Hi

In this series we discuss about animations on the web using css or SVG animation. Everyone of us has at some point stuck to create a stunning loading animation for our web project and right now web has advanced so much that it has made it very easy to create SVGs and then animate them. All of we have to do is keep on learning new features of the web.

Intro

Previously I showed you'll how LaLiga Developers used the old Disney way to make a bunch of image move so fast that it feels like its moving which is really very smart.
In this post I'll show how to achieve a similar effect using just the SVG (no css).

So to start of I need to recreate the LaLiga loading spinner into svg and to do this I used Figma. Figma is a great tool to create web designs and illustrations adn most importantly it is free to use. So I traced the LaLiga loader in figma and you check that file here

Laliga Loader recreated

Lets Code

I know its not perfect but it will do the work.
The loader is made up of 7 individual items and hence in Figma file I have named them in order from 1-7 this indeed will create 7 paths with ids from 1-7. While exporting this helps us to target each section individually and eventually you have more control over each item and thus after exporting it from Figma as SVG the code looks something like this:

<svg width="150" height="150" viewBox="0 0 151 152" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path id="7" d="M44.93 31.95C44.93 31.95 68.07 16.2 87.57 22.63L88.64 0.700003C88.64 0.700003 58.86 -3.08999 35.64 22.41L44.93 31.95Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">

    </path>
    <path id="6" d="M92.02 23.11C92.02 23.11 120.62 33.24 126.57 50.91L143.29 38.86C143.29 38.86 122.55 10.09 93.62 10.7L92.02 23.11Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">

    </path>
    <path id="5" d="M128.82 55.57L138.46 49.15C138.46 49.15 157 69.56 147.46 105.45L128.82 100.58C128.82 100.58 139.41 72.45 128.82 55.57Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">

    </path>
    <path id="4" d="M126.89 104.49L137.07 107.7C137.07 107.7 129.89 142.27 99.46 150.7L91.46 132.34C91.46 132.34 113.29 129.88 126.89 104.49Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">

    </path>
    <path id="3" d="M43 122.7C43 122.7 68.31 139.63 86.07 133.84L90.36 144.13C90.36 144.13 75.36 157.2 34.21 140.7L43 122.7Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">

    </path>
    <path id="2" d="M39.93 120.22C39.93 120.22 18.5 98.7 20.78 80.21L0.5 83.86C0.5 83.86 6.76 118.76 33.13 130.69L39.93 120.22Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">

    </path>
    <path id="1" d="M40.86 34.41C40.86 34.41 19.86 53.02 21.57 74.27L8.93 75.7C8.93 75.7 4.86 35.91 24.93 20.7L40.86 34.41Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">

    </path>

  </svg>
Enter fullscreen mode Exit fullscreen mode

Now we have the loader as we want it and everything is IDed properly. Now to animate each and every item we will using a special tag created for SVGs the animate tag.
This tag consists of the following properties:

  • attributeName : Here you specify the attribute you want to animate for our case we will animating fill-opacity.
  • dur : This specifies how long the animation will run.
  • begin: This specifies at which second your animation will start.
  • values: This is very import this helps us in overriding the value of property we are targeting via attributeName in our case we will define how the fill-opacity will change over the course of 1s for each item.
  • calcMode: This defines the function how our animation will be processed it can have values such as discrete | linear | paced | spline you read more about in Mozilla Docs
  • repeatCount: This defines how long animation will be repeated, since its a loader we want to run it indefinitely.

Hence our animate tag will look something like this:

<animate attributeName="fill-opacity" begin="0s" dur="1s"
values="1;.3;.3;.3;.3;.3;.3" calcMode="linear" 
repeatCount="indefinite" attributeName="translate" />
Enter fullscreen mode Exit fullscreen mode

Interesting thing to note here is the values property. My current values is "1;.3;.3;.3;.3;.3;.3" what this really means that the fill opacity will start from 1 and within a second it will change to .3 so basically we are changing the fill-opacity of each item 7 times so that we achieve the circular motion affect, so for the next path id=2 the animate tag will :

<animate attributeName="fill-opacity" begin="0s" dur="1s"
values=".3;1;.3;.3;.3;.3;.3" calcMode="linear" 
repeatCount="indefinite" attributeName="translate" />
Enter fullscreen mode Exit fullscreen mode

and we will keep doing like this until the last one has values as ".3;.3;.3;.3;.3;.3;1"

Now the final SVG code will be:

 <svg width="150" height="150" viewBox="0 0 151 152" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path id="7" d="M44.93 31.95C44.93 31.95 68.07 16.2 87.57 22.63L88.64 0.700003C88.64 0.700003 58.86 -3.08999 35.64 22.41L44.93 31.95Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">
      <animate attributeName="fill-opacity" begin="0s" dur="1s" values="1;.3;.3;.3;.3;.3;.3" calcMode="linear" repeatCount="indefinite" attributeName="translate" />
    </path>
    <path id="6" d="M92.02 23.11C92.02 23.11 120.62 33.24 126.57 50.91L143.29 38.86C143.29 38.86 122.55 10.09 93.62 10.7L92.02 23.11Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">
      <animate attributeName="fill-opacity" begin="0s" dur="1s" values=".3;1;.3;.3;.3;.3;.3" calcMode="linear" repeatCount="indefinite" />
    </path>
    <path id="5" d="M128.82 55.57L138.46 49.15C138.46 49.15 157 69.56 147.46 105.45L128.82 100.58C128.82 100.58 139.41 72.45 128.82 55.57Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">
      <animate attributeName="fill-opacity" begin="0s" dur="1s" values=".3;.3;1;.3;.3;.3;.3" calcMode="linear" repeatCount="indefinite" />
    </path>
    <path id="4" d="M126.89 104.49L137.07 107.7C137.07 107.7 129.89 142.27 99.46 150.7L91.46 132.34C91.46 132.34 113.29 129.88 126.89 104.49Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">
      <animate attributeName="fill-opacity" begin="0s" dur="1s" values=".3;.3;.3; 1;.3;.3;.3" calcMode="linear" repeatCount="indefinite" />
    </path>
    <path id="3" d="M43 122.7C43 122.7 68.31 139.63 86.07 133.84L90.36 144.13C90.36 144.13 75.36 157.2 34.21 140.7L43 122.7Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">
      <animate attributeName="fill-opacity" begin="0s" dur="1s" values=".3;.3;.3;.3;1;.3;.3" calcMode="linear" repeatCount="indefinite" />
    </path>
    <path id="2" d="M39.93 120.22C39.93 120.22 18.5 98.7 20.78 80.21L0.5 83.86C0.5 83.86 6.76 118.76 33.13 130.69L39.93 120.22Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">
      <animate attributeName="fill-opacity" begin="0s" dur="1s" values=".3;.3;.3;.3;.3;1;.3" calcMode="linear" repeatCount="indefinite" />
    </path>
    <path id="1" d="M40.86 34.41C40.86 34.41 19.86 53.02 21.57 74.27L8.93 75.7C8.93 75.7 4.86 35.91 24.93 20.7L40.86 34.41Z" fill="white" fill-opacity="0.7" stroke="white" stroke-linecap="round" stroke-linejoin="round">
      <animate attributeName="fill-opacity" begin="0s" dur="1s" values=".3;.3;.3;.3;.3;.3;1" calcMode="linear" repeatCount="indefinite" />
    </path>
  </svg>
Enter fullscreen mode Exit fullscreen mode

and we get our round animation.

Now next up we need to do the scale animation for that we will animateTransform this is similar to animate tag but will apply the Transform effect to the svg.

<animateTransform attributeName="transform" type="scale" values="1;.9;1" additive="sum" begin="0s" dur="1.4s" repeatCount="indefinite" />
Enter fullscreen mode Exit fullscreen mode

Here I'm basically changing the transform value from 1 to .9 and to 1 so will expand and collapse on its center.

Result

The final result is:

Conclusion

This is far from perfect but you get the idea I need to refine the SVG a little and it will good to go. In the same way we can create the inner part of the SVG and give the values in reverse order to make to rotate in opposite direction.

Top comments (0)

🌚 Friends don't let friends browse without dark mode.

Just kidding, it's a personal preference. But you can change your theme, font, etc. in your settings.

The more you know. 🌈