Fork me on GitHub

snabbt.js

Minimalistic animation library in javascript

Fast

60 FPS, even on mobile

Light

~5kb minified and gzipped

Simple

Write less, animate more

npm install snabbt.js

bower install snabbt.js

Download

Introduction

snabbt.js is a minimalistic javascript animation library. It focuses on moving things around. It will translate, rotate, scale, skew and resize your elements. By including matrix multiplication operations, transforms can be combined in any way you want. The end result is then set via CSS3 transform matrices.

snabbt.js is built to be fast. It will only animate things that modern browsers can animate cheaply: transforms and opacity. The goal is to make a library that will let the user make smooth animations without needing to know too much about browser rendering.

Note: For convenience, width and height are animatable too, but beware since they may cause page reflows and slow down your animations.

Limitations

Demos

Check out some of the demos to see the capabilities of snabbt.js:

Usage

Animations are started with the snabbt-function call. The function takes an element as first parameter(or list there of) and a configutation-object as second. Example:

snabbt(element, {
  position: [100, 0, 0],
  rotation: [Math.PI, 0, 0],
  easing: 'ease'
});

Chaining

Animation can be chained by using `snabbt()` on the returned animation object. All fromXxx properties will be set to the end state of the previous animation.

snabbt(element, {
  position: [100, 0, 0],
  easing: 'ease'
}).snabbt({
  fromRotation: [0, 0, -2*Math.PI],
  position: [0, 0, 0],
  easing: 'spring',
  springConstant: 0.2,
  springDeceleration: 0.90,
  springMass: 10,
});

Make it stop

Animation can be stopped at any time by replacing the animation configuration with the string literal 'stop':

snabbt(element, 'stop');

If a new animation is started with the same element it will start from the stopped position unless the 'from'-properties are used.

Easing

snabbt.js includes four easing functions: linear, ease, easeIn and easeOut. You can also use your own easing functions or use the physics based spring easing

linear(default)
ease
easeIn
easeOut

Custom easing function

Instead of easing name, pass in a function that takes one parameter:

snabbt(element, {
  position: [200, 0, 0],
  easing: function(value) {
    return value + 0.3 * Math.sin(2*Math.PI * value);
  }
}).snabbt({
  position: [0, 0, 0],
  easing: 'easeOut'
});

Spring easing

When using spring easing, the duration parameter is not in effect. Instead the animation will progress until equilibrium is reached. When easing is set to spring there are three additional parameters that can be set on the animation configuration:

Example:

snabbt(element, {
  position: [100, 0, 0],
  rotation: [0, 0, 2*Math.PI],
  easing: 'spring',
  springConstant: 0.3,
  springDeceleration: 0.8,
}).snabbt({
  position: [0, 0, 0],
  easing: 'spring',
  springConstant: 0.3,
  springDeceleration: 0.8,
});

Advanced concepts

This section describes some of the more advanced usages.

Sequence

Chaining is convenient when animating a single element or group of elements in multiple steps. However, if you want to trigger animations on a different set of element once one animation is completed you often end up with a lot of callbacks. This is where sequencing comes into play. snabbt.sequence is a function call that allows you to specify an array of animations that should run in sequence.

snabbt.sequence([
    [elementTwo, {
      position: [100, 0, 0],
    }],
    [elementOne, {
      position: [100, 0, 0],
    }],
    [elementOne, {
      position: [0, 0, 0],
    }],
    [elementTwo, {
      position: [0, 0, 0],
    }],
  ]
);

Value feeding

The animation object is very simple to work with but has it limitations. Sometimes you want to do the transforms in another order. This is where value feeding comes handy. The valueFeeder parameter expects a function that takes two parameters, one which will progress from 0 to 1 and an identity matrix that you can modify. The function will be called every frame and should return a matrix(see Matrix API) representing the current transform.

snabbt(element, {
  valueFeeder: function(i, matrix) {
    var x = Math.sin(i*Math.PI);
    return matrix.rotateZ(Math.sin(6*i*Math.PI)).translate(x*200, 0, 0);
  },
  duration: 1000
});

Transform origin

By default, rotations are applied around the center of the element. By using transformOrigin rotations can be performed around abritary positions.

snabbt(element, {
  rotation: [0, 2*Math.PI, 0],
  transformOrigin: [element.clientWidth/2, 0, 0]
});

Manual mode

By using manual mode, animations can be fed by user input instead of just being time-based. Define your animations as you normally would but set the manual-property to true. Instead of returning a chainer object, an animation control object is returned. The control object has the following methods:

Here's silly an example of what this could be used for(powered by the great Hammer.js):

