JSFiddle - React, Tailwind, and code Playground
by Andrew Dunai
HTML
<a href="#" class="generate">Generate lightning</a>
<div>
<canvas class="canvas" width="400" height="400"></canvas>
</div>
CSS
.generate {
padding: 10px;
border: 1px solid #000;
display: inline-block;
color: #000 !important;
text-transform: uppercase;
text-decoration: none !important;
font-family: sans-serif;
margin: 0 0 1rem;
}
JavaScript
var $canvas = document.querySelector('.canvas');
var ctx = $canvas.getContext('2d');
ctx.fillStyle = '#002';
ctx.strokeStyle = '#FFF';
ctx.imageSmoothingEnabled = true;
var step = function(start, attraction, limit, width, left) {
if (limit <= 0) {
return;
}
if (width < 0.25) {
// width = 0.25;
}
//var dx = Math.random() * 20 - 10;
//var dy = 10;
var rotated = rotate(0, 0, attraction[0], attraction[1], left ? Math.random() * -45 : Math.random() * 45);
var end = [start[0] + rotated[0] * Math.random() * 20, start[1] + rotated[1] * Math.random() * 20];
ctx.beginPath();
ctx.lineWidth = width;
ctx.moveTo(start[0], start[1]);
ctx.lineTo(end[0], end[1]);
ctx.closePath();
ctx.stroke();
if (Math.random() * 100 <= 10) {
var rotated1 = rotate(0, 0, rotated[0], rotated[1], -22.5);
var rotated2 = rotate(0, 0, rotated[0], rotated[1], 22.5);
step(end, rotated1, limit - 2 * Math.random(), width * 0.9, true);
step(end, rotated2, limit - 2 * Math.random(), width * 0.9, false);
} else {
step(end, rotated, limit - 2 * Math.random(), width * 0.9, !left);
}
};
function rotate(cx, cy, x, y, angle) {
var radians = (Math.PI / 180) * angle,
cos = Math.cos(radians),
sin = Math.sin(radians),
nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
return [nx, ny];
}
var makeNew = function() {
ctx.rect(0, 0, 400, 400);
ctx.fill();
step([200, 0], [0, 1], 25, 5, Math.random() >= 0.5);
//alert(rotate(0, 0, 0, 1, 45));
};
document.querySelector('.generate').addEventListener('click', makeNew);
makeNew();