Animation Programming


Animations are an essential part of many modern user interfaces. They are often defined programmatically, which allows for parametrization and reuse. Two programming paradigms to define animations are common: Procedural animation programming allows the developer to make explicit updates to object properties at each frame, allowing maximum control over behavior. Declarative animation programming allows the developer to specify keyframes, i.e., the value of an object’s property at a given point in time. Frames between two keyframes are interpolated by the animation library.

The following example code shows the implementation of a ball moving up and down in both paradigms:

Procedural

function render(time) { 

var loc = time % 300;
if (loc > 150) {
loc = 150-(loc % 150);
}
ball.top = loc;
}
window.requestAnimationFrame(render);

Declarative

var actor = animator.addActor({ 

context: ball
});

actor.keyframe(0, {top: 0});
actor.keyframe(150, {top: 150});
actor.keyframe(300, {top: 0});

animator.play();


We compared both animation paradigms by inviting developers to a lab study in which they spent two hours to implement as many of the five animations shown above twice, once using each paradigm. Both APIs are similarly powerful. We show that a higher level of abstraction allows developers to solve certain tasks faster and with less testing (see chart below). However, we also find that a higher level of abstraction is prone to hiding crucial implementation details. In this case, abstraction can make comprehension harder instead of easier. Also, the success of the abstraction in APIs is closely tailored to the task at hand, i.e., if the abstraction does not match the task its benefits diminish.

Numbers on bars show how many participants managed to start the task before time ran out.