JSFiddle - React, Tailwind, and code Playground

by Darby Rathbone

HTML

<canvas id="myCanvas" width="500" height="250"></canvas>

CSS

body {
       margin: 0px;
       padding: 0px;
       background: #f1ecec;
   }

JavaScript

(function() {
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;
}());

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var circles = [];

context.fillRect(80, 80, 100, 100);
context.globalCompositeOperation = 'xor';

var backup = document.createElement('canvas'),
    bctx = backup.getContext('2d');

backup.width = canvas.width;
backup.height = canvas.height;

bctx.drawImage(canvas, 0, 0);

var offset = 0;
function animate(current) {
    context.lineWidth = 1;
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.drawImage(backup, 0, 0);
    
    context.setLineDash([8, 16]);
    
    context.lineDashOffset = -offset;
    drawClipped(context, [0, 0, 500, 0, 500, 500], drawCircle);
    
    context.lineDashOffset = offset;
    drawClipped(context, [0, 0, 0, 500, 500, 500], drawCircle);
    
    offset++;
    
    requestAnimationFrame(animate);
}
/*
    context.beginPath();
    context.setLineDash([8, 16]);
    context.lineDashOffset = offset;
}
*/
function drawClipped(ctx, path, cb) {
    if (!Array.isArray(path) || path.length/2 != ~~(path.length/2))
        throw new Error('Path must be an array with an even number of elements');
    
    ctx.save();
    ctx.beginPath();
    
    ctx.moveTo(path.shift(), path.shift());
    while (path.length) {
        ctx.lineTo(path.shift(), path.shift());
    }
    ctx.clip();
    cb(ctx);
    ctx.restore();
}
function drawCircle(ctx) {
    ctx.save();
    ctx.beginPath();
    ctx.arc(80, 80, 40, Math.PI * 1.25, Math.PI * 3.25, 0);
    ctx.stroke();
    ctx.restore();
}
animate();