Pan a color highlight across a series of elements
Experimenting with update/render loop and delta ms to calculate state then render color animation from it
by sfoster
HTML
<div id="strip">
<div class="led"></div>
<div class="led"></div>
<div class="led"></div>
<div class="led"></div>
<div class="led"></div>
<div class="led"></div>
<div class="led"></div>
</div>
<div id="message"></div>
<button>Stop</button>
CSS
.led {
display: inline-block;
width: 40px;
height: 40px;
outline: 1px dotted #999;
}
JavaScript
// library stuff
function Color(r,g,b) {
this.r = r;
this.g = g;
this.b = b;
}
Color.prototype = Object.prototype;
function msg(str) {
document.getElementById("message").textContent = str;
}
function setPixelColor(node, color) {
var colorStr = 'rgb('+color.r.toFixed(0)+','+color.g.toFixed(0)+','+color.b.toFixed(0)+')';
node.style.backgroundColor = colorStr;
}
function render() {
var nodes = container.children;
for(i=0; i<pixels.length; i++) {
setPixelColor(nodes[i], pixels[i]);
}
}
// runtime state
var container = document.getElementById("strip");
var pixels = Array.map(container.children, function() {
return new Color(0,0,0);
});
var currentColor = new Color(0,0,0);
var currentPosition = 0;
var speed = 1000/7;
var startTime = Date.now();
var prevTime = startTime;
var lastFrame = startTime;
var animateFn = null;
// the animation-specific update function
function panHighlight(delta) {
var distance;
if (Date.now() - lastFrame >= speed) {
for(var i=0; i<pixels.length; i++) {
distance = 1+Math.abs(i - currentPosition);
//msg(distance);
pixels[i] = new Color(150,
255 - (150 * distance/pixels.length),
255);
}
currentPosition = (currentPosition+1) % (pixels.length);
lastFrame = Date.now();
}
}
// the animation loop
function startAnimation() {
function onFrame() {
if (!animateFn) {
return;
}
var now = Date.now();
animateFn(now - prevTime);
render();
prevTime = now;
window.requestAnimationFrame(onFrame);
}
window.requestAnimationFrame(onFrame);
}
function stopAnimation() {
animateFn = null;
}
// the init
animateFn = panHighlight;
startAnimation();
document.querySelector("button").onclick = stopAnimation;