Tween.js - Documentation

What is Tween.js?

Tween.js is a lightweight JavaScript library that provides an easy and efficient way to create smooth animations and transitions between different values over time. It’s particularly useful for creating visually appealing animations for user interface elements, game objects, or any other element requiring gradual changes in position, size, opacity, or other properties. Tween.js handles the complex calculations necessary to create smooth, interpolated animation curves, freeing you from the burden of manually managing animation timelines and easing functions.

Why use Tween.js?

Using Tween.js offers several advantages:

Setting up Tween.js in your project

The simplest way to include Tween.js in your project is via a CDN link. Add the following <script> tag to your HTML file within the <head> or just before the closing </body> tag:

<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/18.6.4/Tween.js"></script>

Alternatively, you can download the Tween.js library from its repository and include it locally.

Basic usage example.

This example demonstrates a simple animation that changes the x and y coordinates of an element over 1000 milliseconds (1 second):

// Select the element to animate
const element = document.getElementById('myElement');

// Create a new Tween
const tween = new TWEEN.Tween({ x: 0, y: 0 })
  .to({ x: 200, y: 100 }, 1000) // Animate to x: 200, y: 100 over 1000ms
  .onUpdate(function() {
    // Update the element's position based on the tween's current values
    element.style.left = this.x + 'px';
    element.style.top = this.y + 'px';
  })
  .start();


// This is crucial for animations to run!  Call this in your animation loop (e.g., `requestAnimationFrame`)
function animate() {
  requestAnimationFrame(animate);
  TWEEN.update();
}

animate();

Remember to have an element with the ID myElement in your HTML for this code to function correctly. For example:

<div id="myElement" style="position: absolute; width: 50px; height: 50px; background-color: blue;"></div>

This will create a blue square that animates smoothly to a new position. Remember that the element needs position: absolute or position: relative for the left and top styles to work correctly.

Core Concepts

Tweens and Updates

The fundamental unit of animation in Tween.js is the Tween. A Tween object represents a single animation, defining the target object, the properties to animate, the target values, the duration, and the easing function. Tweens don’t animate themselves; they need to be updated regularly to progress through their animation cycle.

This updating is typically done using TWEEN.update(), which is called within an animation loop, commonly using requestAnimationFrame. requestAnimationFrame ensures that the animation is synchronized with the browser’s repaint cycle, resulting in smoother animations. Each call to TWEEN.update() advances all active tweens by a small time step. If you don’t call TWEEN.update() regularly, your animations won’t play.

Easing Functions

Easing functions control the speed and rhythm of an animation over time. Tween.js offers a variety of pre-defined easing functions, such as linear, quadratic, cubic, and more. These functions determine how the animated property changes over the animation’s duration. For example, a linear easing function results in a constant animation speed, while a easeInOutQuad function accelerates at the beginning, slows down towards the end and creates a more natural-looking animation.

You can specify the easing function when creating a Tween or later in the chain. Refer to the Tween.js documentation for a complete list of available easing functions. Custom easing functions can also be implemented.

Chaining Tweens

Tween.js allows you to chain multiple tweens together to create complex sequences of animations. This is achieved using methods like .chain(). By chaining tweens, you can create smooth transitions between different animation stages without manual intervention to start subsequent animations. When one tween completes, the next one in the chain automatically starts.

Tween Properties

Several key properties control the behavior of a Tween object:

By manipulating these properties, you can fine-tune your animations to achieve the desired visual effects. Understanding these properties is crucial for creating sophisticated and engaging animations with Tween.js.

Creating and Managing Tweens

Creating a Tween

To create a new Tween, you use the new TWEEN.Tween(object) constructor, where object is the object whose properties you want to animate. This object can be a simple JavaScript object literal or any other JavaScript object. The initial values of the properties to be animated are taken from this object.

// Create a tween for a simple object
const myTween = new TWEEN.Tween({ x: 0, y: 0 });

// Create a tween for an existing object
const myElement = document.getElementById('myElement');
const elementTween = new TWEEN.Tween(myElement); // Animating properties directly on the element

Setting Tween Properties (to, duration, easing, etc.)

After creating a Tween, you use methods to set its properties, including the target values (to), the animation duration, the easing function, and callbacks.

