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