The aim of Monomove is to be a minimal toolkit for adding interaction and movement to web apps. It consists of a couple of components:
Tween
(animation tweening)TweenManager
(manages the tweens)delay
(simple utility)Timeline
(a timeline of parallel tweens)TweenChain
(a chain of consecutive tweens)RenderLoop
(manages rendering viarequestAnimationFrame
)SmoothScroller
(listen to DOM element scroll positions viaIntersectionObserver
)
npm install --save @monokai/monomove
The recommended way to use Monomove is via esm style modules. This way of importing supports tree-shaking and keeps your packages small.
import {Tween} from '@monokai/monomove';
You can also use commonjs style modules (const {Tween} = require('monomove')
) but then you'll lose the tree shaking part.
const {Tween} = require('@monokai/monomove');
You can directly link to Monomove via a script tag or require
the umd version and it will globally create a monomove
object from which you can use the modules.
require('@monokai/monomove/umd');
const {SmoothScroller} = window.monomove;
Alternatively, you can directly import from the source files in your project. The source files are not transpiled and potentially use some JavaScript syntax that's not cross-browser compatible.
import {Tween} from 'monomove/source';
A minimal animation tweening utility.
import {Tween} from '@monokai/monomove';
Simple animation, tweening the opacity:
const element = document.getElementById('my-id');
const duration = 0.2; // seconds
await new Tween(({value}) => {
element.style.opacity = value;
}, duration)
.start();
Tweening position with easing:
await new Tween(({value}) => {
element.style.left = `${value * 100}px`;
}, duration)
.easing('0.25, 0.25, 0, 1') // css style easing
.start();
Alternative invocation with any object:
await new Tween({
x: 0,
y: 0
}, duration)
.to({
x: 100,
y: 200
})
.onUpdate(({x, y}) => {
element.style.transform = `translate3d(${x * 100}px, ${y * 100}px, 0)`;
})
.start();
Adding tweens together and create a single timeline
import {Timeline} from '@monokai/monomove';
A timeline is a collection of tweens playing in parallel that you can control with a normalized position (between 0 and 1, inclusive).
Create a timeline of two tweens and jump to 50% of the timeline:
const timeline = new Timeline([
new Tween(({value}) => {
element.style.opacity = value * 0.5;
}, 2),
new Tween(({value}) => {
element.style.left = `${value * 100}px`;
}, 1).delay(0.5)
])
timeline.setPosition(0.5);
import {TweenChain} from '@monokai/monomove';
A tween chain is a collection of tweens that play after each other. You can control the chain by setting a normalized position (between 0 and 1, inclusive).
Create a chain of two tweens and jump to 50% of the timeline:
const tweenChain = new TweenChain([
new Tween(({value}) => {
element.style.opacity = value * 0.5;
}, 2),
new Tween(({value}) => {
element.style.left = `${value * 100}px`;
}, 1).delay(0.5)
])
tweenChain.setPosition(0.5);
import {TweenManager} from '@monokai/monomove';
The tween manager takes care of running and cleaning up tween instances. Whenever you want to immediately delete tweens, you can use this class
TweenManager.removeAll();
import {RenderLoop} from '@monokai/monomove';
The main responsibility of the render loop is to keep track of the time and triggering the tweens on each drawing frame of the browser.
function onTick(ms) {
console.log(`elapsed milliseconds: ${ms}`);
}
RenderLoop.add(this, onTick);
RenderLoop.remove(this, onTick);
RenderLoop.remove(this);
import {delay} from '@monokai/monomove';
A simple utility to wait a bit without relying on setTimeout
;
await delay(3);
The Smooth Scroller lets you control DOM elements based on the scroll position in the browser
import {SmoothScroller} from '@monokai/monomove';
const smoothScroller = new SmoothScroller({
scrollDuration: 1 // easing duration (default = 0)
});
smoothScroller.scrollTo(100, 3);
smoothScroller.scrollToElement(document.getElementById('my-element'), 100, 3);
smoothScroller.add([...document.getElementsByClassName('block')], ({
factor,
item
}) => {
item.style.opacity = 1 - ((factor - 0.5) * 2) ** 4;
});
The callback offers a couple of variables:
item
: the DOM elementbox
: the position and dimensions of the itemrawFactor
: value indicating normalized scroll position: measures from the top of the item at the bottom of the browser page to the bottom of the item at the top of the browser pagerawBoxFactor
: value indicating normalized box scroll position: measures from the top of the item at the bottom of the browser page to the bottom of the item at the bottom of the browser pagefactor
:rawFactor
clamped to [0, 1]boxFactor
:rawBoxFactor
clamped to [0, 1]isInView
: boolean indicating if item is in viewboxIsInView
: boolean indicating if the box of the item is in view
smoothScroller.destroy();