myTween
  .to({ x: 100, y: 200 }, 1000) // Target values and duration (milliseconds)
  .easing(TWEEN.Easing.Quadratic.InOut) // Easing function
  .onUpdate(function() {
    console.log('x:', this.x, 'y:', this.y); // Access tween properties within the callback
  });

elementTween.to({opacity: 0},500).easing(TWEEN.Easing.Cubic.Out)

Starting and Stopping Tweens

Tweens are started using the .start() method. To stop a running Tween, use the .stop() method.

myTween.start();
// ... later ...
myTween.stop();

Pausing and Resuming Tweens

You can pause and resume a Tween using the .pause() and .resume() methods. This allows for temporarily halting and restarting an animation without losing its current state.

myTween.pause();
// ... later ...
myTween.resume();

Chaining Multiple Tweens

Chaining allows you to create sequences of animations. Use the .chain() method to specify the next Tween to run after the current one completes. You can chain multiple tweens together to create complex animation sequences.

const tween1 = new TWEEN.Tween({ x: 0 }).to({ x: 100 }, 500);
const tween2 = new TWEEN.Tween({ x: 100 }).to({ x: 200 }, 500);
const tween3 = new TWEEN.Tween({x:200}).to({x:0}, 500);

tween1.chain(tween2).chain(tween3);
tween1.start();

Tween Events (onStart, onComplete, etc.)

Callbacks are attached to specific events in a Tween’s lifecycle using methods like .onStart(), .onUpdate(), and .onComplete(). These functions are executed at the respective stages of the animation.

myTween
  .onStart(function() { console.log('Tween started!'); })
  .onUpdate(function() { /* ... */ })
  .onComplete(function() { console.log('Tween completed!'); });

Managing Multiple Tweens

To manage multiple tweens effectively, use TWEEN.getAll() to get an array of all active tweens, and TWEEN.removeAll() to remove all tweens. Individual tweens can be removed using tween.stop(). Remember to call TWEEN.update() in your animation loop (e.g., using requestAnimationFrame) to update all active tweens. This ensures all your animations run smoothly and concurrently.

// Get all active tweens
const allTweens = TWEEN.getAll();

// Remove all active tweens
TWEEN.removeAll();

Remember that TWEEN.update() must be called within an animation loop (usually using requestAnimationFrame) to update all active tweens and see the animations.

Easing Functions in Detail

Tween.js provides a wide variety of easing functions to control the speed and rhythm of your animations. These functions are categorized by their mathematical basis and produce different animation curves. Each easing function is available in TWEEN.Easing as an object with In, Out, and InOut variations. In accelerates from the start, Out decelerates towards the end, and InOut combines both acceleration and deceleration. They all accept a normalized time value (between 0 and 1) as input and return a normalized output value (also between 0 and 1).

Linear Easing

Provides a constant animation speed throughout its duration. No acceleration or deceleration.

// Example using linear easing
myTween.easing(TWEEN.Easing.Linear.None);

Quadratic Easing

Uses quadratic equations to create acceleration or deceleration effects.

// Quadratic ease-in
myTween.easing(TWEEN.Easing.Quadratic.In);
// Quadratic ease-out
myTween.easing(TWEEN.Easing.Quadratic.Out);
// Quadratic ease-in-out
myTween.easing(TWEEN.Easing.Quadratic.InOut);

Cubic Easing

Uses cubic equations, providing smoother acceleration and deceleration than quadratic easing.

// Cubic ease-in
myTween.easing(TWEEN.Easing.Cubic.In);
// Cubic ease-out
myTween.easing(TWEEN.Easing.Cubic.Out);
// Cubic ease-in-out
myTween.easing(TWEEN.Easing.Cubic.InOut);

Quartic Easing

Uses quartic (fourth-power) equations for even smoother transitions.

// Quartic ease-in
myTween.easing(TWEEN.Easing.Quartic.In);
// Quartic ease-out
myTween.easing(TWEEN.Easing.Quartic.Out);
// Quartic ease-in-out
myTween.easing(TWEEN.Easing.Quartic.InOut);

Quintic Easing

Uses quintic (fifth-power) equations, offering the smoothest transitions among the power-based easings.