Peek-a-boo!
Drag to flip!
Flip me back!

Attention animations

snabbt.js has support for attention animations. This can be useful in form validations when you want to draw attention to a form element for example. Attention animation use spring easings.

snabbt(element, 'attention', {
  rotation: [0, 0, Math.PI/2],
  springConstant: 1.9,
  springDeceleration: 0.9,
});
snabbt(element, 'attention', {
  position: [50, 0, 0],
  springConstant: 2.4,
  springDeceleration: 0.9,
});

Multi-element animations

Several elements can be animated with a single snabbt-call by passing a list of elements instead of just one. If you want to set different values for each of the elements you can pass initilization functions for the properties instead of actual values.

The initialization functions take two parameters, the current index of the element in the collection and the total number of elements. The functions must return a value in the same format as usual, e.g. a position function initializer must return an array of three coordinates.

This makes it possible to create complex animations with very little code:

snabbt(document.querySelectorAll('.multi-example-box'), {
  fromRotation: [0, 0, 0],
  rotation: function(i, total) {
    return [0, 0, (i/(total - 1)) * (Math.PI/2)];
  },
  delay: function(i) {
    return i * 50;
  },
  easing: 'spring',
}).snabbt({
  rotation: [0, 0, 0],
  delay: function(i, total) {
    return (total - i - 1) * 50;
  },
  easing: 'ease',
});

To see a more elaborate example of this, check out the sticks demo

Module loaders

snabbt.js is wrapped in a UMD boilerplate which means it will work with both RequireJS and browserify.

CommonJS:
var snabbt = require('snabbt.js');

snabbt(element, {
  position: [200, 0, 0]
});
AMD:
require(['snabbt.js'], function(snabbt) {
  snabbt(element, {
    rotation: [2*Math.PI, 0, 0]
  });
});

jQuery

snabbt.js works with or without jQuery. If jQuery is detected snabbt will be loaded as a jQuery-plugin. When using snabbt with jQuery, the first parameter is the animation configuration:

With jQuery
$element.snabbt({
  position: [150, 0, 0],
  rotation: [0, 0, Math.PI],
});
Without jQuery
snabbt(element, {
  position: [150, 0, 0],
  rotation: [0, 0, Math.PI],
});

Matrix API

Matrix operations are performed using the Matrix class. The class has the following methods:

All operations are chainable to make writing matrix multiplications concise, e.g.:

matrix.translate(100, 0, 0).rotateX(Math.PI);

Freeform transforms

The matrix operations can be used outside of snabbt's animation engine. This could be useful for interactive animations.

var matrix = snabbt.createMatrix();
matrix.translate(100, 0, 0);
snabbt.setElementTransform(element, matrix);

Animation configuration

The following parameters can be used in the configuration object:

Parameter Type Default Description
position Array(3) [0, 0, 0] Pixel offsets in each x-, y- and z-direction
rotation Array(3) [0, 0, 0] Rotation in radians in x-, y- and z-direction
scale Array(2) [1, 1] Scale in x- and y-direction
rotationPost Array(3) [0, 0, 0] Rotation applied after position and rotation
width Scalar Unchanged Element width in pixels(fromWidth mandatory if used)
height Scalar Unchanged Element height in pixels(fromHeight mandatory if used)
opacity Scalar 1 Element opacity(0 - 1)(fromOpacity mandatory if used)
duration Scalar 500 Animation duration in milliseconds
delay Scalar 0 Delay before the animation is started in milliseconds
start(index, total) function undefined Function to be called just before the animation starts. If multiple elements are animated, this function will be called once for every element with two parameters, index of current element and total elements in the animated collection.
update(i, index, total) function undefined Function to be called on every progress step of the animation. The first parameter is a value between 0 and 1 and indicates the current progress of the animation. If multiple elements are animated, this function will be called for every progress step for every element in the collection. index indicates the current element and total corresponds to the total number of elements in the colletion.
complete(index, total) function undefined Function to be called when animation is completed. If multiple elements are animated, this function will be called once for every element with two parameters, index of current element and total elements in the animated collection. this will be bound the current element
allDone function undefined Will be called once independent of how many elements animated

A 'from'-property can be set on most properties. Note that 'from' has precedance over the previous end state.

Parameter Type Default
fromPosition Array(3) [0, 0, 0] or previous end state
fromRotation Array(3) [0, 0, 0] or previous end state
fromScale Array(2) [1, 1] or previous end state
fromRotationPost Array(3) [0, 0, 0] or previous end state
fromWidth Scalar Previous end state width
fromHeight Scalar Previous end state height
fromOpacity Scalar Previous end state opacity