Led lamp animation test
(c) 2020 All rights reserved
by PhilQ
HTML
<div id="lamp"></div>
<button id="run">Run animation</button>
SCSS
*, :before, :after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100vw;
height: 100vh;
}
body {
display: flex;
justify-content: center;
align-items: center;
font-family: Helvetica;
background: #20262E;
}
#lamp {
width: 400px;
height: 300px;
position: relative;
}
#run {
position: absolute;
top: 10px;
right: 10px;
font-size: 20px;
}
.led {
position: absolute;
color: rgba(0,0,0, 0.1);
// background: #fff;
width: 1px;
translate: -50% -50%;
aspect-ratio: 1/1;
transition: color 500ms linear;
&:before {
content: '';
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
width: 76%; // 3.8/5
aspect-ratio: 1/1;
background: currentColor;
border-radius: 50%;
}
}
JavaScript
let lamp, cnv, ctx;
let zoom = 4;
const leds_w = 32;
const leds_h = 16;
const canvas = {
w: 400,
h: 300,
};
const center = {
x: canvas.w / 2,
y: canvas.h / 2,
};
const led = {
w: 5,
h: 5,
r: 3.8,
d_strip: 1000/144, // strip length / led
a_ring: 360/16, // angle / led
d_ring: 39.5 / 2, // distance from center
o_ring: 55.9, // ring distance center-to-center
};
const leds = [];
const el = (s, p = document) => {
return p.querySelectorAll(s);
}
const addLed = (x, y, a = 0) => {
let e = document.createElement('div');
e.classList.add('led');
e.style.width = `${zoom*led.w}px`;
e.style.height = `${zoom*led.h}px`;
e.style.left = `${x}px`;
e.style.top = `${y}px`;
e.style.rotate = `${a}deg`;
lamp.append(e);
leds.push(e);
}
const drawRing = (sx, sy) => {
for (let i = 0; i < 16; i++) {
addLed(
sx + zoom * led.d_ring * Math.sin(Math.PI * 2 * (i/16)),
sy + zoom * led.d_ring * -Math.cos(Math.PI * 2 * (i/16)),
i * led.a_ring // Maybe * -1
);
}
}
const drawStrips = (start = 0) => {
// 4 strips, starting at top (0), added counter-clockwise
for (let i = start; i < start + 4; i++) {
let a = (i%4) * -90;
let dx = (i%2)== 0 ? ((i%4)==0 ? -1: 1) : 0;
let dy = (i%2)== 0 ? 0 : ((i%4)==1 ? 1: -1);
let total = ((i%2)== 0 ? leds_w : leds_h) - 1;
let sx = center.x + (zoom * led.d_strip * (leds_w - 1) * 0.5 * (dx==0 ? -dy : -dx));
let sy = center.y + (zoom * led.d_strip * (leds_h - 1) * 0.5 * (dy==0 ? dx : -dy));
for (let j = 0; j < total; j++) {
addLed(
sx + zoom * led.d_strip * dx * j,
sy + zoom * led.d_strip * dy * j,
a
);
}
}
}
const colorLeds = (color, interval, i = 0) => {
leds[i++].style.color = color;
if (i < leds.length) {
setTimeout(() => {
colorLeds(color, interval, i);
}, interval);
}
}
const runColors = (colors, duration, interval, loop = false, i = 0) => {
colorLeds(colors[i++], interval, 0);
if (i < colors.length) {
// Next color
setTimeout(() => {
runColors(colors,...