// Quintic ease-in
myTween.easing(TWEEN.Easing.Quintic.In);
// Quintic ease-out
myTween.easing(TWEEN.Easing.Quintic.Out);
// Quintic ease-in-out
myTween.easing(TWEEN.Easing.Quintic.InOut);

Sinusoidal Easing

Uses sine functions to create a smooth, wave-like animation.

// Sinusoidal ease-in
myTween.easing(TWEEN.Easing.Sinusoidal.In);
// Sinusoidal ease-out
myTween.easing(TWEEN.Easing.Sinusoidal.Out);
// Sinusoidal ease-in-out
myTween.easing(TWEEN.Easing.Sinusoidal.InOut);

Exponential Easing

Uses exponential functions, resulting in rapid acceleration or deceleration.

// Exponential ease-in
myTween.easing(TWEEN.Easing.Exponential.In);
// Exponential ease-out
myTween.easing(TWEEN.Easing.Exponential.Out);
// Exponential ease-in-out
myTween.easing(TWEEN.Easing.Exponential.InOut);

Circular Easing

Uses circular functions, creating a smooth, rounded animation.

// Circular ease-in
myTween.easing(TWEEN.Easing.Circular.In);
// Circular ease-out
myTween.easing(TWEEN.Easing.Circular.Out);
// Circular ease-in-out
myTween.easing(TWEEN.Easing.Circular.InOut);

Elastic Easing

Simulates an elastic effect, with overshooting and oscillations. It takes an amplitude and period parameter to customize the effect.

// Elastic ease-in
myTween.easing(TWEEN.Easing.Elastic.In);
// Elastic ease-out
myTween.easing(TWEEN.Easing.Elastic.Out);
// Elastic ease-in-out
myTween.easing(TWEEN.Easing.Elastic.InOut);

//Example with custom parameters.
myTween.easing(TWEEN.Easing.Elastic.InOut.get(1, .3)); // amplitude = 1, period = .3

Back Easing

Creates an animation that overshoots its target before settling. Similar to elastic, but without oscillations.

// Back ease-in
myTween.easing(TWEEN.Easing.Back.In);
// Back ease-out
myTween.easing(TWEEN.Easing.Back.Out);
// Back ease-in-out
myTween.easing(TWEEN.Easing.Back.InOut);

Bounce Easing

Simulates a bouncing effect, with decreasing amplitude.

// Bounce ease-in
myTween.easing(TWEEN.Easing.Bounce.In);
// Bounce ease-out
myTween.easing(TWEEN.Easing.Bounce.Out);
// Bounce ease-in-out
myTween.easing(TWEEN.Easing.Bounce.InOut);

Custom Easing Functions

You can create your own custom easing functions by defining a function that takes a single normalized time argument (between 0 and 1) and returns a normalized output value (also between 0 and 1). This function can then be used directly with the easing() method.

// Example custom easing function
function myCustomEasing(k) {
  return k * k; //Simple quadratic ease-in
}

myTween.easing(myCustomEasing);

Remember to experiment with different easing functions to find the best fit for your animation needs. The visual difference between many of these can be subtle, but choosing the right one significantly impacts the feel of your animations.

Advanced Techniques

Using Tween.js with different animation libraries

Tween.js can coexist with other animation libraries. It doesn’t directly integrate with them, but you can use Tween.js to manage specific animations while letting other libraries handle other aspects of your application’s visual effects. The key is to ensure that your animation loops and update mechanisms don’t conflict. If you’re using another library that provides its own animation loop (like a game engine’s update function), you should integrate TWEEN.update() into that loop instead of creating a separate requestAnimationFrame loop.

Creating complex animations with Tween.js

Complex animations can be achieved by chaining multiple tweens, using different easing functions, and incorporating callbacks. For highly intricate animations, consider breaking down the animation into smaller, manageable tweens that are chained together sequentially or in parallel using techniques like creating multiple tweens that start simultaneously or using branching logic within onUpdate or onComplete callbacks to control the flow.

Optimizing Tween.js performance

For optimal performance, particularly with many simultaneous animations:

Debugging Tween.js animations

Debugging issues with Tween.js animations involves standard JavaScript debugging techniques:

Integrating with other JavaScript frameworks (React, Angular, Vue)

Integrating Tween.js with popular JavaScript frameworks generally involves:

