Animations with requestAnimationFrame
Recently I deceided to explore requestAnimationFrame as a way to peer behind the jQuery.animate veil. While you should absolutely use jQuery.animate (or similar) when working on a "real" project, the results were pretty interesting:
function animate(el, properties, duration, done) {
function map(obj, transform){
var result = {};
Object.keys(obj).forEach(function (key) {
result[key] = transform(key, obj[key]);
});
return result;
}
function accessor(property) {
return {
get: function (el) {
var value = styles[property]
if (value === 'auto') {
return 0;
}
return parseInt(value, 10);
},
set: function (el, value) {
el.style[property] = value + "px";
}
};
}
var start,
styles = getComputedStyle(el),
startingValues = map(properties, function(key, value) {
return accessor(key).get(el);
});
requestAnimationFrame(function step(timestamp) {
done = done || function () {};
start = start || timestamp;
var elapsed = timestamp - start;
Object.keys(properties).forEach(function (property) {
var goal = properties[property],
startingValue = startingValues[property],
delta = goal - startingValue,
progress = elapsed / duration,
bound = (delta > 0 ? Math.min : Math.max),
value = bound(delta * progress + startingValue, goal);
accessor(property).set(el, value);
});
if (elapsed < duration) {
requestAnimationFrame(step);
} else {
done();
}
});
}
Interestingly enough, the actual animation code is almost dwarfed by the code providing the API and fiddling with css properties to make sure they're in the right format.
Enough chit-chat, where's the bouncing ball?
I'm so glad you asked, I've even implemented the obligatory bouncing ball. Go take a look!