PageSourceSearch

https://symfony.com/assets/twenty_years/init-0isE53W.js

js symfony.com collected 2026-09-24 06:40:18 UTC 3,628 bytes, 125 lines download raw bytes

1import { gsap } from 'gsap';
2import { ScrollToPlugin } from 'gsap/dist/ScrollToPlugin.min.js';
3import { ScrollTrigger } from 'gsap/dist/ScrollTrigger.min.js';
4
5import { setupConfettiOnClick } from './confettis-effect.js';
6import { createBoxes, setupBoxesTimeline } from './scroll-boxes.js';
7import { setupSectionsAnimations } from './scroll-sections.js';
8import {
9    goToNextSection,
10    goToPreviousSection,
11    scrollToTarget,
12    setupTimelineActions,
13    setupTimelineScroll,
14} from './scroll-timeline.js';
15
16// Register GSAP plugins.
17gsap.registerPlugin(ScrollTrigger, ScrollToPlugin);
18
19/**
20 * Initializes page animations and interactions.
21 */
22async function initializePage() {
23    createBoxes();
24    await setupBoxesTimeline();
25    setupSectionsAnimations();
26    setupTimelineScroll();
27    setupTimelineActions();
28    setupConfettiOnClick();
29
30    // Navigation elements.
31    const logo = document.querySelector('.top-logo');
32    const scrollButton = document.querySelector('.scroll-button');
33    const firstSection = document.querySelector('.section');
34    const targetScrollSection = document.querySelectorAll('.section')[2];
35
36    // Handle click events for scrolling.
37    if (logo) {
38        logo.addEventListener('click', (e) => {
39            e.stopImmediatePropagation();
40            e.preventDefault();
41            scrollToTarget(firstSection);
42        });
43    } else {
44        console.warn("Element '.top-logo' not found.");
45    }
46
47    if (scrollButton) {
48        scrollButton.addEventListener('click', () => scrollToTarget(targetScrollSection, 1));
49    } else {
50        console.warn("Element '.scroll-button' not found.");
51    }
52
53    // Logo animation based on first section scroll.
54    gsap.set(logo, { opacity: 0, y: -10, pointerEvents: 'none' });
55
56    const logoAppearAnimation = gsap.to(logo, {
57        opacity: 1,
58        y: 0,
59        pointerEvents: 'auto',
60        duration: 0.3,
61        ease: 'power1.out',
62        paused: true,
63        reversed: true,
64    });
65
66    ScrollTrigger.create({
67        trigger: '#section1',
68        start: 'bottom center',
69        onEnter: () => {
70            logoAppearAnimation.play();
71        },
72        onLeaveBack: () => {
73            logoAppearAnimation.reverse();
74        },
75    });
76
77    ScrollTrigger.create({
78        trigger: '#final',
79        start: 'top center',
80        end: 'top-=10% center',
81        onEnter: () => {
82            logoAppearAnimation.reverse();
83        },
84        onLeaveBack: () => {
85            logoAppearAnimation.play();
86        },
87    });
88}
89
90/**
91 * Handles window resizing.
92 */
93function handleWindowResize() {
94    clearTimeout(window.__resizeTimeout);
95
96    window.__resizeTimeout = setTimeout(() => {
97        // Kill existing ScrollTriggers.
98        ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
99
100        // Remove 'box' elements.
101        document.querySelectorAll('[class*="box"]').forEach((element) => element.remove());
102
103        // Recreate and reconfigure components.
104        createBoxes();
105        setupBoxesTimeline();
106        setupSectionsAnimations();
107        setupTimelineScroll();
108
109        ScrollTrigger.refresh();
110    }, 250);
111}
112
113// --- Global Event Listeners ---
114window.addEventListener('DOMContentLoaded', async () => await initializePage());
115window.addEventListener('resize', handleWindowResize);
116
117window.addEventListener('keydown', (e) => {
118    if (e.code === 'ArrowDown' || (e.code === 'Space' && !e.shiftKey)) {
119        e.preventDefault();
120        goToNextSection();
121    } else if (e.code === 'ArrowUp' || (e.code === 'Space' && e.shiftKey)) {
122        e.preventDefault();
123        goToPreviousSection();
124    }
125});

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.