Are you looking for a non-standard portfolio page welcome text? Do you want to create an animated website to propose to your loved one?
Say no more!
In this #showdev I'll teach you how to create stunning SVG animation with an equally stunning animejs
library!
The result will look like this:
NOTE: This post will show you how to create a line drawing animation in animejs. If you want it in a condensed form, straight from the source, visit the official documentation.
Prerequisites
To create a stunning animated SVG image, first, you will need SVG to animate. There are many tools to do that, available both online and offline. You can, for example, start with generating text using easysvg (written in php, but a great tool nonetheless).
Important: Every letter in your SVG should be a separate
<path>
tag! Here paths mark the outlines of the letters.
You will also need a container to run the animation in. It can be anything, pure JS script or a more advanced app. In my case, I'm using a very simple Vue.js app.
Preparing your SVG
To make our SVG look classy, we need to tweak it a bit:
To provide it with an "outlined" look, set
fill
attribute in every<path>
tag totransparent
and setstroke
attribute to any color you want.Add some extra elements for flavor - directly in SVG code (if you're the pro and a math nerd) or use some editor to do it.
Use my SVG, if you want: link to github file.
Animating
First, install animejs
. %[github.com/juliangarnier/anime]
Then add animejs animation:
anime({
targets: document.getElementsByTagName('svg')[0].children,
strokeDashoffset: [anime.setDashoffset, 0],
easing: 'easeInOutBack',
delay: function(el, i) { return i * 250 },
direction: 'normal',
});
Easy? Let me break it down line by line!
targets: document.getElementsByTagName('svg')[0].children,
In this line, we point to every element we want to animate, in this case to an array of every child element of our SVG. You may need to adjust it a little to the structure of your SVG.
strokeDashoffset: [anime.setDashoffset, 0],
This is what makes animation happen. It uses stroke-dashoffset
attribute. If you want to know more about animating SVGs using this attribute, I recommend this CSS Tricks article.
easing: 'easeInOutBack',
I wanted to add a little "bouncing" at the beginning and the end of the animation of every letter. If you want to test different easing functions on your own, I recommend easings.net.
delay: function(el, i) { return i * 250 },
I wanted to slightly delay every animated path, so I passed a function that multiplies the delay by the index of an element in the table I passed in targets
.
direction: 'normal',
You can choose from normal
, reverse
, and alternate
.
Embed this... somewhere
Although animejs can be used in Vanilla, I really wanted to use it in my Vue.js app.
I used Vue.js transitions to do that. More on them.
First, template:
<Transition appear :css="false" @enter="onEnter" name="howdy">
<!-- Your SVG goes here. I used v-html because I'm lazy ¯\_(ツ)_/¯ -->
<div v-html="howdy" />
</Transition>
You can use SVG Component to embed your SVG on a page.
I wanted my animation to start on a component render, so I added appear
keyword to the transitions. I also needed to tell Vue this animation would be purely JS, so I used :css="false"
.
Now I only need to write onEnter
callback:
const onEnter = (el: Element, done: () => void) => {
anime({
targets: el.getElementsByTagName('svg')[0].children,
strokeDashoffset: [anime.setDashoffset, 0],
easing: 'easeInOutBack',
delay: function(el, i) { return i * 250 },
direction: 'normal',
complete: () => {
done();
},
});
}
onEnter
uses the Transition Element as the first argument and done()
function as the second. We have to call done()
function at the end of the application to signal to Vue that the animation ended. We can use complete
hook from animejs to do it. And we want to animate only descendants of our Transition element, so we can specify targets
using the first argument.
And... that's it! Sit back and enjoy your animated text!
If you have any questions, I'm happy to answer :) If there's anything to be improved in this short post, let me know, and I'll gladly fix that!
And if you want to see this animation in action, you can visit my page (I have to warn you though, this is still in a WIP stage).
All the best,
Aleksandra (or Ola, for short)