JSFiddle - React, Tailwind, and code Playground
by jcubed111
HTML
<canvas id="main"></canvas>
CSS
body{
margin: 0;
background: #504b41;
}
JavaScript
const canvas = document.getElementById('main');
const ctx = canvas.getContext('2d');
Array.prototype.shuffle = function() {
for(let i = this.length - 1; i > 0; i--){
const j = Math.floor(Math.random() * i);
[this[i], this[j]] = [this[j], this[i]];
}
return this;
};
const Point = (x, y) => ({
x: x,
y: y,
hash: function() { return `${this.x},${this.y}`; },
});
class Edge{
constructor(from, to) {
this.from = from;
this.to = to;
this.age = 0;
}
}
const edges = [];
const takenPoints = new Set(["0,0"]);
let fringePoints = [Point(0, 0)];
function grow() {
const firstGrowChance = 0.1;
const secondGrowChance = 0.3;
fringePoints = fringePoints.shuffle().flatMap(from => {
const newEdges = [
Point(from.x + 1, from.y),
Point(from.x - 1, from.y),
Point(from.x, from.y + 1),
Point(from.x, from.y - 1),
].filter(
to => !takenPoints.has(to.hash())
).shuffle().filter((_, i) => {
if(i == 0) {
return Math.random() < firstGrowChance;
}else{
return Math.random() < secondGrowChance;
}
});
newEdges.forEach(to => {
newEdges.push(new Edge(from, to));
takenPoints.add(to.hash());
});
if(newEdges.length) {
return newEdges.map(e => e.to);
}else{
return [from];
}
});
}
function render() {
canvas.width = innerWidth;
canvas.height = innerHeight;
ctx.setTransform(1, 0, 0, 1, innerWidth >> 1, innerHeight >> 1);
edges.forEach(e => {
ctx.beginPath();
ctx.moveTo(e.from.x, e.from.y);
ctx.lineTo(e.to.x, e.to.y);
ctx.stroke();
});
}
grow(); grow(); grow();
render();