Skip to content

Instantly share code, notes, and snippets.

@wiledal
Last active March 19, 2025 05:26
Show Gist options
  • Select an option

  • Save wiledal/0050fdb1b7a271b029a04639a7416065 to your computer and use it in GitHub Desktop.

Select an option

Save wiledal/0050fdb1b7a271b029a04639a7416065 to your computer and use it in GitHub Desktop.
Tiny GSAP-style CSS animation library
/*
Tiny, smart, single-method animation library for CSS animations - TweenMax-style.
Returns a Promise that resolves when the transition has ended.
Usage:
Single element:
AnimationService.animate(element, time, to)
AnimationService.animate(element, time, from, to)
Multiple elements with stagger:
AnimationService.animate(elements, time, to, [staggerDelay])
AnimationService.animate(elements, time, from, to, [staggerDelay])
Example:
// Get an array of elements
var els = [].slice.call(document.querySelectorAll('.animated-thing'))
// from-state
var from = {
opacity: 0,
transform: 'translate3d(100px, 0, 0) rotateY(20deg)'
}
// to-state
var to = {
opacity: 1,
transform: 'translate3d(0, 0, 0) rotateY(0)',
ease: 'ease-out', // Custom attribute in {to} for quick ease
delay: 100 // Custom attribute in {to} for adding delay to the start of the animation
}
// 50 millisecond delay between the animations of the individual elements
var staggerDelay = 50
// For one second
var time = 1000
AnimationService.animate(els, time, from, to, staggerDelay).then(() => {
alert('Animation completed!')
})
*/
const AnimationService = (() => {
function setStyles(el, styles) {
for (var prop in styles) {
el.style[prop] = styles[prop]
}
}
function animate(target, time, arg1, arg2, arg3) {
var els = Array.isArray(target) ? target : [target]
var from = typeof arg2 === 'object' ? arg1 : null
var to = from ? arg2 : arg1
var staggerDelay = (from ? arg3 : arg2) || 0
els.forEach((el) => {
el.style.transition = 'none'
el.removeEventListener('transitionend', el.__onTransitionEnd)
if (from) {
setStyles(el, from)
}
})
els[0].offsetWidth // trigger layout
els.forEach((el, i) => {
el.style.transition = 'all'
el.style.transitionDuration = time + 'ms'
el.style.transitionTimingFunction = to.ease ? to.ease : 'ease'
el.style.transitionDelay = ((to.delay ? to.delay : 0) + (staggerDelay * i)) + 'ms'
setStyles(el, to)
})
return new Promise((resolve) => {
var transitionTarget = els[els.length-1]
transitionTarget.__onTransitionEnd = function(event) {
if (event.target === transitionTarget) {
event.target.removeEventListener('transitionend', event.target.__onTransitionEnd)
resolve()
}
}
transitionTarget.addEventListener('transitionend', transitionTarget.__onTransitionEnd)
})
}
return {
animate
}
})()
/*
Easing functions that can be used by the css animation library.
*/
var ease = {
inQuad: 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',
inCubic: 'cubic-bezier(0.550, 0.055, 0.675, 0.190)',
inQuart: 'cubic-bezier(0.895, 0.030, 0.685, 0.220)',
inQuint: 'cubic-bezier(0.755, 0.050, 0.855, 0.060)',
inSine: 'cubic-bezier(0.470, 0.000, 0.745, 0.715)',
inExpo: 'cubic-bezier(0.950, 0.050, 0.795, 0.035)',
inCirc: 'cubic-bezier(0.600, 0.040, 0.980, 0.335)',
inBack: 'cubic-bezier(0.600, -0.280, 0.735, 0.045)',
outQuad: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',
outCubic: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)',
outQuart: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)',
outQuint: 'cubic-bezier(0.230, 1.000, 0.320, 1.000)',
outSine: 'cubic-bezier(0.390, 0.575, 0.565, 1.000)',
outExpo: 'cubic-bezier(0.190, 1.000, 0.220, 1.000)',
outCirc: 'cubic-bezier(0.075, 0.820, 0.165, 1.000)',
outBack: 'cubic-bezier(0.175, 0.885, 0.320, 1.275)',
inOutQuad: 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',
inOutCubic: 'cubic-bezier(0.645, 0.045, 0.355, 1.000)',
inOutQuart: 'cubic-bezier(0.770, 0.000, 0.175, 1.000)',
inOutQuint: 'cubic-bezier(0.860, 0.000, 0.070, 1.000)',
inOutSine: 'cubic-bezier(0.445, 0.050, 0.550, 0.950)',
inOutExpo: 'cubic-bezier(1.000, 0.000, 0.000, 1.000)',
inOutCirc: 'cubic-bezier(0.785, 0.135, 0.150, 0.860)',
inOutBack: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)',
linear: 'linear'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment