Understanding Tween.js

Tween.js is a JavaScript tween library. Its entire purpose is to smoothly update numeric values of JavaScript objects over time. In general, it doesn't do anything unless you ask it to. Let's take a look at a basic page that uses Tween.js:

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<script src="Tween.js"></script>
<body>
<script>
var box = document.createElement('div');
box.style.setProperty('background-color', '#008800');
box.style.setProperty('width', '100px');
box.style.setProperty('height', '100px');
document.body.appendChild(box);

function animate(time) {
requestAnimationFrame(animate);
TWEEN.update(time);
}
requestAnimationFrame(animate);

var coords = { x: 0, y: 0 };
var tween = new TWEEN.Tween(coords)
.to({ x: 300, y: 200 }, 1000)
.onUpdate(function() {
box.style.setProperty('transform', 'translate(' + coords.x + 'px, ' + coords.y + 'px)');
})
.start();
</script>
</body>
</html>

I recommend pasting this into a new html file, putting Tween.js in the same directory, then opening the html file with a browser.

Let's step through the code:

var box = document.createElement('div');
box.style.setProperty('background-color', '#008800');
box.style.setProperty('width', '100px');
box.style.setProperty('height', '100px');
document.body.appendChild(box);

This just creates a green square div that we can animate.

function animate(time) {
requestAnimationFrame(animate);
TWEEN.update(time);
}
requestAnimationFrame(animate);

Tween.js doesn't do anything unless we call its update method. This code sets up an animation loop. The requestAnimationFrame function schedules a function to be called during the next "animation frame". In current browsers there are 60 animation frames per second at a regular interval, but in the future there may be 90 or more animation frames per second. The requestAnimationFrame method supplies your function with a single argument that represents the number of milliseconds that have elapsed since the page has loaded. This value needs to be passed to the update method so that it can calculate the progress of your tweens.

For performance reasons, it's ideal to only have one requestAnimationFrame loop in your code. Whenever possible, combine multiple animation loops into a single animation loop. Also note that we placed the animation loop code before the rest of the code, but we could also have placed it at the end.

var coords = { x: 0, y: 0 };

This is the object that will be animated. I usually call it the "tweened object". Tween.js will change the properties of this object over time once we tell it to.

var tween = new TWEEN.Tween(coords)

This creates a new tween using the TWEEN.Tween constructor. Every tween must have a tweened object passed into the constructor.

.to({ x: 300, y: 200 }, 1000)

The to method does two things: set the final values of the tween, and set the duration of the tween in milliseconds. Note that the duration value has units in milliseconds because TWEEN.update is called with values in units of milliseconds in the animation loop. Also note that we are using a syntax called "chaining syntax", where we call a bunch of methods in a chain. This is made possible because each function that acts on a tween instance changes the tween's internal state then returns the tween instance.

If you are using a newer version of Tween.js, then you can use the duration method instead of passing the tween duration as the second argument to the to method.

.easing(TWEEN.Easing.Quadratic.Out)

This line of code is optional. It adds easing to the tween so that it appears smoother. The variable TWEEN.Easing.Quadratic.Out is just a function that accepts a single value, representing the tween's progress in time, in the domain of 0 to 1. It outputs a single number representing the tween's progress through its parameters. You can create your own easing functions, but Tween.js comes with a variety of easing functions, which are defined at the bottom of Tween.js.

.onUpdate(function() {
box.style.setProperty('transform', 'translate(' + coords.x + 'px, ' + coords.y + 'px)');
})

Here we specify a callback function that will be called every time the tween updates. Tween.js does not do anything for you besides update the values on the tweened object. Therefore, in order to make the green box move, we need to map the values in the JavaScript object coords to values on the green box div. We can set the box's position using a CSS transform, which is more efficient than the alternative of using the top and left CSS properties, because it does not trigger a page reflow. Tween.js is very generic; You can use the onUpdate callback to update virtually anything, not just the 2D coordinates of divs.

Because coords is the tweened object, it can also be accessed as the first parameter passed to the callback, like so:

.onUpdate(function(object) {
box.style.setProperty('transform', 'translate(' + object.x + 'px, ' + object.y + 'px)');
})

Now we can start the tween.

.start();

Once a tween is started, its values may be updated whenever TWEEN.update is called in the animation loop. Whether the values will be updated depends on the start time and duration of the tween. When start is called without a parameter, the start time is the same instant as the start method was called. However, you can also pass in a timestamp to the start method, which will cause the tween to start once the value passed to TWEEN.update is greater than or equal to the start timestamp. You can also use the .delay(n) method to delay the tween by n time units past the normal starting time. The tween will end after its true start time plus the specified duration value. After that point Tween.js will no longer update the tweened object's values. When a tween ends, Tween.js calls the tween's onComplete callback. This way you can specify some code to run when a tween finishes, which is useful for starting other tweens, like so:

.onCompleted(function() {
tween2.start();
})

This should be everything you need to know to start using Tween.js. More documentation is available in the official README and User Guide.