Drawing Creative Brushstrokes with JavaScript

0
106

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

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 a detailed documentation in the github repo.

#Drawing the Background Image

As you may see, our poster consists of a background image and a 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();

#Drawing the Text

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. For this demo, we’ve used the “Hershey Text” extension available in the Inkscape vector editor (from version 0.91 or newer). You can find more info about it here.

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;
}

#Adding “Run Again” Functionality

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;
}

#Conclusion

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!

Suggest

The Complete JavaScript Course

Angular, React.js & Vue.js – Quickstart & Comparison

Webpack 2: The Complete Developer’s Guide 

LEAVE A REPLY

Please enter your comment!
Please enter your name here