/** * This script observes all dropdowns with the class 'navbar_dropdown-toggle' * and the visibility of the element with class 'section_hero'. * * It performs two main actions: * 1. Disables body scrolling when any dropdown is open and re-enables it when all are closed. * 2. If the 'section_hero' is in view and a dropdown transitions from open to closed, * it programmatically clicks the element with class 'navbar_trigger'. */ (function () { // 1. Select all relevant elements from the DOM. const dropdownToggles = document.querySelectorAll('.navbar_dropdown-toggle'); const navbarTrigger = document.querySelector('.navbar_trigger'); const heroSection = document.querySelector('.section_hero'); const scrollSection = document.querySelector('.section_scroll-image'); // If no dropdowns are found, there's nothing to observe. Exit the script. if (dropdownToggles.length === 0) { console.warn( "Observer: No elements with class 'navbar_dropdown-toggle' found." ); return; } // Warn if the trigger or hero elements are missing, as part of the functionality will not work. if (!navbarTrigger) { console.warn("Observer: Element with class 'navbar_trigger' not found."); } if (!heroSection) { console.warn("Observer: Element with class 'section_hero' not found."); } if (!scrollSection) { console.warn( "Observer: Element with class 'section_scroll-image' not found." ); } // 2. State variables to track the status of dropdowns and hero section visibility. let isAnyDropdownOpen = false; let isHeroSectionInView = false; let isScrollSectionInView = false; /** * 3. This function is the core logic. It is called whenever a dropdown state changes. * It checks dropdown states, toggles body scroll, and triggers the click if conditions are met. */ const checkStateAndPerformActions = () => { // Store the state from before the change. const wasAnyDropdownOpen = isAnyDropdownOpen; // Recalculate the current state: is any dropdown open right now? const isNowOpen = Array.from(dropdownToggles).some(toggle => toggle.classList.contains('w--open') ); // Update the global state variable for the next change. isAnyDropdownOpen = isNowOpen; // --- Action 1: Scroll Lock Logic --- if (isAnyDropdownOpen) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = ''; } // --- Action 2: Trigger Click Logic --- // Condition: A dropdown must have just closed (i.e., it was open before, but is not open now). const aDropdownJustClosed = wasAnyDropdownOpen && !isAnyDropdownOpen; // If a dropdown just closed, AND the hero section is in view, AND the trigger element exists... if (aDropdownJustClosed && isHeroSectionInView && navbarTrigger) { // ...then programmatically click the navbar trigger. navbarTrigger.click(); } // If a dropdown just closed, AND the scroll section is in view, AND the trigger element exists... if (aDropdownJustClosed && isScrollSectionInView && navbarTrigger) { // ...then programmatically click the navbar trigger. navbarTrigger.click(); } }; /** * 4. Setup the MutationObserver for the dropdown toggles. * This watches for class changes (e.g., adding/removing 'w--open'). */ const dropdownObserver = new MutationObserver(checkStateAndPerformActions); const dropdownObserverConfig = { attributes: true, // Watch for attribute changes. attributeFilter: ['class'], // Specifically, only the 'class' attribute. }; // Attach the observer to each dropdown toggle element. dropdownToggles.forEach(toggle => { dropdownObserver.observe(toggle, dropdownObserverConfig); }); /** * 5. Setup the IntersectionObserver for the hero section. * This efficiently tracks if the hero section is visible in the viewport. */ if (heroSection) { const heroObserverCallback = entries => { // We are only observing one element, so we can access entries[0]. if (entries[0]) { // Update our state variable based on whether the element is intersecting the viewport. isHeroSectionInView = entries[0].isIntersecting; } }; const heroObserver = new IntersectionObserver(heroObserverCallback, { // threshold: 0 means the callback will run as soon as even a single pixel is visible. threshold: 0, }); // Start observing the hero section. heroObserver.observe(heroSection); } if (scrollSection) { const scrollObserverCallback = entries => { // We are only observing one element, so we can access entries[0]. if (entries[0]) { // Update our state variable based on whether the element is intersecting the viewport. isScrollSectionInView = entries[0].isIntersecting; } }; const scrollObserver = new IntersectionObserver(scrollObserverCallback, { // threshold: 0 means the callback will run as soon as even a single pixel is visible. threshold: 0, }); // Start observing the scroll section. scrollObserver.observe(scrollSection); } // 6. Perform an initial check when the script loads to set the initial state correctly. checkStateAndPerformActions(); })(); /** * This script animates SVG lines within containers having the class '.line-line' * when they scroll into view and resets them when they scroll out of view. * * Dependencies: * 1. GSAP Core Library (gsap.min.js) * 2. GSAP DrawSVGPlugin (DrawSVGPlugin.min.js) - This is a premium plugin. * * How it works: * - It waits for the DOM to be fully loaded. * - Registers the DrawSVGPlugin with GSAP. * - Sets the initial state of all lines to be 0% drawn (invisible). * - Uses an IntersectionObserver to track when elements enter or leave the viewport. * - When an element enters view, it animates the line to 100% drawn. * - When an element leaves view, it instantly resets the line to 0% drawn. */ document.addEventListener('DOMContentLoaded', () => { // 1. Check if GSAP and DrawSVGPlugin are available if (typeof gsap === 'undefined' || typeof DrawSVGPlugin === 'undefined') { console.error( 'GSAP or DrawSVGPlugin is not loaded. Please include the required libraries.' ); return; } // 2. Register the GSAP plugin gsap.registerPlugin(DrawSVGPlugin); // 3. Select all the elements you want to animate const lineElements = document.querySelectorAll('.line-line'); if (lineElements.length === 0) { console.warn("DrawSVG script: No elements with class '.line-line' found."); return; } // 4. Set the initial state for all lines to be hidden // This prevents them from being visible on page load before scrolling. lineElements.forEach(line => { const svgPath = line.querySelector('svg path, svg line'); if (svgPath) { gsap.set(svgPath, { drawSVG: '0%' }); } }); // 5. Set up the IntersectionObserver const observer = new IntersectionObserver( entries => { entries.forEach(entry => { const svgPath = entry.target.querySelector('svg path, svg line'); if (!svgPath) return; // Skip if no path is found inside // 6. Check if the element is entering or leaving the viewport if (entry.isIntersecting) { // Element is IN view: animate it to 100% gsap.to(svgPath, { drawSVG: '100%', duration: 2, ease: 'power2.inOut', }); } else { // Element is OUT of view: instantly reset it to 0% gsap.set(svgPath, { drawSVG: '0%', }); } }); }, { // threshold: 0.5 means the callback will trigger when 50% of the element // is visible. Adjust this value to control when the animation triggers. threshold: 0.5, } ); // 7. Attach the observer to each of the line elements lineElements.forEach(line => { observer.observe(line); }); }); /*smooth scrolling*/ // Initialize Lenis // const lenis = new Lenis(); // Use requestAnimationFrame to continuously update the scroll // function raf(time) { // lenis.raf(time); // requestAnimationFrame(raf); // } // requestAnimationFrame(raf); var reeller = new Reeller.Reeller({ container: '.marquee-wrapper', wrapper: '.company_grid-marquee', itemSelector: '.partner-card', speed: 10, }); let marqueeWrapper = document.querySelector('.marquee-wrapper'); marqueeWrapper.addEventListener('mouseenter', function () { reeller.pause(); }); marqueeWrapper.addEventListener('mouseleave', function () { reeller.resume(); });