export class AnimateElement {
constructor(el) {
this.el = el;
this.animationQueue = [];
this.handleAnimationEnd = this.handleAnimationEnd.bind(this);
}
addAnimation(fromx, fromy, tox, toy, delay, time, func = 'linear', direction = 'forwards', handler = null) {
this.animationQueue.push({ fromx, fromy, tox, toy, delay, time, func, direction, handler });
console.log(this.animationQueue);
}
move() {
console.log('move called.', this.animationQueue.length, this.animationQueue);
if (this.animationQueue.length > 0) {
let oper = this.animationQueue.shift();
let fromx = oper.fromx !== null ? oper.fromx : parseFloat(this.el.style.getPropertyValue('--translate-to-x')) || 0;
let fromy = oper.fromy !== null ? oper.fromy : parseFloat(this.el.style.getPropertyValue('--translate-to-y')) || 0;
console.log('fromx:', fromx, 'fromy:', fromy);
this.el.style.setProperty('--translate-from-x', fromx + 'px');
this.el.style.setProperty('--translate-from-y', fromy + 'px');
this.el.style.setProperty('--translate-to-x', oper.tox + 'px');
this.el.style.setProperty('--translate-to-y', oper.toy + 'px');
this.el.style.setProperty('--animate-time', oper.time + 'ms');
this.el.style.setProperty('--animate-func', oper.func);
this.el.style.setProperty('--animate-delay', oper.delay + 'ms');
this.el.style.setProperty('--animate-direction', oper.direction);
this.el.currentAnimationHandler = oper.handler;
this.el.addEventListener('animationend', this.handleAnimationEnd);
console.log('added listener.');
this.el.classList.add('animate-transform');
}
}
handleAnimationEnd(event) {
console.log('handleAnimationEnd called.');
// Update the from coordinates to be the to coordinates for the next animation
this.el.style.setProperty('--translate-from-x', this.el.style.getPropertyValue('--translate-to-x'));
this.el.style.setProperty('--translate-from-y', this.el.style.getPropertyValue('--translate-to-y'));
event.target.classList.remove('animate-transform');
event.target.removeEventListener('animationend', this.handleAnimationEnd);
console.log('removed listener.');
if (this.el.currentAnimationHandler) {
this.el.currentAnimationHandler();
}
this.move(); // Trigger the next animation in the queue
}
}
I have a jsfiddle:
https://jsfiddle.net/va9skyj4/
Basically I am trying to create a javascript class that encapsulates a DOM element and that can add animations and then trigger them to run sequentially. The break of the code is two fold:
- After the first animation is complete (which works perfectly), the next animation does not animate but just snaps to the end location.
- Never continues after the second move.
Looking at the console.logs the animationend handler is called once only. While the handler removes itself from the element’s listeners, the move method is called which re adds that same handler again.