Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

phegman/animate-vanilla-js

Repository files navigation

Animate Vanilla JS

A tiny promise based animation function implemented in vanilla JavaScript.

  • πŸ‘» 3kb (1kb gzipped)
  • πŸ“¦ No dependencies
  • 🌚 TypeScript support
  • πŸ•Ί Multiple built-in easings
  • 🀝 Promise based
  • βš™ Uses requestAnimationFrame
  • πŸ™…β€β™‚οΈ Cancelable

Installation

Module bundler (e.g. Webpack)

yarn add animate-vanilla-js
import animate from 'animate-vanilla-js'

Script tag

Download animate-vanilla-js-browser.js from the latest release here: https://github.com/phegman/animate-vanilla-js/releases

<script type="text/javascript" src="animate-vanilla-js-browser.js"></script>

The animation function will then be usable via the global function animateVanillaJs()

Usage

Parameters

Parameter Type Description Options
from number Starting animation value N/A
to number Ending animation value N/A
duration number Animation duration N/A
easing string || EasingFunction Easing linear, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint
update Function Function with animation value passed as parameter N/A

Basic Usage

import animate from 'animate-vanilla-js'
animate(
 0, // from
 100, // to
 500, // duration
 'easeInOutQuad', // easing
 value => {
 // update function
 console.log(value)
 // Perform DOM manipulation
 }
).then(() => {
 console.log('Done animating')
})

Canceling animations

import animate from 'animate-vanilla-js'
const promise = animate(
 0, // from
 100, // to
 500, // duration
 'easeInOutQuad', // easing
 value => {
 // update function
 console.log(value)
 // Perform DOM manipulation
 }
)
document.addEventListener('keydown', event => {
 event = event || window.event
 // Escape key is pressed
 if (event.keyCode === 27) {
 promise.cancel()
 }
})
promise.then(() => {
 console.log('Done animating')
})

Custom easing

import animate from 'animate-vanilla-js'
animate(
 0, // from
 100, // to
 500, // duration
 (t, b, c, d) => (c * t) / d + b, // easing function
 value => {
 // update function
 console.log(value)
 // Perform DOM manipulation
 }
).then(() => {
 console.log('Done animating')
})

Custom Easing Function

Parameter Type Description
t number Current time
b number Beginning value
c number Change in value
d number Duration

Examples

Animate to height: auto

const el = document.getElementById('el')
const toggleButton = document.getElementById('toggle-button')
toggleButton.addEventListener('click', () => {
 if (el.classList.contains('open')) {
 animate(el.scrollHeight, 0, 500, 'easeInOutQuad', value => {
 el.style.height = `${value}px`
 }).then(() => {
 el.style.cssText = ''
 el.classList.remove('open')
 el.setAttribute('aria-hidden', 'true')
 toggleButton.setAttribute('aria-expanded', 'false')
 })
 } else {
 animate(0, el.scrollHeight, 500, 'easeInOutQuad', value => {
 el.style.height = `${value}px`
 }).then(() => {
 el.style.cssText = ''
 el.classList.add('open')
 el.setAttribute('aria-hidden', 'false')
 toggleButton.setAttribute('aria-expanded', 'true')
 })
 }
})

Smooth Scroll

function addEventListenerMulti(
 element: Element | NodeList,
 listeners: string,
 callback: (arg0: Event) => void
) {
 function addListeners(el: Element) {
 listeners
 .split(' ')
 .forEach(listener => el.addEventListener(listener, callback))
 }
 if (NodeList.prototype.isPrototypeOf(element)) {
 ;[...(<NodeList>element)].forEach(addListeners)
 } else {
 addListeners(<Element>element)
 }
}
function removeEventListenerMulti(
 element: Element | NodeList,
 listeners: string,
 callback: (arg0: Event) => void
) {
 function removeListeners(el: Element) {
 listeners
 .split(' ')
 .forEach(listener => el.removeEventListener(listener, callback))
 }
 if (NodeList.prototype.isPrototypeOf(element)) {
 ;[...(<NodeList>element)].forEach(removeListeners)
 } else {
 removeListeners(<Element>element)
 }
}
const button = document.querySelector('.scroll-button')
const scrollAnchor = document.getElementById('scroll-anchor')
button.addEventListener('click', () => {
 const currentScrollPosition =
 (document.documentElement && document.documentElement.scrollTop) ||
 document.body.scrollTop
 const scrollAnchorTop =
 scrollAnchor.getBoundingClientRect().top + currentScrollPosition
 const promise = animate(
 currentScrollPosition,
 scrollAnchorTop,
 500,
 'easeInQuad',
 value => {
 window.scrollTo(0, value)
 }
 )
 promise.then(() => {
 // Try to focus on element
 scrollAnchor.focus()
 // If that element was not able to be focused, set tabindex and then refocus
 if (document.activeElement !== scrollAnchor) {
 scrollAnchor.tabIndex = -1
 scrollAnchor.focus()
 // We can hide the outline here because normally this element wouldn't be focusable.
 // We made it focusable so the tab order could be set correctly
 scrollAnchor.style.outline = 'none'
 }
 cancelScroll()
 })
 addEventListenerMulti(
 document.querySelectorAll('html, body'),
 'scroll mousedown wheel DOMMouseScroll mousewheel touchmove',
 cancelScroll
 )
 function cancelScroll() {
 promise.cancel()
 removeEventListenerMulti(
 document.querySelectorAll('html, body'),
 'scroll mousedown wheel DOMMouseScroll mousewheel touchmove',
 cancelScroll
 )
 }
})

Browser Support

IE / Edge
IE / Edge
Firefox
Firefox
Chrome
Chrome
Safari
Safari
iOS Safari
iOS Safari
IE11, > Edge 12 > 23 > 24 > 6.1 > 7.1

Development

Start development server with hot module reloading

yarn serve

Build project for production

yarn build

About

A tiny promise based animation function implemented in vanilla JavaScript

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /