PageSourceSearch

https://vasaloppet.se/en/wp-content/plugins/breakdance/subplugins/…/popups@1/popup-animations.js?bd_ver=2.5.2

js vasaloppet.se collected 2026-10-02 05:50:40 UTC 6,753 bytes, 243 lines download raw bytes

1/* global gsap */
2(function () {
3    const {
4        mergeObjects,
5        prefersReducedMotion
6    } = BreakdanceFrontend.utils;
7
8    class BreakdancePopupAnimation {
9        animatingClass = 'breakdance-popup-animating';
10        completedClass = 'breakdance-popup-open';
11
12        slideWidth = 200;
13        slideHeight = 200;
14        flipDistance = 100;
15
16        entranceAnimations = {
17            fade: [
18                { alpha: 0 },
19                { alpha: 1 }
20            ],
21
22            slideUp: [
23                { y: this.slideHeight },
24                { y: 0 }
25            ],
26            slideDown: [
27                { y: -this.slideHeight },
28                { y: 0 }
29            ],
30            slideRight: [
31                { x: -this.slideWidth },
32                { x: 0 }
33            ],
34            slideLeft: [
35                { x: this.slideWidth },
36                { x: 0 }
37            ],
38
39            flipUp: [
40                { perspective: 2500, rotateX: -this.flipDistance },
41                { rotateX: 0 }
42            ],
43
44            flipDown: [
45                { perspective: 2500, rotateX: this.flipDistance },
46                { rotateX: 0 }
47            ],
48
49            flipLeft: [
50                { perspective: 2500, rotateY: -this.flipDistance },
51                { rotateY: 0 }
52            ],
53
54            flipRight: [
55                { perspective: 2500, rotateY: this.flipDistance },
56                { rotateY: 0 }
57            ],
58
59            zoomIn: [
60                { scale: 0.6 },
61                { scale: 1 }
62            ],
63            zoomOut: [
64                { scale: 1.2 },
65                { scale: 1 }
66            ],
67        };
68
69
70        exitAnimations = {
71            fade: [
72                { alpha: 1 },
73                { alpha: 0 }
74            ],
75
76            slideDown: [
77                { y: 0 },
78                { y: this.slideHeight },
79            ],
80            slideUp: [
81                { y: 0 },
82                { y: -this.slideHeight },
83            ],
84            slideRight: [
85                { x: 0 },
86                { x: this.slideWidth },
87            ],
88            slideLeft: [
89                { x: 0 },
90                { x: -this.slideWidth },
91            ],
92
93            flipUp: [
94                { rotateX: 0 },
95                { perspective: 2500, rotateX: this.flipDistance },
96            ],
97
98            flipDown: [
99                { rotateX: 0 },
100                { perspective: 2500, rotateX: -this.flipDistance },
101            ],
102
103            flipLeft: [
104                { rotateY: 0 },
105                { perspective: 2500, rotateY: this.flipDistance },
106            ],
107
108            flipRight: [
109                { rotateY: 0 },
110                { perspective: 2500, rotateY: -this.flipDistance },
111            ],
112
113            zoomOut: [
114                { scale: 1 },
115                { scale: 0.6 },
116            ],
117            zoomIn: [
118                { scale: 1 },
119                { scale: 1.2 },
120            ],
121        };
122
123        defaultOptions = {
124            animation_type: null,
125            duration: { number: 500, unit: 'ms', style: '500ms' },
126            delay: { number: 0, unit: 'ms', style: '0ms' },
127            ease: 'power1.out',
128        };
129
130        initialized = false;
131
132        constructor(element, wrapper, options, isExitAnimation = false) {
133            this.element = element;
134            this.wrapper = wrapper;
135            this.options = mergeObjects(this.defaultOptions, options);
136            this.isExitAnimation = isExitAnimation;
137
138            this.init();
139        }
140
141        getDuration(value) {
142            if (!value) return value;
143            if (value.unit === 's') return value.number;
144            return value.number / 1000; // Convert MS to S
145        }
146
147        createTween() {
148            const type = this.options.animation_type;
149            const animations = this.isExitAnimation ? this.exitAnimations : this.entranceAnimations;
150
151            if (!animations[type]) {
152                console.log(`[POPUP] The selected ${type} animation is invalid.`);
153                return;
154            }
155
156            const [from, to] = animations[type];
157            const ease = this.options.ease;
158            const duration = this.getDuration(this.options.duration);
159            const delay = this.getDuration(this.options.delay);
160
161            const anim = gsap.timeline({
162                paused: true
163            });
164
165            anim.fromTo(this.wrapper, {
166                alpha: this.isExitAnimation ? 1 : 0
167            }, {
168                alpha: this.isExitAnimation ? 0 : 1,
169                duration,
170                delay,
171            }, 0);
172
173            anim.fromTo(this.element, {
174                    ...from,
175                    autoAlpha: this.isExitAnimation ? 1 : 0
176                },
177                {
178                    ...to,
179                    autoAlpha: this.isExitAnimation ? 0 : 1,
180                    duration,
181                    delay,
182                    ease,
183                    clearProps: 'all',
184                    onStart: () => {
185                        this.wrapper.classList.add(this.animatingClass);
186                    },
187                    onComplete: () => {
188                        this.wrapper.classList.remove(this.animatingClass);
189                        if (this.isExitAnimation) {
190                            this.wrapper.classList.remove(this.completedClass);
191                        } else {
192                            this.wrapper.classList.add(this.completedClass);
193                        }
194                    }
195                }, 0);
196
197            return anim;
198        }
199
200        play() {
201            if (!this.tween) return;
202            return this.tween.progress(0).play();
203        }
204
205        initTween() {
206            if (this.initialized) return;
207            this.initialized = true;
208
209            this.element.classList.remove(this.completedClass);
210            this.tween = this.createTween();
211        }
212
213        destroy() {
214            this.initialized = false;
215
216            if (!this.element) return;
217
218            this.element.classList.add(this.completedClass);
219
220            if (!this.tween) return;
221
222            this.tween.kill();
223            this.tween = null;
224
225            // Remove all inline styles
226            gsap.set(this.element, { clearProps: 'all' });
227        }
228
229        init() {
230            if (!this.options.animation_type) return;
231
232            if (prefersReducedMotion()) {
233                console.log('[POPUP] Not playing animations. "Prefers Reduced Motion" is enabled.')
234                this.wrapper.classList.add(this.completedClass);
235                return;
236            }
237
238            this.initTween();
239        }
240    }
241
242    window.BreakdancePopupAnimation = BreakdancePopupAnimation;
243}());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.