DEV Community

Cover image for A quick introduction to SVG animation
Manuel Ricci
Manuel Ricci

Posted on

A quick introduction to SVG animation

In the past few days I worked a lot with SVGs. For years I used Illustrator for graphic purposes, but I never touched the source code of what I did, even less animated.

To better understand this marvelous technology, I decided to go deeper in the topic and the mess of paths and coordinates has become much more clear.

In this my first post on DEV.to I want to share with you my knowledge about SVGs, so you can spicing up your next project.

Small recap about SVGs

If you don't know what SVGs are, don't be afraid, read this easy explanation.

SVG stand for Scalable Vector Graphics, it's a technology able to visualize a vector graphic objects and, therefore, to manage scalable images dimensionally.

SVG its standardized by W3C, you can read the documentation here.

Here we go

Now that the definition of SVG is clear for everybody, let's deep dive into.

Let's start talking about the SVG itself, the object that we want to animate. I think that no one create with code from scratch an SVG, for that you can use Adobe Illustrator or Inkscape (there are a plenty number of software that permit to create SVGs).

For this introduction I created on Illustrator the classic batman logo
Classic Batman Logo

And that's the code

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Livello_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 595.28 841.89" style="enable-background:new 0 0 595.28 841.89;" xml:space="preserve">
<style type="text/css">
    .st0{fill:none;stroke:#010101;stroke-miterlimit:10;}
</style>
<path class="st0" d="M340.44,418.45c-2.83,4.36-7.29,8.3-13.24,11.72c-2.98,1.72-6.2,3.22-9.8,4.59c0.98-1.21,1.97-2.47,2.86-3.83
    c1.06-1.61,2.45-4.05,2.33-6.68c-0.11-2.32-1.31-4.54-3.08-5.66c-1.95-1.24-4.85-1.32-7.06-0.2c-2.55,1.3-3.85,4.14-5.06,6.94
    c-0.49-0.64-0.99-1.3-1.51-1.94c-1.05-1.3-2.24-2.6-3.76-3.33c-1.84-0.87-4.23-0.94-6.09-0.16c-2.28,0.96-3.8,3.16-4.98,5.19
    c-1.13,1.93-2.12,3.98-3.2,6.66c-0.96,2.35-1.83,4.8-2.67,7.18c-0.85-2.38-1.73-4.83-2.67-7.18c-1.09-2.67-2.07-4.73-3.2-6.66
    c-1.19-2.03-2.7-4.23-4.98-5.19c-0.87-0.37-1.86-0.55-2.85-0.55c-1.13,0-2.26,0.24-3.24,0.7c-1.52,0.73-2.7,2.03-3.76,3.33
    c-0.52,0.64-1.02,1.3-1.51,1.94c-1.21-2.79-2.5-5.65-5.06-6.94c-2.21-1.12-5.11-1.04-7.06,0.2c-1.77,1.12-2.97,3.34-3.08,5.66
    c-0.12,2.62,1.27,5.06,2.33,6.68c0.89,1.36,1.89,2.62,2.86,3.83c-3.61-1.37-6.82-2.87-9.8-4.59c-5.95-3.43-10.41-7.37-13.24-11.72
    c-3.27-5-4.36-10.5-3.1-15.47c0.73-2.84,2.31-5.89,4.6-8.8c2.94-3.75,6.82-6.99,11.87-9.89c3.3-1.9,6.9-3.56,10.68-4.91
    c2.55-0.91,5.3-1.73,8.39-2.5c-1.2,1.44-2.02,2.49-2.78,3.64c-1.5,2.28-2.35,4.34-2.59,6.31c-0.26,2.08,0.16,4.17,1.19,5.89
    c0.94,1.59,2.42,2.94,4.16,3.81c1.93,0.96,4.09,1.28,6.09,0.9c1.2-0.23,2.34-0.71,3.27-1.4c2-1.48,3.36-4.05,4.16-7.88
    c0.44-2.1,0.62-4.16,0.79-6.17l0.04-0.46c0.21-2.39,0.45-4.85,0.69-7.23l3.88,5.75h7.91l3.88-5.75c0.24,2.38,0.48,4.84,0.69,7.23
    l0.04,0.46c0.17,2.01,0.36,4.07,0.79,6.17c0.8,3.82,2.16,6.4,4.16,7.88c0.93,0.69,2.06,1.18,3.27,1.4c2,0.38,4.16,0.05,6.09-0.9
    c1.75-0.87,3.22-2.23,4.16-3.81c1.02-1.73,1.43-3.81,1.19-5.89c-0.24-1.97-1.09-4.03-2.59-6.31c-0.75-1.14-1.57-2.19-2.78-3.64
    c3.1,0.77,5.85,1.59,8.39,2.5c3.79,1.35,7.38,3.01,10.68,4.91c5.05,2.91,8.94,6.15,11.87,9.89c2.28,2.91,3.87,5.95,4.6,8.8
    C344.81,407.95,343.7,413.44,340.44,418.45z"/>
</svg>

Enter fullscreen mode Exit fullscreen mode

Optimize the code

Before proceeding further I use SVGOMG to optimize the code generated from Illustrator. Just paste the code and the tool will do the rest. The default settings are good, but you're free to play with them to obtain an higher o lower optimization.

Mine SVG after the optimization is 88% lighter.

Click the icon to copy the optimized code and paste it in your code editor into a new HTML file.

Set up the playground

Create a new CSS file and, just for demo purpose, center the SVG in the viewport, how to do it? Well it's pretty simple, the SVG element is a block element so there's no magic here

svg {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
}
Enter fullscreen mode Exit fullscreen mode

What I want to achieve is to animate the outline, making it look like it's being drawn.

First of all we need to define an initial state and for that we need two properties stroke-dasharray and stroke-dashoffset. What this two properties does is simple:

  • stroke-dasharray define the pattern of dashes and gaps in and outline of a shape.
  • stroke-dashoffset define the offset on the rendering of the associated dash array.

Which number do you need to use in this two properties, well, you can guess it, or you can use Javascript to find the right one.

Let's find the path length

To find out the right path length you can use the code below:

let path = document.querySelector('path');
let pathLength = path.getTotalLength();
console.log(pathLength)
Enter fullscreen mode Exit fullscreen mode

A more advanced solution can be the one where you modify a CSS variable with Javascript, but it's up to you to understand how :)

The code above will print in the console the path length. That number is the one that we need to give to stroke-dasharray, and the same value, but negative, to stroke-dashoffset.

Create the animation

To animate the outline we need to use our old friend, the keyframes

path {
  stroke-dashoffset: -1419;
  stroke-dasharray: 1419;
}

@keyframes draw-logo {
  from {
    stroke-dashoffset: -1419;
  }
  to {
    stroke-dashoffset: 0;
  }
}
Enter fullscreen mode Exit fullscreen mode

What this code mean? We create an initial breakpoint where the stroke-dashoffset is set to the negative value of the path length (in my case -1419, your will be different if you use a different figure) and then we set a final breakpoint where stroke-dashoffset is set to 0. In other words we can translate this animation as follows "from hidden to fully drawn".

If you want to invert the line drawing you need to change -1419 to 1419.

Apply the animation

Now that we've the animation in place we can apply it to the SVG path. For this purpose we need to use the animation-* properties.

path {
  stroke-dashoffset: -1419;
  stroke-dasharray: 1419;
  animation-name: draw-logo;
  animation-duration: 2s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-tiiming-function: ease-in;
  animation-fill-mode: forwards;
}

@keyframes draw-logo {
  from {
    stroke-dashoffset: -1419;
  }
  to {
    stroke-dashoffset: 0;
  }
}
Enter fullscreen mode Exit fullscreen mode

Let's analyze what we've written

  • animation-name: it's pretty simple is the name of the animation that we created before using the @keyframes
  • animation-duration: how much time the animation need to complete
  • animation-iteration-count: how many times the animation it'll repeated
  • animation-direction: where the animation go, the value are normal, reverse, alternate and alternate-reverse play with it
  • animation-timing-function: how the animation progresses during his cycle
  • animation-fill-mode: what styles the animation applies before and after its execution.

You can use the shorthand animation, but it's not really understandable like other ones like font, background and others.

You can check the final result here

Conclusion

Well done, you've created your first SVG animation with CSS and a little bit of JS.

What do you think? Let me know in the comments :)

Top comments (0)