@enea-entertainment/animjs
TypeScript icon, indicating that this package has built-in type declarations

1.0.4 • Public • Published

AnimJS

Lighweight library which lets you tween multiple object's properties

Dependency: Runner

Features

  • tween, timeline, delay, wait
  • onStart(), onUpdate(), onRepeat(), onComplete() callbacks
  • manual tick
  • tweening array of numbers
  • seek time
  • time scale
  • animation groups
  • ability to provide custom easing functions

Installation

npm install --save-dev @enea-entertainment/animjs

NPM


Basic usage example

import { anim } from '@enea-entertainment/animjs';

const myObject =
    {
        alpha    : 0,
        rotation : Math.PI
    };

anim.to(myObject,
    {
        duration : 1,
        alpha    : 1,
        rotation : 0,
        ease     : 'sineInOut'
    });

Update loop

AnimJS doesn't come with built-in update loop, instead it encourages you to call anim.tick(); manually. Whenever you want to.

import { anim } from '@enea-entertainment/animjs';

mainUpdateLoop(deltaTime)
{
    // request animation frame

    anim.tick(deltaTime); // in seconds

    // update scene
    // render scene
}

or simply via setInterval();

import { anim } from '@enea-entertainment/animjs';

const delta = 16.7;

setInterval(()=>
{
    anim.tick(delta / 1000); // in seconds
}, delta);

Tween example

import { anim } from '@enea-entertainment/animjs';

const myObject =
    {
        x : 0,
        y : 50
    };

// by setting 'paused: true' we tell tween not to start immediately
const firstTween = anim.from(myObject,
    {
        paused : true,
        delay  : 1,
        y      : 0,

        onStart: () =>
        {
            console.log('First tween start');
        },

        onComplete: () =>
        {
            console.log('First tween complete');
        }
    });

anim.to(myObject,
    {
        duration    : 2,
        x           : 100,
        repeat      : 1,
        repeatDelay : 0.5,
        ease        : 'cubicOut',
        yoyoEase    : 'backInOut',

        onStart: () =>
        {
            console.log('Second tween start');
        },

        onUpdate: (target, progress) =>
        {
            // target   : returns tweened object (myObject in this case)
            // progress : returns value between 0 and 1
            console.log('Second tween update:', progress);
        },

        onComplete: () =>
        {
            console.log('Second tween complete');

            // now we run firstTween
            firstTween.paused = false;
        }
    });

For 'infinite' tween loop, provide

repeat: -1

Note: loop isn't really infinite, AnimJS internally uses very large number.

anim.fromTo(); method allows you to override object's start values

import { anim } from '@enea-entertainment/animjs';

const myObject =
    {
        x : 0,
        y : 1
    };

// myObject's x and y values will both start from 2
anim.fromTo(myObject,
    {
        x : 2,
        y : 2
    },
    {
        duration : 1,
        x        : 4,
        y        : 4,
        ease     : 'none'
    });

Timeline example

above shown tween example could be written in simpler form without pausing and resuming first tween by using anim.timeline();
Tweens in timeline are chained and second tween will start after first one has finished.

import { anim } from '@enea-entertainment/animjs';

const myObject =
    {
        x : 0,
        y : 50
    };

const timeline = anim.timeline({
    onStart: () =>
    {
        console.log('timeline start');
    },

    onComplete: () =>
    {
        console.log('timeline complete');
    }
});

timeline.to(myObject,
    {
        duration    : 2,
        x           : 100,
        repeat      : 1,
        repeatDelay : 0.5,
        ease        : 'cubicOut',
        yoyoEase    : 'backInOut',

        onStart: () =>
        {
            console.log('First tween start');
        },

        onComplete: () =>
        {
            console.log('First tween complete');
        }
    });

timeline.to(myObject,
    {
        delay : 1,
        y     : 10,

        onStart: () =>
        {
            console.log('Second tween start');
        },

        onComplete: () =>
        {
            console.log('Second tween complete');
        }
    });    

It is also possible to start tweens in timeline at the same time by providing 3rd parameter - label{string}

