When it comes to raw animation speed FAT outperforms every single web animation library out there and also provides flexible animation capabilities like scenes, sequences, controlling and easing.
Installation Guide • API Reference • Custom Builds • Benchmark Ranking
Get Latest (Stable Release):
Build | File | CDN |
fat.min.js | Download | https://cdn.jsdelivr.net/gh/nextapps-de/fat@master/fat.min.js |
fat.light.js | Download | https://cdn.jsdelivr.net/gh/nextapps-de/fat@master/fat.light.js |
fat.compact.js | Download | https://cdn.jsdelivr.net/gh/nextapps-de/fat@master/fat.compact.js |
fat.custom.js | Custom Build |
All Features:
Feature | fat.js / fat.min.js | fat.compact.js | fat.light.js |
Scenes (Groups) | x | x | x |
Easing Collection (Custom Bezier) | x | x | - |
Controlling | x | - | - |
Sequences | x | - | - |
Keyframes | x | - | - |
Presets (Effects) | x | - | - |
Transforms (2D/3D) | x | x | - |
Filter | x | - | - |
Colors | x | x | - |
Custom Properties/Renderer | x | x | x |
Relative Values | x | x | - |
Scroll | x | x | - |
Concurrency (Strict Mode) | x | - | - |
Render Engines | JS, CSS3, WAAPI | JS | JS |
File Size (gzip) | 6.1 kb | 4.4 kb | 1.8 kb |
It is also very simple to make a Custom Build
Library Comparison: Benchmark "Bouncing Balls"
"Animate" (2000 Bouncing Balls)
Rank | Library Name | Library Version | Library Size | Memory Heap * | Memory Allocation ** | Updates per second | Frames per second |
1 | FAT | 0.6.1 | 1.8 kb | 0.85 Mb | 0.15 Mb | 101075 | 51.2 |
2 | GSAP | 2.0.2 | 25.8 kb | 28.32 Mb | 8.1 Mb | 87249 | 43.1 |
3 | TweenJS | 1.0.2 | 8.3 kb | 3.16 Mb | 3.1 Mb | 69647 | 34.4 |
4 | HTML5 (WAAPI) | - | - | 0.91 Mb | 0.75 Mb | - | 32.2 |
5 | TinyAnimate | 0.4.0 | 1.5 kb | 1.93 Mb | 1.98 Mb | 28801 | 29 |
6 | MooTools | 1.6.0 | 31.2 kb | 3.14 Mb | 3.42 Mb | 26919 | 25.2 |
7 | CSS3 (Transition) | - | - | 0 Mb | 0 Mb | - | 22.3 |
8 | Velocity | 2.0.5 | 16.6 kb | 8.33 Mb | 7.98 Mb | 16820 | 6.3 |
9 | AnimeJS | 2.2.0 | 5.9 kb | 7.14 Mb | 8.2 Mb | 9877 | 2.8 |
10 | Anim.js | - | 1.9 kb | 7.08 Mb | 9.49 Mb | 6994 | 2.8 |
11 | Dojo | 1.14.2 | 53.0 kb | 9.1 Mb | 6.5 Mb | 10607 | 2.3 |
12 | Morpheus | 0.7.2 | 2.7 kb | 4 Mb | 2.97 Mb | 8543 | 2.1 |
13 | jQuery | 3.3.1 | 30.0 kb | 25.14 Mb | 25.16 Mb | 14413 | 1.3 |
14 | bajs | 1.0 | 1.2 kb | 1.25 Mb | 0.91 Mb | - | 0.8 |
15 | JustAnimate | 2.5.1 | 7.3 kb | 109.5 Mb | 61.18 Mb | 5087 | 0.6 |
16 | YUI | 3.18.1 | 24.4 kb | 159.59 Mb | 88.35 Mb | 2182 | 0.5 |
17 | Zepto | 1.2.0 | 11.0 kb | 40.14 Mb | 18.49 Mb | - | 0.3 |
"Transforms" (2000 Bouncing Balls)
Rank | Library Name | Library Version | Updates per second | Frames per second |
1 | FAT | 0.6.1 | 90091 | 46.1 |
2 | TweenJS | 1.0.2 | 67931 | 33 |
3 | GSAP | 2.0.2 | 50337 | 26 |
4 | AnimeJS | 2.2.0 | 41040 | 21.6 |
5 | HTML5 (WAAPI) | - | - | 16 |
6 | CSS3 (Transition) | - | - | 15.5 |
7 | Zepto | 1.2.0 | - | 12.4 |
8 | Morpheus | 0.7.2 | 6665 | 3.3 |
9 | bajs | 1.0 | - | 1 |
10 | JustAnimate | 2.5.1 | 1218 | 0.3 |
11 | jQuery | 3.3.1 | 618 | 0.01 |
"Colors" (2000 Flashing Balls)
Rank | Library Name | Library Version | Updates per second | Frames per second |
1 | FAT | 0.6.1 | 111951 | 56.5 |
2 | GSAP | 2.0.2 | 89665 | 42.65 |
3 | TweenJS | 1.0.2 | 89499 | 42 |
4 | Velocity | 2.0.5 | 59617 | 31.25 |
5 | HTML5 (WAAPI) | - | - | 26.5 |
6 | Anim.js | - | - | 23 |
7 | CSS3 (Transition) | - | - | 20.6 |
8 | YUI | 3.18.1 | 84287 | 14.7 |
9 | MooTools | 1.6.0 | 8123 | 13.3 |
10 | Dojo | 1.14.2 | 33004 | 11.1 |
11 | AnimeJS | 2.2.0 | 12483 | 6.3 |
12 | jQuery | 3.3.1 | 14005 | 4 |
13 | Morpheus | 0.7.2 | 3902 | 3.2 |
14 | Zepto | 1.2.0 | - | 2 |
15 | JustAnimate | 2.5.1 | 4283 | 1 |
16 | bajs | 1.0 | - | 0.7 |
Browser: Chrome (Desktop), Test Duration: 30 sec (median value)
* Memory Heap: The size of memory the animations requires to execute
** Memory Allocation: The amount of memory which was allocated during animation runtime
<html>
<head>
<script src="fat.min.js"></script>
</head>
...
Note: Use fat.min.js for production and fat.js for development.
Use latest stable release from CDN:
<script src="https://cdn.jsdelivr.net/gh/nextapps-de/fat@master/fat.min.js"></script>
Use a specific version from CDN:
<script src="https://cdn.jsdelivr.net/gh/nextapps-de/fat@0.3.0/fat.min.js"></script>
Common JS
In your code include as follows:
var Fat = require("Fat");
AMD
var Fat = require("./fat.min.js");
Global methods / Scene methods:
- Fat.animate(selector[] | elements[], styles[]{}, options{})
- Fat.transform(selector[] | elements[], styles[]{}, options{})
- Fat.filter(selector[] | elements[], styles[]{}, options{})
- Fat.transition(selector[] | elements[], styles[]{}, options{})
- Fat.native(selector[] | elements[], styles[]{}, options{})
- Fat.update(selector[] | elements[], styles[]{}, options{})
- Fat.init()
- Fat.destroy()
Controller methods:
- Scene.pause(toggle)
- Scene.reverse(toggle)
- Scene.loop(int)
- Scene.seek(float)
- Scene.speed(float)
- Scene.start(toggle)
- Scene.reset()
- Scene.finish(boolean)
Option | Type | Default | Description |
duration | Number | 400 | Duration of the animation (ms). |
ease | String | Function | "linear" | Choose a pre-defined easing method or pass a custom easing function. |
delay | Number | 0 | Delay of the animation (ms). |
callback | Function | null | Callback function to be called when the animation is finished. |
step | Function(progress, value) | null | Step function to be called on each tick (progress: the current state of progress between 0 and 1, value: the current value including the unit, just important when using custom properties). |
loop | Number | 0 | Loop count of sequences or keyframes. Set to -1 for inifinite loops. |
init | Boolean | false | Forces getting computed styles during next animation loop. Just important when styles changes within the animation callback right before starting a new animation on the same style property (animation loop). |
force | Boolean | false | Forces style changes (equal to css keyword "!important"). |
strict | Boolean | false | Do not override and keep different animations acts on same object's style properties. |
engine | String | "js" | Choose one of 3 render engines: "js", "css", "native". |
Fat.animate(selector[] | elements[], styles[]{}, options{})
Fat.animate("#mydiv", { left: "100px" },{ /* options */ });
Fat.animate("#mydiv", {
left: "100px",
top: "100px"
},{
delay: 1000,
duration: 2000,
ease: "easeInOut",
callback: function(){
// done
console.log(this.style.left); // "this" refers to #mydiv
}
});
See all available options above
Pass in custom options for each style property:
Fat.animate("#mydiv", {
left: {
from: 0,
to: 100,
unit: "%",
duration: 2000,
ease: "linear"
},
top: {
from: 0,
to: "100%",
duration: 2000,
ease: "quadIn",
delay: 2000
}
});
Fat.animate("#mydiv", {
left: "+=100px",
top: "*=2"
});
Fat.animate("#mydiv", {
left: "-=100px",
top: "/=2"
});
Callback shorthand:
Fat.animate("#mydiv", { top: "100px" }, function(){
// callback
});
Fat.animate("#mydiv", {
translateX: "100px",
translateY: "100px"
});
same as:
Fat.transform("#mydiv", ...
same as (has lower performance):
Fat.animate("#mydiv", {
"transform": "translate(100px, 100px)"
});
Fat.animate("#mydiv", {
color: "#f00",
backgroundColor: "rgba(0, 255, 0, 1)",
borderColor: "hsla(0, 100%, 100%, 1)"
});
Animate color channels directly (also improves performance):
Fat.animate("#mydiv", {
colorR: 0,
colorG: 0,
colorB: 0,
colorA: 0,
backgroundColorA: "100%",
borderColorB: 255
});
Fat.animate("#mydiv", {
brightness: 0.5,
contrast: 0.5,
hue: "180deg"
});
You can use the shorthand
hue
ashue-rotate
same as:
Fat.filter("#mydiv", ...
same as (has lower performance):
Fat.animate("#mydiv", {
"filter": "brightness(0.5) contrast(0.5) hue(180deg)"
});
- linear
- easeIn, easeOut, easeInOut (refers to: quadIn, quadOut, quadInOut)
- cubicIn, cubicOut, cubicInOut
- quartIn, quartOut, quartInOut
- quintIn, quintOut, quintInOut
- sineIn, sineOut, sineInOut
- expoIn, expoOut, expoInOut
- circIn, circOut, circInOut
- backIn, backOut, backInOut
- snap
Static (Pre-Cached) vs. Dynamic Easing
There are two ways to define easing functions. When your easing is a static curve (like easeIn, backInOut, elastic, etc.) you should define the easing via Fat.ease["myEasing"] = fn()
and simply pass the name as string within the Fat.animate
options. This will prefetch all the calculations, so you are free to use really heavy easing definitions without any performance drawbacks.
When you want to use dynamic easing, which depends on runtime calculations, you should pass the easing function directly to the Fat.animate
options. In this case the easing calculation will not prefetch. This allows you to control easing programmatically and adding logic during runtime.
Define custom static easing function (1-parameter style):
Fat.ease["linear"] = function(x){
return x;
};
x: current progress (0.0 - 1.0)
Define custom static easing function (4-parameter style):
Fat.ease["linear"] = function(t, b, c, d){
return b + (c - b) * (t / d);
};
t: current time, b: from value, c: to value, d: duration
Apply the custom static easing:
Fat.animate("#mydiv", { left: "100px" },{ ease: "linear" });
Use cubic bezier:
Fat.animate("#mydiv", { left: "100px" },{ ease: "cubic(0, 1, 0, 1)" });
Shorthand array notation for a bezier is recommended:
... ,{ ease: [0, 1, 0, 1] });
Define custom dynamic easing function (1-parameter style):
Fat.animate("#mydiv", { left: "100px" },{ ease: function(x){
// doing some crazy calculations depends on runtime
return x;
}});
Define custom dynamic easing function (4-parameter style):
Fat.animate("#mydiv", { left: "100px" },{ ease: function(t, b, c, d){
// doing some crazy calculations depends on runtime
return x;
}});
Fat.animate(custom_object[]{}, custom_property[]{}, options{})
Note: You can't use more than one custom property per animation. Do not mix the custom property with existing ones within same animation.
Just add a property with the name "custom":
Fat.animate("#mydiv", { custom: "50%" },{ ease: "cubicInOut", step: function(progress, current){
this.style.left = current;
}});
Handle unit separately:
Fat.animate("#mydiv", { custom: 50 },{ ease: "cubicInOut", step: function(progress, current){
this.style.left = current + "%";
}});
Pass in custom object/function as first parameter instead of an element:
Fat.animate({
css: document.getElementById("mydiv").style
},{
custom: 50
},{
ease: "cubicInOut",
step: function(progress, current){
this.css.left = current + "%"; // "this" refers to the custom object
}
});
You can also use sequences:
... [custom: 50, custom: 0, custom: 100, custom: 0]
This way it is possible to pass custom data, logic and renderer through each animation job, e.g.:
var handler = {
unit: "%",
css: document.getElementById("mydiv").style,
set: function(style, value){
this.css[style] = value + this.unit;
}
};
Fat.animate(handler, { custom: 50 },{
ease: "cubicInOut",
step: function(progress, current){
this.set("left", current); // "this" refers to the handler
}
});
You can also use array of objects/handlers:
Fat.animate([handler1, handler2, handler3], ...
If you don't need the from/to transition values at all, another scenario could be:
function cubicInOut(x) {
return ((x *= 2) <= 1 ? x*x*x : (x -= 2) *x*x + 2) / 2;
}
Fat.animate({ ease: cubicInOut }, { custom: true },{ step: function(progress){
var current = this.ease(progress); // "this" refers to the custom object
// console.log(current);
}});
alternatively:
Fat.animate({}, { custom: true },{ step: function(progress){
var current = cubicInOut(progress);
// console.log(current);
}});
or:
Fat.animate({}, { custom: 1 },{ ease: cubicInOut, step: function(progress, current){
// console.log(current);
}});
Fat.animate("#mydiv", [
{ left: "100%" }, // 1st animation, 2000ms
{ top: "100%" }, // 2nd animation, 2000ms
{ left: 0 }, // 3rd animation, 2000ms
{ top: 0 } // 4th animation, 2000ms
],{
callback: function(){ alert("Next Loop") },
delay: 2000,
loop: -1 // infinite
});
Use custom options per style property:
Fat.animate("#mydiv", [{
left: { // 1st animation
from: 0,
to: 100,
unit: "%",
duration: 2000
}
},{
top: { // 2nd animation
to: "100%",
duration: 2000,
ease: "easeInOut",
delay: 0
}
},
...
Fat.animate("#mydiv", {
"25%": { left: "100%" }, // 0 -> 25%, 500ms
"50%": { top: "100%" }, // 25 -> 50%, 500ms
"75%": { left: 0 }, // 50 -> 75%, 500ms
"100%": { top: 0 } // 75 -> 100%, 500ms
},{
callback: function(){ alert("Next Loop") },
delay: 2000,
loop: -1 // infinite
});
Use custom options per style property:
Fat.animate("#mydiv", {
"0%": {
left: {
to: "100%",
ease: "easeIn"
}
},
"100%": {
top: {
to: "0%",
ease: "easeOut"
}
}
},
...
You can also combine Sequences and Keyframes as well as custom options per style property:
Fat.animate("#mydiv", [{
"0%": {
left: 0,
top: 0
},
"100%": {
left: "100%",
top: "100%"
}
},{
"0%": {
left: {
to: 0,
ease: "easeIn"
},
top: {
to: 0,
ease: "easeIn"
}
},
"100%": {
left: {
to: "100%",
ease: "easeOut"
},
top: {
to: "100%",
ease: "easeOut"
}
}
}],
...
Fat.animate("#mydiv", "fadeOut");
Combine multiple presets (ordered):
Fat.animate("#mydiv", "fadeOut zoomOut rollOut");
Also usable with sequences:
Fat.animate("#mydiv", ["slideUp", "zoomIn"]);
Define custom preset:
Fat.preset["fade-out-down"] = {
opacity: 0,
translateY: "100%"
};
Use custom preset:
Fat.animate("#mydiv", "fade-out-down");
Builtin Presets:
- fadeIn, fadeOut, fadeToggle
- slideUp, slideDown, slideToggle
- slideInLeft, slideOutLeft, slideToggleLeft
- slideInRight, slideOutRight, slideToggleRight
- slideInTop, slideOutTop, slideToggleTop
- slideInBottom, slideOutBottom, slideToggleBottom
- zoomIn, zoomOut, zoomToggle
- rollIn, rollOut, rollToggle
- blurIn, blurOut, blurToggle
Get the global scene (default):
var scene = Fat.animate(element, { left: "100%" });
Create a new scene:
var scene = Fat.create();
Add animations to a scene:
scene.animate(element, { left: "100%" });
scene.destroy();
Re-initialize styles before next update:
scene.init();
Update current animation styles:
scene.update("#mydiv", { left: "0%" });
scene.pause();
scene.play(false);
Play a scene:
scene.play();
alternatively:
scene.pause(false);
scene.reverse();
alternatively set direction:
scene.reverse(false);
Stop animation and jump back to the start:
scene.reset();
Stop animation and jump to the end:
scene.finish();
Finish and also execute callback:
scene.finish(true);
scene.speed(0.5); // half
scene.speed(1); // normal
scene.speed(2); // double
Seek a scene to a specific position:
scene.seek(0); // start
scene.seek(0.5); // half
scene.seek(1); // end
Engine | js | css | native |
Renderer | Javascript (Default) | CSS Transition | Web Animation API |
Support Control | x | - | - |
Support SVG | x | - | - |
Support Scenes | x | x | x |
File Size (gzip) | 7.2 kb | 0.8 kb | 0.5 kb |
Fat.transition("#mydiv", {
left: "100px",
top: "100px"
},{
delay: 1000,
duration: 2000,
ease: "easeInOut",
callback: function(){
// done
console.log(this.style.left);
}
});
Fat.native("#mydiv", {
left: "100px",
top: "100px"
},{
delay: 1000,
duration: 2000,
ease: "easeInOut",
callback: function(){
// done
console.log(this.style.left);
}
});
You need Node.js including Node Package Manager (NPM)
Install Dependencies:
npm install
Full Build:
npm run build
Light Build:
npm run build-light
Compact Build:
npm run build-compact
Custom Build:
npm run build-custom SUPPORT_EASE_IN_CUBIC=true SUPPORT_CONTROL=true
On custom builds each build flag will be set to false by default.
Alternatively (Custom Build):
node compile SUPPORT_CONTROL=true
Supported Build Flags
Flag | Values |
SUPPORT_COLOR | true, false |
SUPPORT_CONTROL | true, false |
SUPPORT_SEQUENCE | true, false |
SUPPORT_TRANSFORM | true, false |
SUPPORT_FILTER | true, false |
SUPPORT_SCROLL | true, false |
SUPPORT_RELATIVE | true, false |
SUPPORT_CONCURRENCY | true, false |
SUPPORT_EASING | true, false |
SUPPORT_PRESET | true, false |
SUPPORT_ENGINE | string: "all", "js", "css", "native" / "waapi" |
SUPPORT_ANIMATE | true, false (overrides SUPPORT_ENGINE) |
SUPPORT_TRANSITION | true, false (overrides SUPPORT_ENGINE) |
SUPPORT_NATIVE | true, false (overrides SUPPORT_ENGINE) |
The custom build will be saved to fat.custom.js
Copyright 2019 Nextapps GmbH
Released under the Apache 2.0 License