PageSourceSearch

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

js accademiamoda.it collected 2026-10-04 13:23:58 UTC 4,736 bytes, 131 lines download raw bytes

1/**
2 * Portfolio Home Mobile - Scroll Animation
3 * Titolo verticale, portfolio card che salgono dal basso e si sovrappongono
4 */
5(function() {
6    'use strict';
7
8    document.addEventListener('DOMContentLoaded', () => {
9        const portfolioBlock = document.querySelector('.portfolio-home-mobile');
10        
11        if (!portfolioBlock) return;
12        
13        // Verifica che l'elemento sia visibile (non nascosto da display:none)
14        const isVisible = window.getComputedStyle(portfolioBlock).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(portfolioBlock).display !== 'none';
19                if (checkVisible) {
20                    initPortfolioHomeMobileAnimation();
21                } else {
22                    setTimeout(checkVisibility, 100);
23                }
24            };
25            checkVisibility();
26            return;
27        }
28
29        initPortfolioHomeMobileAnimation();
30    });
31    
32    function initPortfolioHomeMobileAnimation() {
33        const portfolioBlock = document.querySelector('.portfolio-home-mobile');
34        if (!portfolioBlock) return;
35        
36        // Verifica nuovamente la visibilità prima di inizializzare
37        if (window.getComputedStyle(portfolioBlock).display === 'none') {
38            return;
39        }
40
41        const titleWrapper = portfolioBlock.querySelector('.portfolio-home-mobile__title-wrapper');
42        const cards = portfolioBlock.querySelectorAll('.portfolio-card-mobile');
43        const footer = portfolioBlock.querySelector('.portfolio-home-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        // Usa xPercent/yPercent per mantenere il centraggio CSS
56        gsap.set(titleWrapper, { 
57            xPercent: -50, // Mantiene il centramento orizzontale
58            yPercent: -50, // Mantiene il centramento verticale
59            y: 0, // Già centrato, nessun movimento
60            opacity: 1
61        });
62
63        // Tutte le card partono dal basso
64        gsap.set(cards, { 
65            y: viewportHeight,
66            opacity: 1
67        });
68
69        // Footer parte dal basso (NO FADE)
70        if (footer) {
71            gsap.set(footer, { 
72                y: 50,
73                opacity: 1 // Sempre visibile
74            });
75        }
76
77        // === ANIMAZIONE CON PIN (IDENTICO a exchange program) ===
78        // Durata calcolata: titolo + (card × numCards) + footer
79        const totalPhases = 1 + numCards + 1; // Titolo + cards + footer
80        const pinDuration = `+=${totalPhases * 100}%`;
81        
82        const mainTimeline = gsap.timeline({
83            scrollTrigger: {
84                trigger: portfolioBlock,
85                start: 'top top',
86                end: pinDuration, // Dinamico come exchange
87                pin: true,
88                scrub: 1,
89                anticipatePin: 1,
90                // markers: true, // Debug
91            }
92        });
93
94        // FASE 1: Titolo rimane fisso e centrato (non animiamo, il CSS lo centra)
95        // Manteniamo xPercent e yPercent per il centraggio, y: 0 già impostato nello stato iniziale
96
97        // Pausa minima (0-5% timeline)
98        mainTimeline.to({}, { duration: 0.05 });
99
100        // FASI 2-N: Ogni card sale singolarmente al centro (5-80% timeline) - Inizia subito
101        cards.forEach((card, index) => {
102            const startTime = 0.05 + (index * 0.12);
103            
104            // Card sale dal basso al centro (y: 0, sovrapposta)
105            mainTimeline.to(card, {
106                y: 0,
107                duration: 0.12,
108                ease: 'none',
109                onStart: () => {
110                    // Z-index crescente per sovrapposizione corretta
111                    card.style.zIndex = 10 + index;
112                }
113            }, startTime);
114        });
115
116        // FASE FINALE: Footer sale (80-100% timeline) - NO FADE
117        if (footer) {
118            const footerStartTime = 0.05 + (numCards * 0.12) + 0.03;
119            
120            mainTimeline.to(footer, {
121                y: 0, // Solo movimento, no opacity
122                duration: 0.2,
123                ease: 'none',
124            }, footerStartTime);
125        }
126
127        //console.log('Portfolio Home Mobile initialized:', numCards, 'portfolio items');
128    }
129
130})();
131

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.