In all cases, remember to handle the TWEEN.update() call within your framework’s rendering loop or lifecycle methods (e.g., requestAnimationFrame in React or Angular, using Vue’s lifecycle hooks).

Using Plugins

Tween.js itself doesn’t have a built-in plugin architecture. However, you can extend its functionality by creating custom functions or classes that build on top of the core Tween.js API. These custom additions could be considered “plugins” in the sense that they extend Tween.js’s capabilities. For example, you could create a plugin that adds support for more complex easing functions or animation types. This would involve creating a new module with your added functions that operate on the core Tween.js classes.

API Reference

This section provides a detailed overview of the Tween.js API. Note that the specific methods and properties available might vary slightly depending on the version of Tween.js you are using. Always consult the latest documentation for the most up-to-date information.

Tween Class Methods

The TWEEN.Tween class is the core of Tween.js. It represents a single animation. Here are some of its key methods:

Easing Function Reference

Tween.js provides a comprehensive set of easing functions categorized under TWEEN.Easing. Each category (e.g., Quadratic, Cubic, Elastic) has In, Out, and InOut variations:

Utility Functions

Tween.js provides several utility functions:

This API reference provides a concise summary. For complete details and examples, refer to the full Tween.js documentation and source code. Remember to check the version you are using, as minor variations in methods or parameters might exist across versions.

Examples

This section provides examples demonstrating various uses of Tween.js, ranging from simple animations to more complex scenarios. Remember to include the Tween.js library in your HTML file (via CDN or local file) before running these examples.

Simple Animations

This example animates the left and opacity properties of a div element:

<div id="myElement" style="position: absolute; left: 0px; top: 0px; width: 50px; height: 50px; background-color: blue;"></div>
<script>
  const element = document.getElementById('myElement');
  const tween = new TWEEN.Tween({ left: 0, opacity: 1 })
    .to({ left: 200, opacity: 0 }, 1000)
    .onUpdate(function() {
      element.style.left = this.left + 'px';
      element.style.opacity = this.opacity;
    })
    .start();

  function animate() {
    requestAnimationFrame(animate);
    TWEEN.update();
  }
  animate();
</script>

This moves the blue square 200 pixels to the right and fades it out over one second.

Complex Animations

This example chains multiple tweens together to create a more complex animation sequence:

const element = document.getElementById('myElement');
let x = 0;
const tween1 = new TWEEN.Tween({ x: x }).to({ x: 200 }, 1000).easing(TWEEN.Easing.Quadratic.InOut);
const tween2 = new TWEEN.Tween({ x: 200 }).to({ x: 0 }, 1000).easing(TWEEN.Easing.Cubic.InOut);

tween1.onUpdate(function() { element.style.left = this.x + 'px'; })
      .chain(tween2);

tween2.onUpdate(function() { element.style.left = this.x + 'px'; });


tween1.start();

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

This animates an element back and forth using different easing functions. Remember you need the myElement div from the previous example.

Animations with Easing Functions

This example demonstrates the use of different easing functions:

const element = document.getElementById('myElement');
const tweenLinear = new TWEEN.Tween({ x: 0 }).to({ x: 200 }, 1000).easing(TWEEN.Easing.Linear.None);
const tweenBounce = new TWEEN.Tween({ x: 0 }).to({ x: 200 }, 1000).easing(TWEEN.Easing.Bounce.Out);


tweenLinear.onUpdate(function() { element.style.left = this.x + 'px'; }).start();

tweenBounce.onUpdate(function() {element.style.left = this.x + 'px';}).start();


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

This creates two tweens animating the myElement to show the difference between linear and bounce easing. Note this example requires some adjustment to avoid conflicting animations; you might want to make a copy of myElement or chain these tweens sequentially rather than starting them concurrently.

Practical Application Examples

These examples provide a starting point. The possibilities for creating sophisticated animations with Tween.js are vast. Experiment with different combinations of tweens, easing functions, and callbacks to achieve the desired results. Remember to adjust the selectors and styles to match your specific HTML structure.

Troubleshooting

This section addresses common issues encountered when using Tween.js and provides strategies for debugging.

Common Errors and Solutions

Debugging Tips

By systematically using these debugging techniques and checking for the common errors listed above, you should be able to resolve most issues when working with Tween.js. Remember that a well-structured codebase with clear separation of concerns makes debugging much easier.