Erase effect in HTML canvas using JavaScript

It feels interactive when you discover an image by erasing the screen with mouse pointer. In this article, I am going to show how to make erase effect using HTML canvas with the help of JavaScript.

The logic behind it is creating a HTML element with background image, and then drawing a canvas above it. Therefore, the background image will not be visible by default. Moreover, erasing the canvas with help of another shape (brush) on mouse event.

So let us start with this.

You will need an image for background, a brush png image, jQuery and a HTML file. Create the HTML and include jQuery.
Try below code.

HTML Document


<style>
            #canvas {
                background: url('background_image.jpg');
                background-size: cover;
                width: 100%;
                height: 100%;
                position: fixed;
            }
</style>
<script>
            $(document).ready(function () {
                var container = document.getElementById('canvas');
                init(container, $('#canvas').width(), $('#canvas').height(), '#fff');
            });

            function createCanvas(parent, width, height) {
                var canvas = {};
                canvas.node = document.createElement('canvas');
                canvas.context = canvas.node.getContext('2d');
                canvas.node.width = width || 100;
                canvas.node.height = height || 100;
                parent.appendChild(canvas.node);
                return canvas;
            }

            var Trig = {
                distanceBetween2Points: function (point1, point2) {

                    var dx = point2.x - point1.x;
                    var dy = point2.y - point1.y;
                    return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
                },
                angleBetween2Points: function (point1, point2) {
                    var dx = point2.x - point1.x;
                    var dy = point2.y - point1.y;
                    return Math.atan2(dx, dy);
                }
            }

            function init(container, width, height, fillColor) {
                var canvas = createCanvas(container, width, height);
                var ctx = canvas.context, lastMousePoint = {x: -1, y: -1};
                // define a custom fillCircle method
                ctx.getRandomOffset = function (radius) {
                    var random_angle = Math.random() * (2 * Math.PI);
                    var random_radius = Math.random() * radius;
                    return {
                        x: Math.cos(random_angle) * random_radius,
                        y: Math.sin(random_angle) * random_radius
                    };
                };
                ctx.enerateSprayParticles = function (x, y, radius, fillColor) {
                    // Particle count, or, density
                    var density = 10;

                    for (var i = 0; i < density; i++) {
                        var offset = ctx.getRandomOffset(radius);

                        x = x + offset.x;
                        y = y + offset.y;

                        this.fillStyle = fillColor;

                        ctx.fillRect(x, y, 1, 1);
                    }
                };
                ctx.randomBrush = function (x, y, radius, fillColor) {
                    var brush = new Image();
                    brush.src = 'brush.png';

                    var halfBrushW = brush.width / 2;
                    var halfBrushH = brush.height / 2;

                    x = x - halfBrushW;
                    y = y - halfBrushH;

                    if (lastMousePoint.x == -1 && lastMousePoint.y == -1) {
                        lastMousePoint.x = x;
                        lastMousePoint.y = y;
                    }

                    var start = {x: lastMousePoint.x, y: lastMousePoint.y};
                    var end = {x: x, y: y};

                    var distance = parseInt(Trig.distanceBetween2Points(start, end));
                    var angle = Trig.angleBetween2Points(start, end);

                    var tx, ty;

                    for (var z = 0; (z <= distance || z == 0); z++) {
                        tx = start.x + (Math.sin(angle) * z);
                        ty = start.y + (Math.cos(angle) * z);
                        ctx.drawImage(brush, tx, ty);
                    }

                    lastMousePoint.x = tx;
                    lastMousePoint.y = ty;
                    return;
                }
                ctx.fillCircle = function (x, y, radius, fillColor) {
                    ctx.randomBrush(x, y, radius, fillColor);
                };
                ctx.clearTo = function (fillColor) {
                    ctx.fillStyle = fillColor;
                    ctx.fillRect(0, 0, width, height);
                };
                ctx.clearTo(fillColor || "#ddd");

                ctx.getPointerEvent = function (event) {
                    return event.originalEvent.touches ? event.originalEvent.touches&#91;0&#93; : event;
                }

                $(document).bind('touchstart mouseenter', function (event) {
                    event.preventDefault();
                    var e = ctx.getPointerEvent(event);
                    var x = e.pageX;// - this.offsetLeft;
                    var y = e.pageY;// - this.offsetTop;

                    var brush = new Image();
                    brush.src = 'brush.png';

                    var halfBrushW = brush.width / 2;
                    var halfBrushH = brush.height / 2;

                    x = x - halfBrushW;
                    y = y - halfBrushH;

                    lastMousePoint.x = x;
                    lastMousePoint.y = y;
                });

                $(document).bind('touchmove touchend mousemove', function (event) {

                    event.preventDefault();

                    var e = ctx.getPointerEvent(event);

                    var x = e.pageX;// - this.offsetLeft;
                    var y = e.pageY;// - this.offsetTop;

                    var radius = 10; // or whatever
                    var fillColor = '#ff0000';
                    ctx.globalCompositeOperation = 'destination-out';
                    ctx.fillCircle(x, y, radius, fillColor);
                });
                canvas.node.onmousedown = function (e) {
                    canvas.isDrawing = true;
                };
                canvas.node.onmouseup = function (e) {
                    canvas.isDrawing = false;
                };
            }
        </script>
<div id="canvas"></div>

Hope this helped.

Share this Post