PageSourceSearch

https://newt.vision/typo3temp/assets/vhs/vhs-assets-service-js.js

js newt.vision collected 2026-10-10 00:15:14 UTC 7,412 bytes, 148 lines download raw bytes

1  document.addEventListener("DOMContentLoaded", () => {
2             gsap.registerPlugin(ScrollTrigger);
3
4    // ─── FADE-IN ENTRATA ─────────────────────────────────────────────────────
5    gsap.to("#page-content", { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" });
6
7    if (document.getElementById("real-header")) {
8        gsap.to("#real-header", { opacity: 1, duration: 0.6, ease: "power2.out", delay: 0.2 });
9    } else if (document.getElementById("real-header-logo")) {
10        gsap.to(["#real-header-logo", "#menu-toggle"], { opacity: 1, duration: 0.6, ease: "power2.out", delay: 0.2 });
11    }
12
13    // ─── SCROLL REVEAL ───────────────────────────────────────────────────────
14    gsap.utils.toArray(".reveal-text").forEach(el => {
15        gsap.from(el, {
16            scrollTrigger: { trigger: el, start: "top 85%", toggleActions: "play none none reverse" },
17            y: 30, opacity: 0, duration: 0.8, ease: "power2.out"
18        });
19    });
20
21    // ─── HAMBURGER MENU ──────────────────────────────────────────────────────
22    const menuToggle = document.getElementById("menu-toggle");
23    if (!menuToggle) return;
24
25    const line1 = menuToggle.querySelector(".line-1");
26    const line2 = menuToggle.querySelector(".line-2");
27
28    // Stato iniziale: menu fuori schermo a destra, invisibile
29    gsap.set("#fullscreen-menu", { xPercent: 100, autoAlpha: 0 });
30
31    const menuTl = gsap.timeline({ paused: true, reversed: true })
32        .set("#fullscreen-menu", { autoAlpha: 1, pointerEvents: "auto" })
33        .to("#fullscreen-menu",  { xPercent: 0, duration: 0.7, ease: "power4.inOut" })
34        .to(".menu-link",        { y: "0%", duration: 0.5, stagger: 0.1, ease: "power3.out" }, "-=0.3")
35        .to(".menu-info",        { opacity: 1, x: 0, duration: 0.5, stagger: 0.1, ease: "power3.out" }, "-=0.4");
36
37    function closeMenu() {
38        menuToggle.classList.remove("active");
39        document.body.style.overflow = "auto";
40        gsap.to(line1, { top: 14, rotate: 0,  duration: 0.4, ease: "back.out(1.5)" });
41        gsap.to(line2, { top: 26, rotate: 0,  duration: 0.4, ease: "back.out(1.5)", width: "2rem", backgroundColor: "#ffffff" });
42        menuTl.timeScale(1.5).reverse();
43    }
44
45    menuToggle.addEventListener("click", () => {
46        menuToggle.classList.toggle("active");
47        if (menuToggle.classList.contains("active")) {
48            document.body.style.overflow = "hidden";
49            gsap.to(line1, { top: 20, rotate:  45, duration: 0.4, ease: "back.out(1.5)" });
50            gsap.to(line2, { top: 20, rotate: -45, duration: 0.4, ease: "back.out(1.5)", width: "2rem", backgroundColor: "#8eb353" });
51            menuTl.timeScale(1).play();
52        } else {
53            closeMenu();
54        }
55    });
56
57    document.querySelectorAll(".menu-link").forEach(link => {
58        link.addEventListener("click", () => { if (menuToggle.classList.contains("active")) closeMenu(); });
59    });
60
61
62            // ANIMAZIONE ALLO SCROLL DEI BLOCCHI
63            gsap.utils.toArray('.reveal-block').forEach(block => {
64                gsap.from(block, {
65                    scrollTrigger: {
66                        trigger: block,
67                        start: "top 85%",
68                        toggleActions: "play none none reverse"
69                    },
70                    y: 40,
71                    opacity: 0,
72                    duration: 0.8,
73                    ease: "power2.out"
74                });
75            });
76
77            // ─── PANEL REVEAL (stile megacard, ma allo scroll invece che al load) ─────
78            gsap.utils.toArray('.panel-reveal').forEach(panel => {
79                gsap.from(panel, {
80                    scrollTrigger: { trigger: panel, start: "top 90%", toggleActions: "play none none reverse" },
81                    y: 100, opacity: 0, duration: 1, ease: "power3.out"
82                });
83            });
84
85            // TECH SPECS DAI CONTENUTI TYPO3
86            // L'elenco puntato nel testo del servizio viene spostato nel pannello "Tech Specs".
87            // Se il servizio non ha un elenco, pulsante e pannello vengono rimossi.
88            document.querySelectorAll('.nv-service').forEach(card => {
89                const list = card.querySelector('.service-body ul');
90                const specs = card.querySelector('.service-specs');
91                if (!list || !specs) {
92                    card.querySelector('.service-trigger')?.remove();
93                    card.querySelector('.service-content')?.remove();
94                    return;
95                }
96                list.className = 'space-y-4 font-mono text-xs text-gray-400';
97                list.querySelectorAll('li').forEach(li => {
98                    li.classList.add('flex', 'gap-4');
99                    const marker = document.createElement('span');
100                    marker.className = 'text-newtgreen';
101                    marker.textContent = '>';
102                    li.prepend(marker);
103                });
104                specs.appendChild(list);
105            });
106
107            // MOTORE ESPANSIONE SERVIZI (Accordion GSAP)
108            const serviceTriggers = document.querySelectorAll('.service-trigger');
109            
110            serviceTriggers.forEach(trigger => {
111                let isOpen = false;
112                const content = trigger.nextElementSibling;
113                const icon = trigger.querySelector('.trigger-icon svg');
114
115                trigger.addEventListener('click', () => {
116                    isOpen = !isOpen;
117                    
118                    if (isOpen) {
119                        // Ruota l'icona a 45 gradi (X) e colora il bottone
120                        gsap.to(icon, { rotation: 45, duration: 0.3, ease: "back.out(1.5)" });
121                        trigger.querySelector('.trigger-icon').classList.add('border-newtgreen', 'text-newtgreen');
122                        trigger.querySelector('.trigger-icon').classList.remove('border-white/20', 'text-white');
123                        
124                        // Srotola il contenuto
125                        gsap.to(content, { 
126                            height: "auto", 
127                            opacity: 1, 
128                            duration: 0.5, 
129                            ease: "power2.out" 
130                        });
131                    } else {
132                        // Riporta l'icona a 0 gradi (+)
133                        gsap.to(icon, { rotation: 0, duration: 0.3, ease: "power2.inOut" });
134                        trigger.querySelector('.trigger-icon').classList.remove('border-newtgreen', 'text-newtgreen');
135                        trigger.querySelector('.trigger-icon').classList.add('border-white/20', 'text-white');
136                        
137                        // Richiudi il contenuto
138                        gsap.to(content, { 
139                            height: 0, 
140                            opacity: 0, 
141                            duration: 0.4, 
142                            ease: "power2.inOut" 
143                        });
144                    }
145                });
146            });
147        });
148

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.