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();