// GSAP code by Fagan Wilcox // POPCANDI 2024 // Set initial visibility gsap.set( [ ".glass", ".glass-nav", ".logo", ".nav-menu-wrapper", ".socials", ".main-heading", ".subheading", ".btn-hm", ], { visibility: "visible" } ); // Ensure Webflow array exists window.Webflow = window.Webflow || []; window.Webflow.push(() => { gsap.registerPlugin(ScrollTrigger); }); let mm = gsap.matchMedia(); // Select all '.cell-c' elements const cells = document.querySelectorAll(".cell-c"); // Create a function to handle the hover animation function createHoverAnimation(cell) { const image = cell.querySelector(".p-image"); // Create the hover animation timeline const tl = gsap.timeline({ paused: true }); tl.to(image, { scale: 1.1, duration: 2, ease: "ease.inOut", }); // Add event listeners for mouseenter and mouseleave cell.addEventListener("mouseenter", () => tl.play()); cell.addEventListener("mouseleave", () => tl.reverse()); } // Apply the hover animation to each '.cell-c' element cells.forEach(createHoverAnimation); // Glass border color animation // gsap.to(".btn-hm", { // duration: 8, // boxShadow: [ // "0 0 10px rgba(255, 255, 255, 0.1)", // "0 0 20px rgba(200, 200, 200, 0.3)", // "0 0 30px rgba(150, 150, 150, 0.5)", // "0 0 20px rgba(200, 200, 200, 0.3)", // "0 0 10px rgba(255, 255, 255, 0.1)", // ], // ease: "none", // repeat: -1, // yoyo: true, // }); // gsap.to(".glass, .email-footer-form", { // duration: 5, // boxShadow: [ // "0 0 10px rgba(255, 255, 255, 0.1)", // "0 0 20px rgba(200, 200, 200, 0.3)", // "0 0 30px rgba(150, 150, 150, 0.5)", // "0 0 20px rgba(200, 200, 200, 0.3)", // "0 0 10px rgba(255, 255, 255, 0.1)", // ], // ease: "none", // repeat: -1, // yoyo: true, // }); // Above the fold animations const elements = [ // { selector: ".logo", delay: 2, y: -100 }, // { selector: ".nav-menu-wrapper", delay: 2.2, y: -100 }, // { selector: ".socials", delay: 2.4, y: -100 }, // { selector: ".main-heading", delay: 2.6, y: -100 }, // { selector: ".subheading", delay: 2.8, y: -50 }, // { selector: ".btn-hm", delay: 3, y: 0 }, // { selector: ".glass", delay: 2.6, y: -100, stagger: 0.3 }, // { selector: ".glass-nav", delay: 5, y: 0, duration: 3 }, ]; elements.forEach(({ selector, delay, y, stagger, duration = 1 }) => { gsap.from(selector, { y, duration, opacity: 0, delay, stagger, }); }); // Scroll triggers // gsap.from(".cellc", { // y: -180, // duration: 1, // stagger: 0.3, // scrollTrigger: { // trigger: "#product", // start: "top 75%", // toggleActions: "play none none none", // }, // }); // Fade In animations const fadeInElements = gsap.utils.toArray("[fade-in]"); fadeInElements.forEach((element) => { gsap.fromTo( element, { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 0.5, scrollTrigger: { trigger: element, start: "top 60%", end: "bottom 50%", }, } ); }); // Fade in list animations const fadeInLists = gsap.utils.toArray("[fade-list]"); fadeInLists.forEach((list) => { gsap.fromTo( list.children, { opacity: 0, y: 50 }, { opacity: 1, y: 0, duration: 0.5, stagger: 0.5, scrollTrigger: { trigger: list, start: "top 80%", end: "bottom 50%", }, } ); }); // Refresh ScrollTrigger setTimeout(() => { ScrollTrigger.refresh(true); console.log("Scroll Trigger has been refreshed"); }, 1500); // Scroll number animation gsap.to("#section2", { scrollTrigger: { trigger: "#section2", onEnter: () => { const counterConfig = { start: 0, duration: 2, delay: 10, once: true, repeat: false, decimals: 0, legacy: true, }; new PureCounter({ ...counterConfig, selector: "#numS", end: 380 }); new PureCounter({ ...counterConfig, selector: "#numC", end: 35 }); new PureCounter({ ...counterConfig, selector: "#numP", end: 29 }); new PureCounter({ ...counterConfig, selector: "#numX", end: 450 }); }, }, }); // Scroll number animation gsap.to("#section2", { scrollTrigger: { trigger: "#section2", onEnter: () => { const counterConfig = { start: 0, duration: 2, delay: 10, once: true, repeat: false, decimals: 0, legacy: true, }; new PureCounter({ ...counterConfig, selector: "#fig1", end: 100 }); new PureCounter({ ...counterConfig, selector: "#fig2", end: 30 }); new PureCounter({ ...counterConfig, selector: "#fig3", end: 30 }); new PureCounter({ ...counterConfig, selector: "#fig4", end: 10 }); }, }, }); // Scroll to top functionality document.getElementById("scroll-top").addEventListener("click", () => { window.scrollTo({ top: 0, behavior: "smooth", }); }); // Set custom background color document.addEventListener("DOMContentLoaded", () => { const element = document.querySelector("[data-custom-bg]"); if (element) { element.style.backgroundColor = element.getAttribute("data-custom-bg"); } }); document.addEventListener("DOMContentLoaded", function () { gsap.to(".img-sym", { y: "+=20", // Moves 20px down (positive value) duration: 5, // 5-second duration ease: "power1.inOut", // Smooth easing for a natural float repeat: -1, // Infinite repeat yoyo: true, // Reverses the animation back up yoyoEase: true, // Ensures smooth reversing x: "+=10", // Optional: slight horizontal movement to enhance the floating effect repeatRefresh: true, // Generates random values on each repeat }); }); //tab click document.addEventListener("DOMContentLoaded", function () { // Function to animate region items within the active tab function animateRegionList(regionList) { gsap.fromTo( regionList.querySelectorAll(".region-item"), { opacity: 0, y: 20, // Start 20px below the final position }, { opacity: 1, y: 0, duration: 0.6, // Duration of each item's animation stagger: 0.1, // Time between the start of each item's animation ease: "power2.out", } ); } // Listen for clicks on tab links document.querySelectorAll(".tab-link").forEach((tabLink) => { tabLink.addEventListener("click", function () { // Use a small delay to ensure the active class has been applied setTimeout(() => { // Find the active tab pane const activePane = document.querySelector(".tab-pane.w--tab-active"); if (activePane) { const regionList = activePane.querySelector(".region-list"); if (regionList) { animateRegionList(regionList); } } }, 50); }); }); // Optionally, animate the initial active tab's region list on page load const initialActivePane = document.querySelector(".tab-pane.w--tab-active"); if (initialActivePane) { const regionList = initialActivePane.querySelector(".region-list"); if (regionList) { animateRegionList(regionList); } } }); //check viewport size // // Create a container for the viewport size display // const sizeDisplay = document.createElement("div"); // sizeDisplay.id = "viewport-size-display"; // sizeDisplay.style.cssText = ` // position: fixed; // bottom: 10px; // left: 10px; // background-color: rgba(0, 0, 0, 0.7); // color: white; // padding: 5px 10px; // border-radius: 5px; // font-family: Arial, sans-serif; // font-size: 14px; // z-index: 9999; // `; // // // Function to update the viewport size display // function updateSizeDisplay() { // const width = window.innerWidth; // const height = window.innerHeight; // sizeDisplay.textContent = `Viewport: ${width}px × ${height}px`; // } // updateSizeDisplay(); // document.body.appendChild(sizeDisplay); // window.addEventListener("resize", updateSizeDisplay); //hero image scale animation // Make sure to include the GSAP library in your HTML file // // Wait for the DOM to be fully loaded document.addEventListener("DOMContentLoaded", () => { // Select the image element const heroImage = document.querySelector(".hero-img-wrapper .hero"); // Check if the element exists if (heroImage) { // Set the initial scale to 1 (full size) gsap.set(heroImage, { scale: 1 }); // Animate the image gsap.to(heroImage, { duration: 10, // Animation duration in seconds scale: 1.1, // Final scale (20% larger) ease: "power1.inOut", // Smooth easing for a gradual scale delay: 0.5, // Slight delay before the animation starts }); } else { console.error("Hero image not found. Check your HTML structure."); } }); // Make sure to include the GSAP and ScrollTrigger plugin in your project gsap.registerPlugin(ScrollTrigger); // Select all elements with the class 'cell-c' const products = gsap.utils.toArray(".p-wrapper"); // Create the animation gsap.from(products, { opacity: 0, y: 50, // Optional: adds a slight vertical movement stagger: 0.2, // Adjust this value to control the delay between each element's animation duration: 1, ease: "power2.out", scrollTrigger: { trigger: products, start: "top 80%", // Adjust this to change when the animation starts end: "bottom 20%", // Adjust this to change when the animation ends toggleActions: "play none none reverse", }, }); // Wait for the DOM to be fully loaded document.addEventListener("DOMContentLoaded", () => { // Get the element with the custom attribute for theming const themeElement = document.querySelector("[data-theme-animate]"); // Get the hero image const heroImage = document.querySelector(".hero"); // Function to animate theme change const animateTheme = () => { gsap.to(themeElement, { duration: 3, attr: { "element-theme": "2" }, ease: "power1.out", onUpdate: () => { // Force a style recalculation to ensure smooth transition themeElement.style.cssText = themeElement.style.cssText; }, }); }; }); // Make sure GSAP is loaded if (typeof gsap !== "undefined") { // Select all dropdown elements const dropdowns = document.querySelectorAll(".dropdown"); dropdowns.forEach((dropdown) => { // Find the dropdown list and links within each dropdown const dropdownList = dropdown.querySelector(".dropdown-nav-list"); const dropdownLinks = dropdown.querySelectorAll(".dropdown-link"); // Set initial state for dropdown links (hidden) gsap.set(dropdownLinks, { opacity: 0, y: 20 }); // Create a timeline for the dropdown animation const dropdownTl = gsap.timeline({ paused: true }); // Add the stagger animation to the timeline dropdownTl.to(dropdownLinks, { opacity: 1, y: 0, duration: 0.5, stagger: 0.01, ease: "power2.out", }); // Play dropdown animation on mouseenter dropdown.addEventListener("mouseenter", () => { dropdownTl.play(); }); // Reverse dropdown animation on mouseleave dropdown.addEventListener("mouseleave", () => { dropdownTl.reverse(); }); // Add hover effect to individual dropdown links dropdownLinks.forEach((link) => { // Create a timeline for the hover animation const hoverTl = gsap.timeline({ paused: true }); // Add the hover animation to the timeline hoverTl.to(link, { x: 5, duration: 0.3, ease: "power2.out", }); // Play hover animation on mouseenter link.addEventListener("mouseenter", () => { hoverTl.play(); }); // Reverse hover animation on mouseleave link.addEventListener("mouseleave", () => { hoverTl.reverse(); }); }); }); }