SVG, Inkscape, anime.js
Emulate and Animate Hand Writing with SVG
Emulate and Animate Hand Writing with SVG
Original Manuscript from 'Le Bateau Ivre' by Arthur Rimbaud

Earlier this year, I went to an exhibition about Marcel Proust, a French writer in Paris. In the first room, some text was being animated on the wall. It was the begining of Du côté de chez Swann, brought back to life with its own hand writing. The strokes were flowing, then corrected, then crossed, and written again. It was like witnessing the author during his work. I wanted to try it out and I am explaining here how to reproduce this same effect with Inkscape and javascript. I'm using the same technique in Collage & Code to animate the first painting.

1. Drawing SVG paths with Inkscape from a picture
2. From Inkscape to HTML
3. Animating the path with anime.js

1. Drawing SVG paths with Inkscape from a picture

Inkscape is an open source tool to draw SVGs. It comes with a lot of features and in-house algorithms to edit and draw SVGs. It is often compared with Illustrator, its Adobe alternative. To bring an animated text to life, we need first to load our picture, reduce its opacity and get the Bezier curve tool to follow the paths.

Layers and Bezier Curve
header
on the left, the bezier curve tool / on the rights, layers and opacity


With the bezier curve tool, it is time to follow the writing paths. Note that you can always edit your paths later. Usually, I draw a first version and polish it afterwards. To simulate hand writing, I recommend to follow the natural way to write: when you will animate the text, it will follow the order of the points of the bezier curves (ie: do not start with the last letter in the reversed way for example).

header
Drawing the first version
header
Polishing and editing some nodes of the curves


Some take aways from the few drawings I did in the past:

• Organize your layers. By default, Inkscape does not create layers. It will become really convenient at some point, for example to compare the real picture with your path (toggling and opacity)

• When saving your files, the Inskcape default viewBox will be the one exported in your svg. Go to "Document Properties > Page" if you want your viewBox to match with the selection for example.

• Remove your picture layer before saving. If you just hide it, the image will still be exported to your svg file which is not optimal

In the next part, we'll see what the svg part is and how to prepare it before the animation.

2. From Inkscape to HTML

Your SVG now has to be incorporated in your page. This can be done in different ways depending on whether or not you're using a javascript framework, raw html files etc. We will break it out with core HTML. Of course, you can use tools such as vue-svg-loader and other frameworks eauivalent instead.

• You can get bring your raw svg file into the page

• Check how it is built. Usually, you will see a group matching with your layer and all your different paths. If you group your paths in Inkscape, they will be grouped in the SVG tags too.

• Inkscape will always gives to the file the viewBox we talked about earlier along with width and height. When working with SVG on the web, I personnally prefer to remove width and height, and only tweak the viewBox and div containers to avoid sizes issues and responsiveness problems.

• As a last note, the property we are going to use to animate the text is the stroke-dasharray property. In Inkscape, this property is sometimes set to stroke-dasharray:none; in the style of the path, after changing some stroke properties. You will have to remove it for every path otherwise you will not be able to animate it. You can also do it in javascript before the animation.

3. Animating the path with anime.js

Once your SVG is brought to your page, we are ready to animate it. I'm using here anime.js which can be imported from your HTML document, or with your javascript framework. The documentation is very well explained and full of visuals to the different effects.

I recommend to check if it works with a div transform as follow:

anime({
  targets: 'div',
  translateX: 250,
  rotate: '1turn',
  backgroundColor: '#FFF',
  duration: 800
});

The following will translate and rotate all the div of the page in 800 milliseconds, and change their background to white.


As metioned earlier, the property we are going to change is the stroke-dasharray. The anime.js SVG documentation comes with external resources to better explain what is happening under the hood. We can try it out to see if our SVG is being animated. We are targetting all the SVG paths of the page but you can select ids and classes as well.

anime({
  targets: 'svg path',
  strokeDashoffset: [anime.setDashoffset, 0],
  easing: 'easeInOutSine',
  duration: 1500,
  delay: function(el, i) { return i * 250 },
  direction: 'alternate',
  loop: true
});
The animation should now look like the one below. Your text is being animated but does not really follow someone writing as letters are written almost at the same time.

header
A synchronous animation we want to avoid to reflect normal writing


Instead, we want to wait for every letter to be fully written before starting to write the next one. To do that, I'm giving the duration of every path its own length multiplied by a slow factor. And I'm incrementing the delay with an offset matching with the length of the animation.
let offset = 0;
let slowFactor = 100;

anime({
  targets: 'svg path',
  strokeDashoffset: [anime.setDashoffset, 0],
  easing: 'easeInOutSine',
  duration: function(el, i) { 
    offset += el.getTotalLength() * slowFactor;
    return el.getTotalLength() * slowFactor;
  },
  delay: function(el, i) { 
    return offset - offset/10;
  },
});

header
Animating text following the natural way to write thanks to anime.js

References

  • Original Picture by Gallica BNF - Arthur Rimbaud. Poèmes. II Manuscrits autographes
  • Tool for SVG editing - Inkscape
  • Animation library by Julian Garnier - anime.js
  • © 2020-2023 Loris Mat