(function (){
const {
mergeObjects,
prefersReducedMotion
}=BreakdanceFrontend.utils;
class BreakdancePopupAnimation {
animatingClass='breakdance-popup-animating';
completedClass='breakdance-popup-open';
slideWidth=200;
slideHeight=200;
flipDistance=100;
entranceAnimations={
fade: [
{ alpha: 0 },
{ alpha: 1 }
],
slideUp: [
{ y: this.slideHeight },
{ y: 0 }
],
slideDown: [
{ y: -this.slideHeight },
{ y: 0 }
],
slideRight: [
{ x: -this.slideWidth },
{ x: 0 }
],
slideLeft: [
{ x: this.slideWidth },
{ x: 0 }
],
flipUp: [
{ perspective: 2500, rotateX: -this.flipDistance },
{ rotateX: 0 }
],
flipDown: [
{ perspective: 2500, rotateX: this.flipDistance },
{ rotateX: 0 }
],
flipLeft: [
{ perspective: 2500, rotateY: -this.flipDistance },
{ rotateY: 0 }
],
flipRight: [
{ perspective: 2500, rotateY: this.flipDistance },
{ rotateY: 0 }
],
zoomIn: [
{ scale: 0.6 },
{ scale: 1 }
],
zoomOut: [
{ scale: 1.2 },
{ scale: 1 }
],
};
exitAnimations={
fade: [
{ alpha: 1 },
{ alpha: 0 }
],
slideDown: [
{ y: 0 },
{ y: this.slideHeight },
],
slideUp: [
{ y: 0 },
{ y: -this.slideHeight },
],
slideRight: [
{ x: 0 },
{ x: this.slideWidth },
],
slideLeft: [
{ x: 0 },
{ x: -this.slideWidth },
],
flipUp: [
{ rotateX: 0 },
{ perspective: 2500, rotateX: this.flipDistance },
],
flipDown: [
{ rotateX: 0 },
{ perspective: 2500, rotateX: -this.flipDistance },
],
flipLeft: [
{ rotateY: 0 },
{ perspective: 2500, rotateY: this.flipDistance },
],
flipRight: [
{ rotateY: 0 },
{ perspective: 2500, rotateY: -this.flipDistance },
],
zoomOut: [
{ scale: 1 },
{ scale: 0.6 },
],
zoomIn: [
{ scale: 1 },
{ scale: 1.2 },
],
};
defaultOptions={
animation_type: null,
duration: { number: 500, unit: 'ms', style: '500ms' },
delay: { number: 0, unit: 'ms', style: '0ms' },
ease: 'power1.out',
};
initialized=false;
constructor(element, wrapper, options, isExitAnimation=false){
this.element=element;
this.wrapper=wrapper;
this.options=mergeObjects(this.defaultOptions, options);
this.isExitAnimation=isExitAnimation;
this.init();
}
getDuration(value){
if(!value) return value;
if(value.unit==='s') return value.number;
return value.number / 1000;
}
createTween(){
const type=this.options.animation_type;
const animations=this.isExitAnimation ? this.exitAnimations:this.entranceAnimations;
if(!animations[type]){
console.log(`[POPUP] The selected ${type} animation is invalid.`);
return;
}
const [from, to]=animations[type];
const ease=this.options.ease;
const duration=this.getDuration(this.options.duration);
const delay=this.getDuration(this.options.delay);
const anim=gsap.timeline({
paused: true
});
anim.fromTo(this.wrapper, {
alpha: this.isExitAnimation ? 1:0
}, {
alpha: this.isExitAnimation ? 0:1,
duration,
delay,
}, 0);
anim.fromTo(this.element, {
...from,
autoAlpha: this.isExitAnimation ? 1:0
},
{
...to,
autoAlpha: this.isExitAnimation ? 0:1,
duration,
delay,
ease,
clearProps: 'all',
onStart: ()=> {
this.wrapper.classList.add(this.animatingClass);
},
onComplete: ()=> {
this.wrapper.classList.remove(this.animatingClass);
if(this.isExitAnimation){
this.wrapper.classList.remove(this.completedClass);
}else{
this.wrapper.classList.add(this.completedClass);
}}
}, 0);
return anim;
}
play(){
if(!this.tween) return;
return this.tween.progress(0).play();
}
initTween(){
if(this.initialized) return;
this.initialized=true;
this.element.classList.remove(this.completedClass);
this.tween=this.createTween();
}
destroy(){
this.initialized=false;
if(!this.element) return;
this.element.classList.add(this.completedClass);
if(!this.tween) return;
this.tween.kill();
this.tween=null;
gsap.set(this.element, { clearProps: 'all' });
}
init(){
if(!this.options.animation_type) return;
if(prefersReducedMotion()){
console.log('[POPUP] Not playing animations. "Prefers Reduced Motion" is enabled.')
this.wrapper.classList.add(this.completedClass);
return;
}
this.initTween();
}}
window.BreakdancePopupAnimation=BreakdancePopupAnimation;
}());