A simple tweening library for animating DOM elements and JavaScript objects.
Open the index.html file to view a demo of the essential features.
Director comes with three types of tweens, 'to', 'from', and 'fromTo'. These tweens currently support numeric CSS attributes as well as 2D Transforms. Currently, 2D Translation only supports units as percentages. The animation target can be a single DOM Node, a NodeList, or a JavaScript object.
A 'to' tween will allow you to animate properties from their current state to a specified end state.
Director.to(element, { opacity: 0.5 }, { duration: 1, ease: 'linear' })
A 'from' tween will allow you to animate properties from a specified state to their current state.
Director.from(element, { opacity: 0, translateX: -100 }, { duration: 1, ease: 'easeOutExpo' })
A 'fromTo' tween will allow you to animate properties by providing both a beginning state and an ending state.
Director.fromTo(element, { opacity: [1, 0], translateY: [100, -100] }, { duration: 1, ease: 'easeInOutQuint' })
The addClass method will append a class to any DOM Node or NodeList. When used in a Scene, the 'toggle' attribute can be set if the class is to be removed when the Scene progress is set prior to the addClass animation, such as when rewinding.
scene.addClass(element, { class: 'show' }, { toggle: true }, 2)
The removeClass method will remove a class from any DOM Node or NodeList. When used in a Scene, the 'toggle' attribute can be set if the class is to be added when the Scene progress is set prior to the addClass animation, such as when rewinding.
scene.removeClass(element, { class: 'hidden' }, { toggle: true }, 2)
The stagger attribute can be used to stagger the timing of each animated element by a set duration if the target is either a NodeList or an array of JavaScript objects.
Director.fromTo(elements, { opacity: [1, 0], translateY: [100, -100] }, { duration: 1, stagger: 0.1, ease: 'easeInOutQuint' })
Any tween can use a callback function to execute a function when a tween starts, updates, or completes.
Director.to(element, { opacity: 0 }, { duration: 1, ease: 'easeInOutQuint', onStart: () => {
console.log('tween has started')
} })
Director.to(element, { opacity: 0 }, { duration: 1, ease: 'easeInOutQuint', onUpdate: () => {
console.log('tween has updated')
} })
Director.to(element, { opacity: 0 }, { duration: 1, ease: 'easeInOutQuint', onComplete: () => {
console.log('tween has completed')
} })
Tweens use a linear easing by default. Director supports the following easing functions:
- 'linear'
- 'easeInSine'
- 'easeOutSine'
- 'easeInOutSine'
- 'easeInQuad'
- 'easeOutQuad'
- 'easeInOutQuad'
- 'easeInCubic'
- 'easeOutCubic'
- 'easeInOutCubic'
- 'easeInQuart'
- 'easeOutQuart'
- 'easeInOutQuart'
- 'easeInQuint'
- 'easeOutQuint'
- 'easeInOutQuint'
- 'easeInExpo'
- 'easeOutExpo'
- 'easeInOutExpo'
- 'easeOutSpring'
- 'easeOutBack'
Tie multiple animations together into one choreographed sequence. Create a Scene and use the same tweening syntax to add animations to it. A fourth argument is required in order to set the starting time for the particular tween.
const scene = new Director.Scene()
scene.fromTo(elementOne, { scale: [1, 0], opacity: [1, 0] }, { duration: 1, ease: 'easeOutQuint', stagger: 0.1 }, 0)
scene.fromTo(elementTwo, { scale: [0, 1], opacity: [0, 1] }, { duration: 1, ease: 'easeOutQuint' }, 0.25)
scene.play()
Scenes can be played, paused, and even rewound. Calls to setProgress can allow for more complex functionality like scrubbing through an animation through a range input. The setProgressImmediately method differs from setProgress in that it will also update the current animation state, rather than just setting the progress alone so that an external requestAnimationFrame call can handle the update.
scene.play()
scene.pause()
scene.rewind()
scene.setProgress(0.5)
scene.setProgressImmediately(0.75)
Camera uses IntersectionObserver and a scroll event listener to facilitate controlling a Scene's playback by scroll position. A Camera takes three arguments, an element that will be the scroll target, a scene, and an options object. A Camera object contains its own 'progress' attribute which stores the progress of the scene.
Using the 'pinned' option assume that the target element is using 'position: sticky;' and automatically calculates the height of the target's parent so that all Camera sequences playback at the same speed, regardless of duration.
The 'beginOnIntersection' option will force the scene to begin scrubbing as soon as the target element has intersected the viewport, as opposed to when the target element has reached the top of the viewport.
An 'offset' value can be supplied to alter the scroll position necessary to begin the scene animation.
const scene = new Director.Scene()
scene.fromTo(elements, { scale: [1, 0], opacity: [1, 0] }, { duration: 1, ease: 'easeOutQuint', stagger: 0.1 }, 0)
scene.fromTo(element, { scale: [0, 1], opacity: [0, 1] }, { duration: 1, ease: 'easeOutQuint' }, 0.25)
const camera = new Director.Camera(elementWrapper, scene, { pinned: true, offset: 100, beginOnIntersection: true })
const update = () => {
scene.setProgress(camera.progress)
window.requestAnimationFrame(update)
}
window.requestAnimationFrame(update)
The 'setScene' method can be used to assign a new scene to an existing Camera object. The 'resize' method can be called by an external resize event listener to recalculate the proper scrolling progress of a Scene.
camera.setScene(newScene)
camera.resize()
Licensed under the MIT license.