Animating SVGs
Tags: css, svg, html
Published: 2021-09-05 04:11:13


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](https://www.figma.com/file/j4OeUYJtowhZgr7z9Nu9XL/LaLiga-Loader?node-id=0%3A1)

![Laliga Loader recreated](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1c6se9mexkc5idn7pk1.png)

###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: 

```html
<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>
``` 

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](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/calcMode) 
* `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: 
```html
<animate attributeName="fill-opacity" begin="0s" dur="1s"
values="1;.3;.3;.3;.3;.3;.3" calcMode="linear" 
repeatCount="indefinite" attributeName="translate" />
``` 

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 :
```html
<animate attributeName="fill-opacity" begin="0s" dur="1s"
values=".3;1;.3;.3;.3;.3;.3" calcMode="linear" 
repeatCount="indefinite" attributeName="translate" />
``` 
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: 

```html
 <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>
```
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. 

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

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: 

{% codepen https://codepen.io/sidd_dev/pen/YzQXXrp default-tab=result %}

###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.