hswaw/site: wip new layout

Change-Id: I4da3a668429dee42c7292accb9e24b93703f1538
diff --git a/hswaw/site/static/led.js b/hswaw/site/static/led.js
new file mode 100644
index 0000000..61580f0
--- /dev/null
+++ b/hswaw/site/static/led.js
@@ -0,0 +1,72 @@
+import { animations } from "./animations.js";
+
+class CanvasRenderer {
+    static WIDTH = 1024;
+    static HEIGHT = 1024;
+
+    constructor() {
+        const ledDiv = document.querySelector("#leds");
+        let canvas = document.createElement("canvas");
+        canvas.style.width = "100%";
+        canvas.style.height = "100%";
+        canvas.width = CanvasRenderer.WIDTH;
+        canvas.height = CanvasRenderer.HEIGHT;
+        ledDiv.appendChild(canvas);
+        ledDiv.style.backgroundColor = "#00000000";
+        let context = canvas.getContext('2d');
+
+        this.canvas = canvas;
+        this.context = context;
+    }
+
+    render(animation) {
+        const canvas = this.canvas;
+        const context = this.context;
+        const leds = animation.leds;
+        const nx = animation.nx;
+        const ny = animation.ny;
+
+        const xoff = CanvasRenderer.WIDTH / (nx + 1);
+        const yoff = CanvasRenderer.HEIGHT / (ny + 1);
+        const d = xoff * 0.7;
+
+        context.clearRect(0, 0, canvas.width, canvas.height);
+        for (let x = 0; x < nx; x++) {
+            for (let y = 0; y < ny; y++) {
+                const cx = (x + 1) * xoff
+                const cy = (y + 1) * yoff
+
+                const rgb = leds[x][y];
+                const r = Math.max(rgb[0] * 256, 0x1a);
+                const g = Math.max(rgb[1] * 256, 0x16);
+                const b = Math.max(rgb[2] * 256, 0x22);
+                const color = `rgba(${r}, ${g}, ${b})`;
+
+                context.beginPath();
+                context.arc(cx, cy, d/2, 0, 2 * Math.PI, false);
+                context.fillStyle = color;
+                context.fill();
+            }
+        }
+    }
+}
+
+window.addEventListener("load", () => {
+    const animationClass = animations[Math.floor(Math.random() * animations.length)];
+    console.log(`Picked LED animation: ${animationClass.name}`);
+
+    let renderer = new CanvasRenderer();
+    let animation = new animationClass(16, 16);
+
+    let step = (hrts) => {
+        // Run animation logic.
+        animation.draw(hrts / 1000);
+
+        // Draw LEDs.
+        renderer.render(animation);
+
+        // Schedule next frame.
+        window.requestAnimationFrame(step);
+    }
+    window.requestAnimationFrame(step);
+});