Я написал простой модуль для применения классов css из библиотеки animate.css. Классы определены в атрибуте data элемента html, но по какой-то причине все анимации работают, только если они уникальны на странице, в противном случае реализована анимациятолько до последнего элемента с его классом.
Upd.Отладчик в devtools показывает, что модуль выполняет итерацию по каждому узлу, но все же применяет неуникальные анимации только к последнему узлу.
Пример:
<h2 id="1" class="module_animate-box" data-animate-trigger="scroll" data-animate-script='{"class":"zoomIn","position":"700"}'>Hello</h2>
<h2 id="2" class="module_animate-box" data-animate-trigger="scroll" data-animate-script='{"class":"zoomIn","position":"1000"}'>World</h2>
, если вы дважды используете класс "zoomIn"страница, только id = "2" будет работать.
import "./animate.css";
//check full list of availiable classes here: https://github.com/daneden/animate.css/blob/master/README.md
export default class animationModule {
constructor({
selector
}) {
this.selector = selector;
this.nodes = Array.from(document.querySelectorAll(selector));
this.init();
}
getCoords(e) {//get coords of an element
let coords = e.getBoundingClientRect();
return coords;
}
getTriggerEvent(e){//get the appropriate function by it's trigger type
switch(e.dataset.animateTrigger){
case "scroll":
return this.onScroll
break;
case 'hover':
return this.onHover
break;
case 'moved':
return this.onMouseMove//sort of parallax
default:
return "loaded"
}
}
onScroll(e,repeats,animationTriggerYOffset,isOutOfViewport,animationType){//if trigger === scroll
e.style.animationIterationCount = repeats;//set iteration limits of animation
window.onscroll= function(){
(window.pageYOffset >= animationTriggerYOffset && !(window.pageYOffset > isOutOfViewport.bottom)) ?//check if target el is in the trigger position and not out of the viewport
e.classList.add('animated', 'infinite', animationType.class) ://toggles on classes if everything is ok
e.classList.remove('animated', 'infinite', animationType.class)// toggles off classes if lower the defined trigger position or out of viewport
repeats = e.dataset.animateRepeat;//reset iteration for animation
}
}
onHover(e, repeats, animationTriggerYOffset, isOutOfViewport, animationType){//if trigger === hover
e.style.animationIterationCount = repeats;//set iteration for animation
e.addEventListener('mousemove', ()=> {
e.classList.add('animated', 'infinite', animationType.class);
})
e.addEventListener('animationend', function () {//resets animation iteration
e.classList.remove('animated', 'infinite', animationType.class)
})
}
onMouseMove(e, repeats, animationTriggerYOffset, isOutOfViewport, animationType){
//in data-animate-script set values{"pageX":"#","pageY": "#"} the less the number the bigger the amplitude. negative numbers reverse the movement
window.addEventListener('mousemove',(m) => {
e.style.transform = `translate(${m.pageX * -1 / animationType.pageX}px, ${m.pageY * -1 / animationType.pageY}px)`
})
}
init() {
this.nodes.forEach(e => {
console.log(e.dataset)
let animationType = JSON.parse(e.dataset.animateScript);//define class name of animation needed to apply
let repeats = e.dataset.animateRepeat || 'infinite';//define number of iterations for animation (INFINITE by default)
let animationTriggerYOffset = animationType.position || 0;//defines YOffset to trigger animation(0 by default)
let isOutOfViewport = this.getCoords(e);//sets coords of an element from getCoords function
let action = this.getTriggerEvent(e);//get appropriate function depending on data-animate-trigger value
action(e, repeats, animationTriggerYOffset, isOutOfViewport, animationType);//call appropriate function per each node
})
}
}
// Module data and attributes
// .module_animate-box - class that defines animation target
// data-animate-trigger - animation trigger(possible values: "scroll", "hover", "moved"(watches mouse movement))
// data-animate-repeat - number of repetitions (infinite by default)
// data-animate-script - JSON description of animation. example: '{"class":"wobble","position":"300"}' - will add class wobble when pageYoffset===300