gsap.registerPlugin(Flip, ScrollTrigger, SplitText, ScrollToPlugin); window.Webflow ||= []; window.Webflow.push(() => { //--------------------Define base options----------------------- //------------------------------------------------------------- // SETUP RESIZE let isDesktop = window.innerWidth > 992; let resizeTimer; ScrollTrigger.defaults({ markers: false /*{ startColor: "green", endColor: "red" }*/, scrub: isDesktop ? 1 : 0.8, anticipatePin: true, invalidateOnRefresh: true, }); const BASIC_PIN = { start: "top top", end: "200% top", pin: true, anticipatePin: 1, invalidateOnRefresh: true, }; const ST_BOTTOM_PIN = { start: "top top", end: "bottom top", pin: true, invalidateOnRefresh: true, }; const underlineProp = { "--underline-width": "0%", duration: 0.6, }; const textSlidePropFrom = { autoAlpha: 0, xPercent: -20, }; const textSlidePropTo = { autoAlpha: 1, xPercent: 0, stagger: 0.2, duration: 0.5, ease: "power1.out", }; //--------------------Helper function----------------------- //---------------------------------------------------------- function charDrop(x, delay, timeline) { const split = SplitText.create(x, { type: "words, chars" }); gsap.set(split.chars, { transformOrigin: "0 50%", y: -50, scale: 0.8, rotateX: 50, perspective: 200, autoAlpha: 0, }); const anim = { duration: 0.4, y: 0, scale: 1, rotateX: 0, autoAlpha: 1, ease: "power1.out", stagger: 0.05, }; timeline ? timeline.to(split.chars, anim, delay ? delay : "<") : gsap.to(split.chars, anim, delay ? delay : "<"); } function darkBg() { gsap.to(".body-landing-page", { backgroundColor: "#111" }, "<"); gsap.to(".text-animation-wrapper", { color: "white" }, "<"); //$(".body-landing-page").addClass("dark-bg"); } function lightBg() { gsap.to(".body-landing-page", { backgroundColor: "white" }, "<"); gsap.to(".text-animation-wrapper", { color: "#111" }, "<"); } //---------------------Hero section--------------------- //------------------------------------------------------ gsap.to(".init-hide", { autoAlpha: 1, duraton: 0, }); gsap.from(".htty-landing-page-h1", { x: -50, autoAlpha: 0, delay: 1.5, }); gsap.set(".landing-page-intro-section", { marginTop: isDesktop ? "-100vh" : "2rem", }); charDrop(".hero-text-anim-char", ">0.5", false); gsap.from( ".lp-hero-scroll-down-arrow", { autoAlpha: 0, duration: 0.35 }, ">" ); const heroPin = gsap.timeline({ scrollTrigger: { trigger: isDesktop ? ".htty-lp-hero-wrapper" : ".landing-page-hero-video-section", pin: true, id: "heroWrapper", start: "top top", end: isDesktop ? "200% top" : "center top", onEnter: lightNav, onEnterBack: lightNav, }, }); if (!isDesktop) { //ScrollTrigger.normalizeScroll(true); heroPin .to(".landing-page-hero-video-section", { padding: "0px 10px 80px", }) .to(".htty-background-video", { borderRadius: "0px 0px 40px 40px" }, "<"); } $(".lp-hero-scroll-down-arrow").click(() => { gsap.to(window, { duration: 0.3, scrollTo: { y: ".landing-page-intro-section", offsetY: -350, }, }); }); //----------------Video flip between sections---------------- //----------------------------------------------------------- // SETUP ELEMENTS let $zoneEl = $("[js-scrollflip-element='zone']"), $targetEl = $("[js-scrollflip-element='target']").first(); // SETUP TIMELINE function doFlip() { return new Promise((resolve) => { gsap.set(".htty-hero-video-overlay-text-wrapper", { autoAlpha: 0, }); const initState = Flip.getState($targetEl[0]); $zoneEl.last().append($targetEl); Flip.from(initState, { duration: 0.6, ease: "none", absolute: true, onComplete: resolve, }); darkNav(); }); } function reverseFlip() { return new Promise((resolve) => { const endState = Flip.getState($targetEl[0]); $zoneEl.first().append($targetEl); Flip.from(endState, { duration: 0.6, ease: "none", onComplete: resolve, }); gsap.set(".htty-hero-video-overlay-text-wrapper", { autoAlpha: 1, }); lightNav(); }); } //----------------text fades in line by line---------------- //------------------------------------------------------------ ScrollTrigger.create({ trigger: ".landing-page-intro-section", pin: isDesktop ? false : true, start: "top top", end: "bottom top", }); const $textAnimLine = $(".text-animation-wrapper div"); const textAnimTl = gsap.timeline({ scrollTrigger: { trigger: ".landing-page-intro-section", start: isDesktop ? "top top" : "top center", end: isDesktop ? "150% top" : "center top", id: "lineBylineText", enabled: isDesktop ? false : true, onEnter: darkNav, onEnterBack: darkNav, }, }); textAnimTl.to({}, { duration: 1 }); $(".text-animation-wrapper div").each(function (i) { var $underline = $(this).find(".text-w-red-underline"); textAnimTl .from($textAnimLine[i], { autoAlpha: 0, y: -20, duration: 0.6, stagger: 1, }) .from($underline, underlineProp, ">"); }); charDrop(".landing-page-intro-section .lp-script-text", ">+1", textAnimTl); let videoFlipST; function createTimeline() { if (videoFlipST) videoFlipST.kill(); videoFlipST = gsap.timeline({ scrollTrigger: { trigger: ".landing-page-hero-video-section", start: "bottom bottom", id: "videoFlip", invalidateOnRefresh: true, onEnter: () => { doFlip().then(() => { textAnimTl.scrollTrigger.enable(); ScrollTrigger.refresh(); }); }, onLeaveBack: () => { reverseFlip().then(() => { textAnimTl.scrollTrigger.disable(); }); }, }, }); } if (isDesktop) createTimeline(); let lastIsDesktop = isDesktop; window.addEventListener("resize", () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(() => { const newIsDesktop = window.innerWidth > 992; if (newIsDesktop !== lastIsDesktop) { lastIsDesktop = newIsDesktop; ScrollTrigger.getAll().forEach((st) => st.kill()); ScrollTrigger.refresh(); if (newIsDesktop) createTimeline(); } }, 300); }); //----------------Well done text---------------- //------------------------------------------------ gsap.set(".well-done-section", { backgroundColor: "transparent" }); const colorChange = gsap.timeline({ scrollTrigger: { trigger: ".well-done-section", id: "colorChange", endTrigger: ".htty-text-changing-section", end: "bottom bottom", start: "top center", onEnter: () => { darkBg(); lightNav(); }, onEnterBack: () => { darkBg(); //gsap.set(".well-done-section", { backgroundColor: "transparent" }); }, onLeave: () => { lightBg(); gsap.set(".well-done-section", { backgroundColor: "#111" }); }, onLeaveBack: () => { gsap.set(".well-done-section", { backgroundColor: "transparent" }); lightBg(); darkNav(); }, }, }); ScrollTrigger.create({ ...BASIC_PIN, end: isDesktop ? "200% top" : "center top", id: "wellDoneText", trigger: ".well-done-section", onLeaveBack: darkNav, }); const wellDoneTexAnim = gsap.timeline({ scrollTrigger: { trigger: ".well-done-section .text-drop-in", start: "top center", endTrigger: ".well-done-section", end: isDesktop ? "150% top" : "center top", }, }); gsap.set(".well-done-text", { autoAlpha: 0, yPercent: 100 }); wellDoneTexAnim .from(".well-done-section .text-drop-in", { autoAlpha: 0, yPercent: -100, ease: "power1.out", }) .from(".well-done-section .text-w-red-underline", underlineProp, ">+0.5") .to( ".well-done-text", { autoAlpha: 1, yPercent: 0, ease: "power2.out", }, ">+0.5" ); //----------------spinnning text---------------- //------------------------------------------------ const texts = $(".changing-text"); const count = texts.length; gsap.set(texts, { autoAlpha: 0 }); const spinningTextTl = gsap.timeline({ scrollTrigger: { ...BASIC_PIN, end: isDesktop ? "200% top" : "center top", trigger: ".htty-text-changing-section", id: "spinningText", //onEnter: () => spinLoopTl.play(), //onEnterBack: () => spinLoopTl.play(), }, }); const spinLoopTl = gsap.timeline({ repeat: -1, // infinite loop paused: true, }); const shuffleImages = gsap.utils.toArray(".lp-bg-shuffle-image"); /*const imageTl = gsap.timeline({ repeat: -1, paused: true, }); imageTl.to({}, { duration: 2 }); shuffleImages .slice() .reverse() .forEach((img, i) => { imageTl .to(shuffleImages, { autoAlpha: 0, duration: 0.5 }) // hide all .to(img, { autoAlpha: 1, duration: 0.5 }, "<") // show one .to({}, { duration: 3 }); // stay visible }); */ texts.each((i, el) => { spinLoopTl .to(el, { autoAlpha: 1, yPercent: 0 }) .to({}, { duration: 1 }) .to(el, { yPercent: -100, autoAlpha: 0, duration: 0.3, ease: "power1.out", }) .set(el, { autoAlpha: 0, yPercent: 50 }); }); spinningTextTl .from("#spinning-text-wrapper", { autoAlpha: 0, yPercent: -10, ease: "power1.out", }) .from( $(".htty-text-changing-section .text-w-red-underline"), { "--underline-width": "0%", duration: 0.6, onComplete: () => { spinLoopTl.play(); //imageTl.play(); }, }, ">" ) .from( ".changing-text-list-wrapper", { autoAlpha: 0, ease: "power1,out" }, ">" ) .from({}, { duration: 0.5 }); //----------------full width text anim---------------- //------------------------------------------------ ScrollTrigger.create({ ...BASIC_PIN, end: isDesktop ? "150% top" : "center top", trigger: $(".full-width-text-section")[1], }); const fullWidthTextSt = gsap.timeline({ scrollTrigger: { id: "fullWidthText", start: "bottom 90%", end: isDesktop ? "bottom top" : "center top", trigger: "#quit-for-loved-ones", onEnter: () => { spinLoopTl.pause(); //imageTl.pause(); }, onLeaveBack: () => { spinLoopTl.play(); //imageTl.play(); }, }, }); charDrop("#quit-for-loved-ones", false, fullWidthTextSt); //---------------------------parallax image----------------------------- //---------------------------------------------------------------------- //pin section ScrollTrigger.create({ ...BASIC_PIN, id: "slideRightPin", trigger: ".sliding-right-section", end: isDesktop ? "400% top" : "300% top", onEnter: darkNav, onLeaveBack: lightNav, }); const parallaxImgTl = gsap.timeline({ scrollTrigger: { trigger: ".sliding-right-section", id: "parallaImage", start: "top center", end: isDesktop ? "350% top" : "300% top", invalidateOnRefresh: true, }, }); var textSlideIn = $( ".sliding-right-section .text-slide-in, .sliding-right-section .htty-landing-page-h2" ); gsap.set(textSlideIn, textSlidePropFrom); parallaxImgTl.to( ".parallax-image-section .htty-landing-page-h2", textSlidePropTo ); $(".htty-parallax-image").each((i) => { parallaxImgTl.fromTo( $(".htty-parallax-image")[i], { yPercent: isDesktop ? 100 + i * 50 : 200 + i * 50, }, { yPercent: isDesktop ? -320 : -500, duration: 2, ease: "power1.inOut", }, "<" ); }); gsap.set(".quit-planner-section", { position: "absolute", autoAlpha: 0 }); parallaxImgTl .to(".parallax-image-section .text-slide-in", textSlidePropTo, "<0.05") .from(".parallax-image-section .text-w-red-underline", underlineProp, ">") .to( ".parallax-image-section .landing-page-half-width-text-wrapper", { autoAlpha: 0, xPercent: 20 }, ">0.5" ) .to(".htty-parallax-image", { autoAlpha: 0 }, "<") .to(".quit-planner-section", { autoAlpha: 1, duration: 0 }, "<") .from(".image-parallax-subtle", { yPercent: 120 }, "<") .to(".quit-planner-section .text-slide-in", textSlidePropTo, "<0.3") .to({}, { duration: 0.25 }); //----------------CTA section---------------- //------------------------------------------- ScrollTrigger.create({ trigger: ".htty-quit-planner-dark-section", start: "top top", pin: true, end: isDesktop ? "200% top" : "center top", onEnter: lightNav, onLeaveBack: darkNav, }); gsap.set(".htty-quit-planner-dark-section .text-drop-in", { autoAlpha: 0, yPercent: -100, }); const ctaTl = gsap.timeline({ scrollTrigger: { trigger: ".htty-quit-planner-dark-section .text-drop-in", start: "top 55%", endTrigger: ".htty-quit-planner-dark-section", end: isDesktop ? "150% top" : "center top", }, }); ctaTl.to( ".htty-quit-planner-dark-section .text-drop-in", { autoAlpha: 1, yPercent: 0, ease: "power1.out", stagger: 0.5, }, "<" ); charDrop(".text-drop-in .lp-script-text", false, ctaTl); //----------------Nav change colour---------------- //------------------------------------------------- function darkNav() { gsap.to(".header-nav-logo.white", { autoAlpha: 0, duration: 0.25 }); gsap.to(".header-nav-logo.dark", { autoAlpha: 1, duration: 0.25 }, "<"); $(".landing-page-menu-button, .landing-page-acc").removeClass("inverted"); } function lightNav() { gsap.to(".header-nav-logo.dark", { autoAlpha: 0, duration: 0.25 }); gsap.to(".header-nav-logo.white", { autoAlpha: 1, duration: 0.25 }, "<"); $(".landing-page-menu-button, .landing-page-acc").addClass("inverted"); } //----------------progress bar---------------- //------------------------------------------------- const progress = gsap.timeline({ scrollTrigger: { trigger: ".landing-page-page-wrapper", start: "top top", end: "bottom bottom", }, }); progress.to(".lp-progress-bar-fill", { height: "100%" }); });