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
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>
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;
}
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)
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;
}
}
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;
}
}
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 arenormal
,reverse
,alternate
andalternate-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)