Skip to content

nextapps-de/fat

Repository files navigation


Web's fastest and most lightweight animation tool.

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

Benchmark Ranking

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

Installation

HTML / Javascript
<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");

API Overview

Global methods / Scene methods:

Controller methods:

Options

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".

Basic Usage

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
    }
});

Use relative values:

Fat.animate("#mydiv", { 
    left: "+=100px",
    top: "*=2"
});
Fat.animate("#mydiv", { 
    left: "-=100px",
    top: "/=2"
});

Callback shorthand:

Fat.animate("#mydiv", { top: "100px" }, function(){
    
    // callback
});

Transform

Fat.animate("#mydiv", { 
    translateX: "100px",
    translateY: "100px"
});

same as:

Fat.transform("#mydiv", ...

same as (has lower performance):

Fat.animate("#mydiv", { 
    "transform": "translate(100px, 100px)"
});

Colors

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
});

Filter

Fat.animate("#mydiv", { 
    brightness: 0.5,
    contrast: 0.5,
    hue: "180deg"
});

You can use the shorthand hue as hue-rotate

same as:

Fat.filter("#mydiv", ...

same as (has lower performance):

Fat.animate("#mydiv", { 
    "filter": "brightness(0.5) contrast(0.5) hue(180deg)"
});

Easing

Built-in easing:

  • 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;
}});

Custom Property / Renderer

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);
}});

Sequences

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
    }
},  
...

Keyframes

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"
        }
    }
}],   
...

Presets (Effects)

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

Scenes (Groups)

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%" });

Destroy scene:

scene.destroy();

Re-initialize styles before next update:

scene.init();

Controls

Update current animation styles:

scene.update("#mydiv", { left: "0%" });

Pause a scene:

scene.pause();

alternatively:

scene.play(false);

Play a scene:

scene.play();

alternatively:

scene.pause(false);

Revert playback (toggle):

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);

Set playback speed:

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

Render Engines

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

Use CSS Transitions:

Fat.transition("#mydiv", { 
    left: "100px",
    top: "100px"
},{ 
    delay: 1000,
    duration: 2000,
    ease: "easeInOut",
    callback: function(){ 
        // done
        console.log(this.style.left);
    }
});

Use Web Animation API:

Fat.native("#mydiv", { 
    left: "100px",
    top: "100px"
},{ 
    delay: 1000,
    duration: 2000,
    ease: "easeInOut",
    callback: function(){ 
        // done
        console.log(this.style.left);
    }
});

Custom Builds

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