JSFiddle - React, Tailwind, and code Playground
by Christian Sonne
HTML
<canvas id="c"></canvas>
CSS
html, body {
margin: 0;
padding: 0;
line-height: 0;
}
JavaScript
let W = c.width = window.innerWidth;
let H = c.height = window.innerHeight;
function cross(a, b) {
return [
a[1] * b[2] - a[2] * b[1],
a[2] * b[0] - a[0] * b[2],
a[0] * b[1] - a[1] * b[0]
];
}
function length(v) {
return Math.sqrt(v[0]**2 + v[1]**2 + v[2]**2)
}
let r = Math.max(W, H) / 2;
let segments = 9;
let points = [[W / 2, H / 2, 1]];
let triangles = [];
for (let idx = 0; idx < segments; idx++) {
points.push([
W / 2 + Math.cos(2 * Math.PI / segments * idx) * r,
H / 2 + Math.sin(2 * Math.PI / segments * idx) * r,
0
]);
triangles.push([0, idx + 1, (idx + 1) % segments + 1]);
}
console.log(triangles);
console.log(points);
let ctx = c.getContext("2d");
function draw() {
for (let tri of triangles) {
let a = points[tri[0]];
let b = points[tri[1]];
let c = points[tri[2]];
let ab = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];
let lab = length(ab);
ab = ab.map(c => c/lab);
let ac = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];
let lac = length(ac);
ac = ac.map(c => c/lac);
let cr = cross(ab, ac);
console.log(cr);
let angle = Math.atan2(cr[1], cr[0]);
let hsl = `hsl(${angle}rad, 60%, 70%)`;
ctx.fillStyle = hsl;
ctx.beginPath();
let [x, y, z] = points[tri[0]];
ctx.moveTo(x, y);
[x, y, z] = points[tri[1]];
ctx.lineTo(x, y);
[x, y, z] = points[tri[2]];
ctx.lineTo(x, y);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
points[0][2] += (Math.random() - 0.5);
window.requestAnimationFrame(draw);
}
draw();