UNPKG

scroll-dom-animation

Version:

Makes animating dom elements on scroll event super easy using a declarative approach without having to touch your css

96 lines (85 loc) 4.25 kB
import util from './utils'; import Element from './Element'; const { getNewElement, inView } = util(); export default function eventHandlers(inViewDistance) { let elementInstances = []; function handleScrollAnimation(e) { (function animateInstances() { elementInstances.forEach(element => { if(inView(element.element, inViewDistance)) { element.animate(); } else { element.initializePosition(); } }) })() } const initializeAnimationPositions = (elementsToAnimate) => () => { if(!(elementsToAnimate instanceof Array)) throw "argument must be of type array"; if(elementsToAnimate[0] instanceof Array) { // sample input: [[selector, direction, options], [...same]] elementsToAnimate.forEach(elementSelector => { _getElementInstances(elementSelector); }) } else if(typeof elementsToAnimate[0] === 'string') { /** * this is an optimized for when user provides selector as argument rather * than an array of selectors * sample input: ['.selector', direction, options] */ _getElementInstances(elementsToAnimate); } else { throw "argument must be of type array. Example 1: ['.selector', '->', options] \n Example 2: [['.selector', '->', options], [], []]" } } function _getElementInstances(elementSelectors) { const elementIndex = elementSelectors[2] ? elementSelectors[2].elementIndex : false; const elementSelector = elementSelectors[0]; const animationDirection = elementSelectors[1] ? elementSelectors[1] : ''; const options = elementSelectors[2] || { time: null, offset: null, inViewDistance, elementIndex }; const elements = getNewElement(elementSelector); const directions = _getDirection(animationDirection); if(!elements.forEach) { let instance = new Element(elements, animationDirection, options); elementInstances = [...elementInstances, instance]; } else { let bool = true; elements.forEach((each, i) => { if(elementIndex && !elementIndex.includes(i)) return; let instance; if(Array.isArray(directions)) { let currentDirection = bool ? directions[0] : directions[1]; bool = !bool; instance = new Element(each, currentDirection, options) } else { instance = new Element(each, animationDirection, options) } elementInstances = [...elementInstances, instance]; }); } } function smoothScrollToAnchor(e) { e.preventDefault(); const scrollToTarget = getHrefTarget(e); if(!scrollToTarget) return console.error('href attribute on the element provided does not contain an anchor'); const targetElement = document.getElementById(scrollToTarget); targetElement.scrollIntoView({ behavior: "smooth", block: 'start' }) } function _getDirection(direction) { if(direction.length === 4) { let result = []; result.push(direction.split('').splice(0, 2).join('')) result.push(direction.split('').splice(2, 4).join('')) return result; } else if(direction === '^v' || direction === 'v^') { return ['^', 'v'] } else { return direction; } } return { handleScrollAnimation, smoothScrollToAnchor, initializeAnimationPositions } }