Jo Clark is an illustrator and author with her own greetings card and gifts business. She created her logo from her own distinctive handwriting.
As the logo is formed from handwriting, it seems fitting to animate it using a technique which gives the appearance of the letters being drawn by an invisible hand in realtime.
There is a technique for producing this effect in CSS.
SVG line animation using CSS stroke-dasharray and stroke-dashoffset properties
By setting the stroke-dashoffset value on the paths of an SVG and reducing the stroke-dashoffset property value in increments, the paths appear to be automatically be drawn in realtime.
An explanation for this is covered in Jake Archibald’s article Animated Line Drawing in SVG and in Chris Coyer’s article How SVG Line Animation Works.
This technique is going to provide most of what we need to produce the animation, although the overall effect is very linear and can only produce either a solid or dashed stroke. If Jo’s logo is going to be reproduced in the animation exactly (and as it is part of her branding, it needs to remain consistent ), we need a way to retain or reproduce the pencil texture.
CSS image masking
A mask, in this context, allows you to hide certain parts of an element.
Nathan Gordon’s article Masking SVG Animations combines the above line animation technique with CSS masking to gives us another layer to work with that allows something other than a consistent and equal stroked line.
Deviating from the above methods, we are going to be applying a bitmap image mask to the SVG path as opposed to an SVG mask. This is because the logo we are working with exists as a bitmap image only and the original texture of the pencil needs to be retained (exactly) so it cannot be converted to a vector graphic without having to rebrand.
Removing the white from an image
The bitmap gives us another complication in that it has a solid colour background. Photoshop gives us a few tools to remove the background from an image, but we actually need to remove the white from ‘behind’ the pixels too otherwise the mask won’t give us all of the shades and texture of the logo.
Berg Design’s ‘peel off white’ plugin or Media Militia’s Background Removal Photoshop Actions can save a lot of time here.
Creating the SVG path code
In Illustrator we’re going to place the bitmap logo to use as a guide for our path. Using the pen tool with a stroke that’s wide enough to cover the lines of the writing in the bitmap, created a path for each letter of the logo in order. Create the paths as if you were writing; top to bottom for verticals, left to right for crossbars (for right-handed writing).
If you delete any of the paths to recreate them, make sure they sit in the correct order in the layers panel.
You can go to save as an SVG and view the XML output in Illustrator.
Optimising the SVG code
You can do this manually if you know what to remove or use an online tool such as Jake Archibald’s SVGOMG. Keep each letter as a separate path and retain any IDs that you may have given the paths or groups in Illustrator. Remove the bitmap of the logo that we used as a guide.
You should end up with something like this:
<svg xmlns="https://www.w3.org/2000/svg" width="680.401" height="144" viewBox="0 0 680.401 144"><g id="path_1_" opacity=".69" fill="none" stroke="#6D6E71" stroke-width="9"><path d="M42.646 43.826s2.836 16.64 3.512 23.426c.814 8.188-1.45 17.092-3.824 24.887-2.122 6.96-3.486 11.02-7.576 17.23-3.79 5.76-8.618 10.84-12.736 16.41-4.09 5.53-13.375 12.35-13.375 12.35l-2.32-2 1.758-4.94"/>...
Putting it together
So that we can manipulate the SVG paths with CSS, we need to place the SVG inline, wrapped in a containing DIV element.
Give the SVG group an ID or class and create style rules to apply to our bitmap mask.
I used SASS to create a for / next loop to create the delays for each path / letter. We want each letter to finish drawing before we move on to the next, so tweak the animation delay and lengths until this happens.
$paths:16; @for $i from 1 through $paths{ #logo path:nth-child(#{$i}){ animation-delay: #{$i/(3)}s; } }
If you’re not using SASS or other CSS preprocessor, you just need to define increasing animation delays for each path or use javascript to automate the calculations.
Apply the png mask image with a CSS rule for the SVG group
mask-image:url('/images/path-mask.png');
Set the dash array and dash offset values and animation for all paths:
path{ stroke-dasharray: 500; stroke-dashoffset: 500; animation: dash 1s linear forwards; }
The keyframe animation is simply:
@keyframes dash { to { stroke-dashoffset: 0; } }
Here is the complete code, with the SVG path, SCSS, HTML and base64 encoded mask:
See the Pen Animated hand-drawn text using CSS and image masks by sixsixninenine (@sixsixninenine) on CodePen.
Improvements to the animated writing technique
- We could use javascript to automatically calculate the number of paths, animation length and delays. This would remove the trial and error approach to finding the right animation lengths and delays, although the CSS approach does give us more control.
- Add easing to soften the motion.
- Create and apply the css animation.
- Add classes to the tittles and crossbars and draw these at a faster speed to more accurately imitate the writing motion.