All tweens groupped by labelB will start after all tweens in label labelA have finished.

import { anim } from '@enea-entertainment/animjs';

const myObject =
    {
        a1 : 0,
        a2 : 0,

        b1 : 0,
        b2 : 0
    };

const timeline = anim.timeline({
    onStart: () =>
    {
        console.log('timeline start');
    },

    onComplete: () =>
    {
        console.log('timeline complete');
    }
});

// a1 will finish after one second
timeline.to(myObject,
    {
        duration : 1,
        a1       : 1,

        onComplete: () =>
        {
            console.log('a1 complete');
        }
    }, 'labelA');

// a2 will finish after two seconds
timeline.to(myObject,
    {
        duration : 2,
        a2       : 1,

        onComplete: () =>
        {
            console.log('a2 complete');
        }
    }, 'labelA');

// then b1 will start
// b1 will finish after 4 seconds, notice repeat param
timeline.to(myObject,
    {
        duration : 1,
        b1       : 1,
        repeat   : 3,

        onComplete: () =>
        {
            console.log('b1 complete');
        }
    }, 'labelB');

// b2 will finish 2 seconds after labelA has finished
timeline.to(myObject,
    {
        duration : 2,
        b2       : 1,

        onComplete: () =>
        {
            console.log('b2 complete');
        }
    }, 'labelB');

Tweening array of numbers

Just like numbers, you can also tween arrays

import { anim } from '@enea-entertainment/animjs';

const myObject =
    {
        a : [3, 2, 1],
        b : new Float32Array(3),
        c : [0, 8, 9],
        d : 0
    };

anim.to(myObject,
    {
        a : [1, 2, 3],
        b : [4, 5, 6],
        c : [7], // only first value will be tweened
        d : 10,

        onComplete: () =>
        {
            console.log(myObject.a);
            console.log(myObject.b);
            console.log(myObject.c);
            console.log(myObject.d);

            // outputs {object}

            // myObject.a [1, 2, 3]
            // myObject.b [4, 5, 6]
            // myObject.c [7, 8, 9]
            // myObject.d 10
        }
    });

Tween seek

Jumps to a specific time

import { anim } from '@enea-entertainment/animjs';

const myTween = anim.to({ value: 0 },
    {
        paused   : true,
        duration : 4,
        value    : 10,

        onUpdate: (target) =>
        {
            console.log(target.value);
        }
    });

// outputs: 5
myTween.seek(2);

Time scale

time scale can be used to speed up or slow down tweens. You can either set it globally or per tween

import { anim } from '@enea-entertainment/animjs';

// global time scale
// all tweens will be affected, playing at double speed
anim.timeScale = 2;

or individually

import { anim } from '@enea-entertainment/animjs';

const tween = anim.to({ value: 0 },
    {
        duration : 1,
        value    : 1,
    });

// tween will play at double speed
// and will finish in 0.5 seconds
tween.timeScale = 2;

Built-in easing functions

'none' == 'linear' | 'back' | 'bounce' | 'circ' | 'cubic' | 'elastic' | 'expo' | 'quad' | 'quart' | 'quint' | 'sine'


Easing

could be written in different ways, all of them are valid

ease: 'sineIn'
ease: 'sineOut'
ease: 'sineInOut'
import { Easing } from '@enea-entertainment/animjs';

ease: Easing.sineIn
ease: Easing.sineOut
ease: Easing.sineInOut
import { Easing } from '@enea-entertainment/animjs';

ease: Easing.sine.in
ease: Easing.sine.out
ease: Easing.sine.inOut

Custom easing function

import { anim } from '@enea-entertainment/animjs';

function stepped(time, steps)
{
    return Math.max(0, Math.min(1, (((steps * time) | 0) + 1) * (1 / steps)));
}

const myObject =
    {
        x : 0
    };

anim.to(myObject,
    {
        x    : 10,
        ease : (time) => { return stepped(time, 5); },

        onUpdate: () =>
        {
            // outputs: 2, 4, 6, 8, 10
            console.log(myObject.x);
        }
    });

