DEV Community

Cover image for Animate your SVG text with animejs (and Vue)
Ola B
Ola B

Posted on

Animate your SVG text with animejs (and Vue)

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:

Gif of result

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:

  1. To provide it with an "outlined" look, set fill attribute in every <path> tag to transparent and set stroke attribute to any color you want.
  2. 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 logo juliangarnier / anime

JavaScript animation engine

Anime.js

Anime.js V4 logo animation

Anime.js is a fast, multipurpose and lightweight JavaScript animation library with a simple, yet powerful API.
It works with CSS properties, SVG, DOM attributes and JavaScript Objects

NPM Downloads jsDelivr hits (npm) GitHub Sponsors

Sponsors

Anime.js is 100% free and is only made possible with the help of our sponsors. Help the project become sustainable by sponsoring us on GitHub Sponsors.

Platinum sponsors

Silver sponsors

Usage

Anime.js V4 works by importing ES modules like so:




import {
  animate,
  stagger,
} from 'animejs';

animate('.square', {
  x: 320,
  rotate: { from: -180 },
  duration: 1250,
  delay: stagger(65, { from: 'center' }),
  ease: 'inOutQuint',
  loop: true,
  alternate: true
});
Enter fullscreen mode Exit fullscreen mode
Anime.js code example

V4 Documentation

The full documentation is available here.

V3 Migration guide

You can find the v3 to v4 migration guide…




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',
  });
Enter fullscreen mode Exit fullscreen mode

Easy? Let me break it down line by line!

    targets: document.getElementsByTagName('svg')[0].children,
Enter fullscreen mode Exit fullscreen mode

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],
Enter fullscreen mode Exit fullscreen mode

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',
Enter fullscreen mode Exit fullscreen mode

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 },
Enter fullscreen mode Exit fullscreen mode

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',
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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();
    },
  });
}
Enter fullscreen mode Exit fullscreen mode

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)

Top comments (0)