PageSourceSearch

https://www.accademiamoda.it/wp-content/themes/iuad-theme/src/js/custom/exchange-program-mobile.js?ver=1.0.0

js accademiamoda.it collected 2026-10-04 13:23:56 UTC 4,619 bytes, 128 lines download raw bytes

1/**
2 * Exchange Program Mobile - Scroll Animation
3 * Titolo centrato, card che salgono e si sovrappongono
4 */
5(function() {
6    'use strict';
7
8    document.addEventListener('DOMContentLoaded', () => {
9        const exchangeBlock = document.querySelector('.exchange-program-mobile');
10        
11        if (!exchangeBlock) return;
12        
13        // Verifica che l'elemento sia visibile (non nascosto da display:none)
14        const isVisible = window.getComputedStyle(exchangeBlock).display !== 'none';
15        if (!isVisible) {
16            // Se non è visibile, aspetta che diventi visibile (per template responsive dinamici)
17            const checkVisibility = () => {
18                const checkVisible = window.getComputedStyle(exchangeBlock).display !== 'none';
19                if (checkVisible) {
20                    initExchangeProgramMobileAnimation();
21                } else {
22                    setTimeout(checkVisibility, 100);
23                }
24            };
25            checkVisibility();
26            return;
27        }
28
29        initExchangeProgramMobileAnimation();
30    });
31    
32    function initExchangeProgramMobileAnimation() {
33        const exchangeBlock = document.querySelector('.exchange-program-mobile');
34        if (!exchangeBlock) return;
35        
36        // Verifica nuovamente la visibilità prima di inizializzare
37        if (window.getComputedStyle(exchangeBlock).display === 'none') {
38            return;
39        }
40
41        const titleWrapper = exchangeBlock.querySelector('.exchange-program-mobile__title-wrapper');
42        const cards = exchangeBlock.querySelectorAll('.exchange-card-mobile');
43        const footer = exchangeBlock.querySelector('.exchange-program-mobile__footer');
44        
45        if (!titleWrapper || cards.length === 0) return;
46
47        // Registra ScrollTrigger plugin
48        gsap.registerPlugin(ScrollTrigger);
49
50        const viewportHeight = window.innerHeight;
51        const numCards = cards.length;
52        
53        // === STATO INIZIALE ===
54        // Titolo: posizionato direttamente nel contenitore (nessuna animazione di ingresso)
55        gsap.set(titleWrapper, { 
56            y: 0,
57            opacity: 1 // NO FADE
58        });
59
60        // Tutte le card partono dal basso, sovrapposte
61        gsap.set(cards, { 
62            y: viewportHeight,
63            opacity: 1
64        });
65
66        // Footer parte dal basso
67        if (footer) {
68            gsap.set(footer, { 
69                y: 50,
70                opacity: 1 // NO FADE
71            });
72        }
73
74        // === ANIMAZIONE CON PIN ===
75        // Durata ridotta per evitare scroll eccessivo
76        // Calcoliamo in base al numero di card ma con durata più compatta
77        const pinDuration = `+=${(numCards * 50) + 50}%`; // Ridotto da 100% a 50% per card
78        
79        const mainTimeline = gsap.timeline({
80            scrollTrigger: {
81                trigger: exchangeBlock,
82                start: 'top top',
83                end: pinDuration,
84                pin: true,
85                scrub: 1,
86                anticipatePin: 1,
87                // markers: true, // Debug
88            }
89        });
90
91        // FASE 1: Titolo rimane fisso (non animiamo, il CSS lo centra)
92        // Non aggiungiamo animazione per mantenere il centraggio verticale del CSS
93
94        // FASE 2: Pausa minima (0-2% timeline) - Ridotta per iniziare subito
95        mainTimeline.to({}, { duration: 0.02 });
96
97        // FASI 2-N: Ogni card sale singolarmente al centro (2-85% timeline) - Inizia subito
98        cards.forEach((card, index) => {
99            const startTime = 0.02 + (index * 0.08); // Ridotto spazio tra card (da 0.12 a 0.08)
100            
101            // Card sale dal basso al centro (y: 0, sovrapposta)
102            mainTimeline.to(card, {
103                y: 0,
104                duration: 0.08, // Ridotta durata (da 0.12 a 0.08) per animazione più veloce
105                ease: 'none',
106                onStart: () => {
107                    // Z-index crescente per sovrapposizione corretta
108                    card.style.zIndex = 10 + index;
109                }
110            }, startTime);
111        });
112
113        // FASE FINALE: Footer sale subito dopo l'ultima card
114        if (footer) {
115            const footerStartTime = 0.02 + (numCards * 0.08) + 0.02; // Ridotto spazio prima del footer
116            
117            mainTimeline.to(footer, {
118                y: 0,
119                duration: 0.15, // Ridotta durata footer (da 0.2 a 0.15)
120                ease: 'none',
121            }, footerStartTime);
122        }
123
124        //console.log('Exchange Program Mobile initialized:', numCards, 'cards');
125    }
126
127})();
128

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.