Delaying code execution

Because AnimJS tick(); is updated manually, sometimes you might want to use AnimJS instead of setTimeout(); to delay code execution.

Either using anim.delay(); where 1st parameter is callback and 2nd parameter is required delay (in seconds)

import { anim } from '@enea-entertainment/animjs';

myMethod()
{
    anim.delay(()=>
    {
        // some code
    }, 1);
}

or by using anim.wait(); which returns promise

import { anim } from '@enea-entertainment/animjs';

anim.wait(1).then(()=>
{
    // some code
});

or

import { anim } from '@enea-entertainment/animjs';

async myMethod()
{
    await anim.wait(1);

    // some code
}

Animation groups

Tweens, timelines and delays can be grouped together and then paused, resumed or killed at once

import { anim } from '@enea-entertainment/animjs';

const enum TweenGroup
    {
        INTRO,
        GAME
    }

const introTween1 = anim.to({value : 0},
    {
        duration : 1,
        group    : TweenGroup.INTRO
        value    : 1,
    });
 
const introTween2 = anim.to({value : 2},
    {
        duration : 1,
        group    : TweenGroup.INTRO
        value    : 3,
    });   

// kills all tweens in TweenGroup.INTRO
anim.group.get(TweenGroup.INTRO)?.kill();

Stopping tween, timeline, delay

import { anim } from '@enea-entertainment/animjs';

const myObject =
    {
        x : 0,
        y : 0,

        scale:
            {
                x : 1,
                y : 1
            }
    };

const tween1 = anim.to(myObject,
    {
        x : 1,
        y : 1
    });

// kills tween1
tween1.kill();

const tween2 = anim.to(myObject.scale,
    {
        x : 2,
        y : 2
    });

// kills all running tweens of myObject.scale
anim.killTweensOf(myObject.scale);

// or
// tween2.kill();

similarly you can kill entire timeline (which will also kill all its tweens)

timeline.kill();

Killing all tweens, timelines, delays at once:

anim.killAll();

Tween or timeline can be marked as protected
Such tweens/timlines will not be killed by anim.killAll(); or tween.kill();

import { anim } from '@enea-entertainment/animjs';

const tween = anim.to(myObject,
    {
        protected : true,

        onComplete: ()=>
        {
            console.log('tween complete');
        }
    });

// tween will not be stopped    
anim.killAll();
tween.kill();

To protect anim.delay(); set its protected property after initialization

import { anim } from '@enea-entertainment/animjs';

const myDelay = anim.delay(()=>
    {
        console.log('delay complete');
    }, 1);

myDelay.protected = true;


// delay will not be stopped    
anim.killAll();
myDelay.kill();

However, if you later decide to stop also protected tweens, timelines or delays, pass true to kill(); method

    anim.killAll(true);

    // or

    tween.kill(true);
    timeline.kill(true);
    myDelay.kill(true);

AnimJS default settings

feel free to override any of these

import { anim } from '@enea-entertainment/animjs';

console.log(anim.defaults);

// outputs {object}:

// delay: 0
// duration: 1
// ease: "none"
// paused: false
// protected: false
// repeat: 0
// repeatDelay: 0
// yoyo: false

Webpack ProvidePlugin

Provides anim so you don't have to import it everywhere

const webpack = require('webpack');

plugins:
[
    new webpack.ProvidePlugin({
        anim : ['@enea-entertainment/animjs', 'anim']
    })
]

TODO

  • repeat whole timeline
  • timeline.seek()
  • timeline.restart()

Thank you

  • AnimJS is based on tweenr by Matt DesLauriers (@mattdesl)
  • Robert Penner for easing functions see terms of use
  • Hugh Kennedy (@hughsk) for an-array check

License

MIT, see LICENSE for details.

Package Sidebar

Install

npm i @enea-entertainment/animjs

Homepage

www.enea.sk/

Weekly Downloads

3

Version

1.0.4

License

MIT

Unpacked Size

110 kB

Total Files

6

Last publish

Collaborators

  • enea-entertainment