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.
Inkscape
from a pictureanime.js
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.
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).
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.
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.
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
});
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.
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;
},
});