This tutorial is out of date and no longer maintained.
Some time ago I see this fun demo in Codepen, by Akimitsu Hamamuro. Then I think that it would be great to be able to draw things programmatically in the web. Unfortunately, I could not find any library to do it, so I’ve developed one, using that pen as base.
In this tutorial, we’ll see how to use this new library to draw creative brushstrokes directly in the browser with a nice API. We’ll be able to draw solid colors, images, or even HTML!
Specifically, we will be learning how to build a creative poster like this:
Getting started with the Brushstroke
library is pretty simple. You only need to include the script and start drawing things:
<!-- Optional dependencies goes here -->
<script src="dist/brushstroke.min.js"></script>
<script>
// Options for customization
var options = {
duration: 1,
queue: true
};
// Initialization
var bs = new Brushstroke(options);
// Draw, erase, etc...
bs.draw();
bs.erase();
bs.draw();
</script>
This is just a very basic example. You can find detailed documentation in the GitHub repo.
As you may see, our poster consists of a background image and text. Let’s see how to animate the drawing of the background image.
First, we need to initialize a new Brushstroke
instance for the background image, with all the options we want. Please learn more about each option in the GitHub repo.
// Declaring variables
var width = window.innerWidth || document.body.clientWidth;
var height = window.innerHeight || document.body.clientHeight;
var optionsBackground, bsBackground;
// Random curves for background
optionsBackground = {
animation: 'points',
points: 10,
inkAmount: 5,
size: 300,
frames: 10,
frameAnimation: true,
splashing: false,
image: 'images/background.jpg',
centered: true,
queue: true,
width: width,
height: height
};
bsBackground = new Brushstroke(optionsBackground);
Now we can start drawing things, and more!
Let’s see how to achieve the effect we want for our poster:
// Function to start the animation
function runAnimation() {
// Draw a straight line
bsBackground.draw({
points: [0, height / 2 - 40, width, height / 3]
});
// Draw another straight line
bsBackground.draw({
points: [width, height / 2, 0, height / 1.5 - 40]
});
// Draw a curve generated using 20 random points
bsBackground.draw({
inkAmount: 3,
frames: 100,
size: 200,
splashing: true,
points: 20
});
}
// Start
runAnimation();
Our library is not able to draw text as is, but it can draw along any SVG path
provided. So we can draw our text as SVG paths, and then we can pass the paths to the library.
After render, scale up, and simplify the paths (CTRL+L
) to create smother shapes of our text, our SVG looks like this:
Now we have our text as single-stroke SVG paths, and we can use them to draw with the Brushstroke
library!
First, we need to include the SVG in the HTML:
<!-- Each path is a letter in "Scotch.io" string -->
<svg width="1000" height="300" style="display: none">
<path d="m157.76 105.88c-7.4053-8.9862-16.122-15.85-27.865-17.818-16.604-3.2803-35.244-2.2435-50.148 6.2719-8.4329 6.4228-15.194 15.018-10.757 25.919 6.9636 23.286 33.81 26.063 53.267 33.499 15.84 4.0064 32.554 13.238 35.503 30.658 1.8468 11.869-0.78168 21.884-11.233 28.659-14.576 8.9259-33.167 9.5932-49.689 6.8414-12.29-2.3318-20.767-8.5079-28.636-18.075"/>
<path d="m272.9 150.66c-9.8598-11.768-23.423-22.368-39.709-19.191-13.362 0.5304-25.61 11.328-31.775 22.54-6.7138 13.934-7.1853 29.748-0.25697 43.707 5.5237 11.364 17.648 21.717 30.492 23.311 15.813 2.8302 30.126-5.4593 39.688-17.63l1.2482-1.2482 0.31262-0.31262"/>
<path d="m343.27 131.47c-15.039 5.7827-27.96 17.873-30.612 34.262-4.0296 12.888 0.41254 27.839 7.52 38.602 9.0267 11.179 22.414 19.394 37.213 16.695 13.362-0.53038 25.61-11.328 31.775-22.54 6.7139-13.934 7.1853-29.748 0.25697-43.707-5.5237-11.364-17.648-21.717-30.492-23.311h-15.661z"/>
<path d="m445.62 86.692c0.37493 36.778-0.74805 73.798 0.55819 110.42 2.5876 11.039 6.138 21.243 18.469 23.832 4.2802 0.18855 8.6454 0.0288 12.958 0.0819m-51.176-89.559h44.779"/>
<path d="m586.36 150.66c-9.8598-11.768-23.423-22.368-39.709-19.191-13.362 0.5304-25.61 11.328-31.775 22.54-6.7139 13.934-7.1853 29.748-0.25697 43.707 5.5237 11.364 17.648 21.717 30.492 23.311 15.813 2.8302 30.126-5.4593 39.688-17.63l1.2482-1.2482 0.31262-0.31262"/>
<path d="m631.14 86.692v134.34m0-63.971c12.158-12.114 24.92-29.2 44.341-25.588 10.207-0.53645 22.347 4.9455 22.978 16.444 6.3533 18.657 1.559 39.122 3.0479 58.568v14.546"/>
<path d="m752.68 189.04c-15.025 6.5899 6.2843 18.544 5.1489 5.1489l-5.1489-5.1489z"/>
<path d="m797.46 86.692c6.5899 15.025 18.544-6.2843 5.1489-5.1489l-5.1489 5.1489zm6.3971 44.779v89.559"/>
<path d="m880.62 131.47c-15.039 5.7827-27.96 17.873-30.612 34.262-4.0295 12.888 0.41253 27.839 7.52 38.602 9.0268 11.179 22.414 19.394 37.213 16.695 13.362-0.53038 25.61-11.328 31.775-22.54 6.7139-13.934 7.1853-29.748 0.25697-43.707-5.5237-11.364-17.648-21.717-30.492-23.311h-15.661z"/>
</svg>
Then we can use those SVG paths in our library to draw the text:
// Declaring variables
var optionsPath, bsPath;
// Options for text (SVG paths)
optionsPath = {
animation: 'path',
inkAmount: 2,
frames: 20,
frameAnimation: true,
color: 'white',
width: 1000,
height: 300
};
// Initializing
bsPath = new Brushstroke(optionsPath);
// Draw each letter of the text, with a delay among them
var paths = document.querySelectorAll('path');
var delay = 0;
for (var i = 0; i < paths.length; i++) {
bsPath.draw({path: paths[i], delay: delay});
delay += 0.5;
}
Finally, we’d like to provide an option to repeat the animation in our poster, so we can see it again and again.
The idea is to draw the entire screen with a solid black
color (like erasing), and then run our poster animation again. Let’s see the implementation:
// Declaring variables
var button = document.querySelector('button');
var animating = true;
var optionsErase, bsErase;
// Erase and run again
optionsErase = {
queue: true,
size: 300,
padding: 0,
overlap: 100,
inkAmount: 20,
frames: 100,
frameAnimation: true,
color: '#000',
width: width,
height: height,
end: function () {
// Clear all canvas and run animation
bsBackground.clear();
bsPath.clear();
bsErase.clear();
runAnimation();
}
};
bsErase = new Brushstroke(optionsErase);
// Run again button
button.addEventListener('click', function () {
if (!animating) {
toggleButton();
bsErase.draw();
}
});
function toggleButton() {
button.classList.toggle('hidden');
animating = !animating;
}
And that’s all!
With a bit of styling to get things in the right place, we should have a beautiful and creative poster using brushstroke animations :)
As always, you can check the final demo here, and also get the full code and documentation on GitHub. There are more exciting features waiting for you there!
We really hope you liked this tutorial and find it useful!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.