Jump to content
Search Community

Search the Community

Showing results for 'lenis ScrollTrigger' in content posted in GSAP.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • GreenSock Forums
    • GSAP
    • Banner Animation
    • Jobs & Freelance
  • Flash / ActionScript Archive
    • GSAP (Flash)
    • Loading (Flash)
    • TransformManager (Flash)

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge

Categories

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Found 133 results

  1. Hi guys, hope you're doing well. Trying to achieve a gsap scrollTriggers animations with Lenis and using scroller proxy to avoid performance issues on the main project. Here my code : <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>HTML + CSS</title> <link rel="stylesheet" href="styles.css" /> </head> <style> html, body { height: 100%; overflow: hidden; font-family: sans-serif; } .scrollWrapper { height: 100vh; overflow: hidden; position: absolute; top: 0; } .scrollContent { height: 100%; overflow-y: scroll; -webkit-overflow-scrolling: touch; } section { width: 100vw; max-width: 100%; height: 100vh; display: flex; } section h2 { align-self: center; } </style> <body> <div class="scrollWrapper"> <div class="scrollContent"> <section><h2>My Title 0</h2></section> <section style="background: red"><h2>My Title 1</h2></section> <section style="background: blue"><h2>My Title 2</h2></section> <section><h2>My Title 3</h2></section> <section><h2>My Title 4</h2></section> <section><h2>My Title 5</h2></section> <section><h2>My Title 6</h2></section> <section><h2>My Title 7</h2></section> <section><h2>My Title 8</h2></section> <section><h2>My Title 9</h2></section> <section><h2>My Title 10</h2></section> </div> </div> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js" integrity="sha512-7eHRwcbYkK4d9g/6tD/mhkf++eoTHwpNM9woBxtPUBWm67zeAfFC+HrdoE2GanKeocly/VxeLvIqwvCdk7qScg==" crossorigin="anonymous" referrerpolicy="no-referrer" ></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js" integrity="sha512-onMTRKJBKz8M1TnqqDuGBlowlH0ohFzMXYRNebz+yOcc5TQr/zAKsthzhuv0hiyUKEiQEQXEynnXCvNTOk50dg==" crossorigin="anonymous" referrerpolicy="no-referrer" ></script> <script src="https://cdn.jsdelivr.net/npm/@studio-freight/[email protected]/dist/lenis.min.js"></script> <script> gsap.registerPlugin(ScrollTrigger); const wrapper = document.querySelector(".scrollWrapper"); const content = document.querySelector(".scrollContent"); const lenis = new Lenis({ wrapper: wrapper, content: content, duration: 2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), eventsTarget: document.documentElement, }); function raf(time) { lenis.raf(time); ScrollTrigger.update(); requestAnimationFrame(raf); } requestAnimationFrame(raf); ScrollTrigger.defaults({ scroller: wrapper }); ScrollTrigger.scrollerProxy(wrapper, { scrollTop(value) { return arguments.length ? lenis.scrollTo(value, { duration: 0, immediate: true }) : lenis.scroll; }, getBoundingClientRect() { return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight, }; }, }); const sections = gsap.utils.toArray("section"); sections.map((section, index) => { let tl = gsap.timeline({ duration: 1, scrollTrigger: { trigger: section, markers: true, scrub: true, start: "top bottom", end: "top top", }, }); tl.from(section, { opacity: 0, duration: 1 }); }); </script> </html> And here the live demo : https://codesandbox.io/p/sandbox/m87qzq?file=%2Findex.html%3A1%2C1-127%2C1, as you can see , when I open the console I see the opacity on sections moving, I also see them ( blue overlay) moving, but they dont appear on the screen. And on mobile the markers dont move, I guess I did something wrong in the setup and gsap dont refresh well, or dont detect the scroll on the right element. My goal is to use this idea to avoid using gsap.normalizeScroll and Lenis.syncTouch, these two options dont fit well with webgl background, create some delay and jitterings. So my idea was to use a scroller proxy as you see in my code, and update my webgl at the same place where I update the ScrollTrigger.update(), and lenis.raf(), I guess it's a potential good way to achieve fine and smooth animations and preserving good fps. Thanks you guys!
  2. Hi there, I'm trying to use Scrolltrigger with Lenis smooth scroll inside a Next js project. My problem is when I resize the window when it has been scrolled, the scrolltriggered animations are shifted. I've made a codesandbox reproducing my issue : here. I have setup a simple animation, triggered by the first .section, it's just moving the blue .box by 100vh. If you scroll a little bit and resize the window, the blue .box will shift vertically. It look like it's shifting proportionally to the distance scrolled. If you scroll back to the top and resize the window, the animation will get back to it's normal position. I've already setup scrollerProxy on others custom smooth scrolls, and never had this issue. The problem is hapenning on all animations in my project, on pinned scrolltriger stuff to, (the pin position is shifting by something that looks like the scrolled distance). I didn't find any ressources with a Lenis smooth scroll setup with scrollerProxy (wich is mandatory to keep perfect animations sync). Can someone see what i'm missing or doing wrong ? thanks.
  3. Hello! I started working on a project in which I'm using both Lenis (ReactLenis) and Scrolltrigger on a different, slower machine and am noticing very poor framerates on scroll (whereas on the beefier machine, the scroll animations were fluid, fast). Commenting out ReactLenis restores performance. My question is: how to make scrolltrigger and lenis play nice in React/Next. This is not really a "help me achieve outcome X" in this sandbox/codepen question, moreso a higher-level, best practices "what is the right/recommended way to do Y" question For example, in the React Lenis docs, they suggest synchronizing Lenis and GSAP like this: function Component() { const lenisRef = useRef() useEffect(() => { function update(time) { lenisRef.current?.lenis?.raf(time * 1000) } gsap.ticker.add(update) return () => { gsap.ticker.remove(update) } }) return ( <ReactLenis ref={lenisRef} autoRaf={false}> { /* content */ } </ReactLenis> ) } While in their Next.js starter, synchronization appears to be spread across two files: this more scrollTrigger specific one; and this more generic GSAP one (in the combined setup featured these two files, there is no wrapping ReactLenis element, also). So, again. Just wondering if any GSAP people have a recommended/best practice approach for doing this. As I keep seeing different patterns. Totally fine if this question is ineligible because this isn't a Lenis Q&A board, but I feel like these two tools are used together enough that someone on here might have some clarity. Thanks!
  4. Marko81

    ScrollTrigger force tween to complete

    Thank you for the reply and the suggestions for a possible solution Rodrigo. Indeed, my html element had the rule scroll-behavior: smooth. I changed that declaration to "scroll-behavior: auto !important;", but unfortunately that didn't fix the issue. I also tried the fastScrollend config option. That neither fixed the issue. I tried with values: true, 1000, 500, but without luck. I think that it may be possible, that some of my other code is affecting to my animation. For example, on the same page with this loop animation I have two additional ScrollTrigger animations. However, I don't get any console errors and the rest of my code seems to be working quite well too. I'm also using Lenis Smooth Scroll library. I tried to disable Lenis too, but that didn't fix the issue. I'll try to examine more my other ScrollTrigger animations and the rest of my js logic too. There's so much to learn for me 😄 But I'm sure I'll eventually find a solution for this.
  5. devshinthant

    Pattern(s) for synchronizing ScrollTrigger and Lenis in React/Next

    I just use like this, I don't wrap my content in ReactLenis Wrapper, cause it makes too laggy on mobile,especially on ios devices import { useLayoutEffect } from 'react' import { useLenisStore } from '@/store/lenis-store' import { useGSAP } from '@gsap/react' import gsap from 'gsap' import Flip from 'gsap/dist/Flip' import ScrollTrigger from 'gsap/dist/ScrollTrigger' import TextPlugin from 'gsap/dist/TextPlugin' import Lenis from 'lenis' /* Plugins */ gsap.registerPlugin(ScrollTrigger) gsap.registerPlugin(useGSAP) gsap.registerPlugin(Flip) gsap.registerPlugin(TextPlugin) ScrollTrigger.normalizeScroll(true) gsap.config({ force3D: true }) ScrollTrigger.config({ ignoreMobileResize: true }) export default function mountLenis() { // eslint-disable-next-line react-hooks/rules-of-hooks const lenisStore = useLenisStore((state) => state) // eslint-disable-next-line react-hooks/rules-of-hooks useLayoutEffect(() => { const lenis = new Lenis({ duration: 1.2, syncTouch: true, smoothWheel: false, }) lenisStore.setLenis(lenis) lenis.on('scroll', ScrollTrigger.update) gsap.registerPlugin(ScrollTrigger) gsap.ticker.add((time) => { lenis.raf(time * 600) }) gsap.ticker.lagSmoothing(0) return () => { ScrollTrigger.getAll().forEach((trigger) => trigger.kill()) lenis.destroy() } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return null } import { Outlet } from 'react-router-dom' import mountLenis from '@/hooks/mountLenis' import Footer from './footer' export default function Layout() { mountLenis() return ( <div className='relative overflow-x-hidden bg-[#0F0F0F]'> <Outlet /> <Footer /> </div> ) }
  6. Hi guys, I am totally newbie here, : i am building my website with several javascript and GSAp animations, they are all working fine, but I want to stop the site from scrolling until the preloader animation (or should I call it function)? finishes. so when the preloader finishes you see the hero, I even would like to prevent scrolling for a bit( a delay of 1 second or such) so user can't scroll until white bars fully go out of sight. this is the piece of code in charge of the animation. the structure of the preloader is quite simple: a parent (.preloader): width: 100vw, height: 100vh. inside 10 divs each (.bar) width: 10vw. height:100vh. And an h1 div with the class counter containing a text element, this is the number that goes up to 100. the 10 divs go up at the end of the counter animation showing the rest of the site. here is a link to the live site: https://www.notbranding.com/ I have tried adding the body overflow hidden solution but it is not working. The site is built using webflow if it is relevant. Any help is greatly appreciated, Thanks! //this is for the preloader function startLoader() { let counterElement = document.querySelector(".counter"); let currentValue = 0; function updateCounter() { if (currentValue === 100) { } currentValue += Math.floor(Math.random() * 10) + 1; if (currentValue > 100) { currentValue = 100; } counterElement.textContent = currentValue; let delay = Math.floor(Math.random() * 100) + 50; setTimeout(updateCounter, delay); } updateCounter(); } startLoader(); gsap.to(".counter", 0.25, { delay: 2.5, opacity: 0, }); gsap.to(".bar", 1.5, { //how long the bar takes to move up delay: 2.5, height: 0, stagger: { amount: 0.5, }, ease: "power4.inout", }); and here is the full code I currently have (in case something might be generating a conflict, or if you see something that could be done better). i am adding the code to weblfow using slater. // Load SplitType script if i find issues it might be the async line.not sure if this improves performance or not really. let splitTypeScript = document.createElement("script"); splitTypeScript.src = "https://unpkg.com/split-type"; splitTypeScript.async = true; splitTypeScript.onload = checkScriptsLoaded; document.body.appendChild(splitTypeScript); // Load GSAP script let gsapScript = document.createElement("script"); gsapScript.src = "https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/gsap.min.js"; gsapScript.async = true; gsapScript.onload = checkScriptsLoaded; document.body.appendChild(gsapScript); // Load ScrollTrigger script let scrollTriggerScript = document.createElement("script"); scrollTriggerScript.src = "https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/ScrollTrigger.min.js"; scrollTriggerScript.async = true; scrollTriggerScript.onload = checkScriptsLoaded; document.body.appendChild(scrollTriggerScript); // Load Lenis script let lenisScript = document.createElement("script"); lenisScript.src = "https://cdn.jsdelivr.net/gh/studio-freight/[email protected]/bundled/lenis.min.js"; lenisScript.async = true; lenisScript.onload = checkScriptsLoaded; document.body.appendChild(lenisScript); let scriptsLoaded = 0; function checkScriptsLoaded() { scriptsLoaded++; if (scriptsLoaded === 4) { // All scripts have loaded, execute the main code mainCode(); } } // Main code that depends on SplitType, GSAP, and ScrollTrigger function mainCode() { // //smooth scrolller code // let lenis = new Lenis({ lerp: 0.1, //initial value is 0.1 wheelMultiplier: 0.8, //this slows or makes the interaction faster gestureOrientation: "vertical", normalizeWheel: false, smoothTouch: false, }); function raf(time) { lenis.raf(time); requestAnimationFrame(raf); } requestAnimationFrame(raf); $("[data-lenis-start]").on("click", function () { lenis.start(); }); $("[data-lenis-stop]").on("click", function () { lenis.stop(); }); $("[data-lenis-toggle]").on("click", function () { $(this).toggleClass("stop-scroll"); if ($(this).hasClass("stop-scroll")) { lenis.stop(); } else { lenis.start(); } }); // //thisis for the preloader // function startLoader() { let counterElement = document.querySelector(".counter"); let currentValue = 0; function updateCounter() { if (currentValue === 100) { } currentValue += Math.floor(Math.random() * 10) + 1; if (currentValue > 100) { currentValue = 100; } counterElement.textContent = currentValue; let delay = Math.floor(Math.random() * 100) + 50; setTimeout(updateCounter, delay); } updateCounter(); } startLoader(); gsap.to(".counter", 0.25, { delay: 2.5, opacity: 0, }); gsap.to(".bar", 1.5, { //how long the bar takes to move up delay: 2.5, height: 0, stagger: { amount: 0.5, }, ease: "power4.inout", }); // //This is the text animations, IF IT DOESNT WORKS it is because you are applying the custom attribute: text- split and then the type of animation For example not-who-slide-up as the value and not as a second attribute, i lost 3 HS with this each time. // // split text into spans let typeSplit = new SplitType("[text-split]", { types: "lines, words, chars", tagName: "span", }); // Apply animations to each element individually document.querySelectorAll("[not-who-slide-up]").forEach(function (element) { let tl = gsap.timeline({ paused: true }); tl.from(element.querySelectorAll(".word"), { opacity: 0.0001, yPercent: 80, duration: 2, ease: "back.out(2)", stagger: { each: 0.035 } // stagger: { amount: 0.6 } //this is a different stagger option }); ScrollTrigger.create({ trigger: element, start: "top bottom", onLeaveBack: () => { tl.progress(0); tl.pause(); } }); ScrollTrigger.create({ trigger: element, start: "top 50%", markers: false, scrub: 1, onEnter: () => tl.play(), }); }); document.querySelectorAll("[not-text-slide-left]").forEach(function (element) { let tl = gsap.timeline({ paused: true }); tl.from(element.querySelectorAll(".word"), { opacity: 0.0001, xPercent: -6, duration: 2, delay: 0.5, ease: "back.out(2)", //stagger: { each: 0.035 } stagger: { amount: 0.2 } //this is a different stagger option }); ScrollTrigger.create({ trigger: element, start: "top bottom", onLeaveBack: () => { tl.progress(0); tl.pause(); } }); ScrollTrigger.create({ trigger: element, start: "top 50%", markers: false, scrub: 1, onEnter: () => tl.play(), }); }); document.querySelectorAll("[not-hero-slide-up]").forEach(function (element) { let tl = gsap.timeline({ paused: true }); tl.from(element.querySelectorAll(".char"), { opacity: 0.0001, yPercent: 100, filter: "blur(12px)", duration: 0.9, ease: "power2.inOut", stagger: { amount: 0.5, from: "start" } }); ScrollTrigger.create({ trigger: element, start: "top top", end: "bottom top", markers: false, onToggle: (self) => { if (self.isActive) { tl.play(); } else { tl.progress(0).pause(); } }, toggleActions: "play pause reset none" }); }); document.querySelectorAll("[not-sectiontitle-slide-up]").forEach(function (element) { let tl = gsap.timeline({ paused: true }); tl.from(element.querySelectorAll(".char"), { opacity: 0.0001, yPercent: 100, filter: "blur(12px)", duration: 0.9, ease: "power2.inOut", stagger: { amount: 0.5, from: "start" } }); ScrollTrigger.create({ trigger: element, start: "top bottom", onLeaveBack: () => { tl.progress(0); tl.pause(); } }); ScrollTrigger.create({ trigger: element, start: "top bottom", markers: true, scrub: 1, onEnter: () => tl.play(), }); }); // Avoid flash of unstyled content document.querySelectorAll("[text-split]").forEach(function (element) { gsap.set(element, { opacity: 1 }); }); // //THEME BUTTON OVERLAY // // Set initial position of the button outside the viewport gsap.set("#hiddenButton", { visibility: "hidden", opacity: 0, yPercent: 500, }); // Define initial animation const initialAnimation = gsap.to("#hiddenButton", { visibility: "visible", opacity: 1, filter: "blur(0px)", duration: 0.9, yPercent: 0, ease: "power2.inOut", paused: true, // Pause the animation initially }); ScrollTrigger.create({ trigger: "#triggerSection", // Corrected trigger definition start: "bottom bottom", end: "bottom", onLeave: () => { // Play initial animation when leaving the section initialAnimation.play(); // Animate the button to slide up smoothly gsap.to("#hiddenButton", { duration: 0.5, ease: "power2.inOut", }); }, onEnterBack: () => { // Reverse the initial animation when re-entering the section initialAnimation.reverse(); // Animate the button to slide down smoothly gsap.to("#hiddenButton", { duration: 0.5, ease: "power2.inOut", }); } }); //.....this is for the stacked services cards......0 // Check if the viewport width is within the specified breakpoints if (window.matchMedia("(min-width: 0px)").matches && window.matchMedia("(max-width: 479px)") .matches) { // Initialize the stacking cards animation for small breakpoints stackcards(1); } else if (window.matchMedia("(min-width: 1024px)").matches) { // Initialize the stacking cards animation for large breakpoints stackcards(1.3); } function stackcards(scaleValue) { let tl = gsap.timeline({ scrollTrigger: { trigger: '.services_main_wrap', end: 'bottom bottom', scrub: 0.3, toggleActions: 'restart none reverse', }, }); tl.from('.card_wrapper', { opacity: 100, yPercent: 350, // Adjusted for a more pronounced vertical movement scale: scaleValue, // Start from scale 0 to scale 1 for a scaling effect duration: 1.2, stagger: { each: 0.5, from: 'end' }, // Adjusted stagger for a quicker succession }); } }
  7. Hello, everyone, first of all, thanks for this great tool. Some time ago I decided to refresh my frontend dev portfolio - I thought of using gsap (almost the entire application based on scroll triggers) & next.js So i made it, but i have some doubts about the performance of my application: 1st - I did some workarounds when loading the app itself (the black descending overlay would stutter until the 3d model was loaded, but I solved this with conditional rendering until the animation finished). Now it works perfect, but sometimes its a slightly laggy (on first load). Below is important part where black overlay appears - should i make it in the other way? introTl .set([".hero", ".header"], { opacity: 1, duration: 1 }) .from(".black-overlay", { duration: 2, yPercent: -100, ease: "power2.inOut", }) return ( <section ref={heroRef} className="hero container flex w-full flex-col py-40 font-mainFont text-background opacity-0 md:h-screen lg:flex-row-reverse lg:items-end lg:py-20 dark:text-mainFontColor" > <div className="white-overlay opacity-1 absolute inset-0 z-0 bg-background dark:bg-secondBackground"></div> 2nd - The biggest problem i have, is in ABOUT section, or, more precisely, on several sections connected as pinning sections. I wanted to achieve an effect like the one you can see - Pinning the Stack section (component TECH) >> the ABOUT section enters Tech >> from under the ABOUT section , the CONTACT section appears. So that is how it is in practice - and that was the intention. However, it works...terrible - on mobile phones it slows down a lot, and during fast scrolling, regardless of whether it is a desktop or smartphone, the ABOUT section appears with an annoying skip/jumps (yeah, as you can see in my code - i tried multiple scrolltrigger config options). You can see this in the live version: https://next-portfolio-beta-ecru.vercel.app/ - yes, im'using lenis, but if it's off/on, jumping/performance issue stays the same next.js structure: <main className="main w-full overflow-hidden"> <WaitForModel /> <div className="tech-wrapper"> <Tech /> <div className="wrapper absolute h-screen w-full will-change-transform"> <div className="overlap grid h-full w-full grid-cols-1 grid-rows-1 place-items-center"> <About /> <Contact /> </div> </div> </div> </main> and useGSAP in Contact it's all about this part: master .to(".wrapper", { yPercent: -100, ease: "none", }) .to(".about", { yPercent: -100, ease: "none", const { contextSafe } = useGSAP( () => { ScrollTrigger.refresh(); const techElement = document.querySelector(".tech") as HTMLElement; const techHeight = techElement?.offsetHeight || 0; const master = gsap.timeline({ scrollTrigger: { trigger: ".tech-wrapper", start: () => `top+=${techHeight} bottom`, end: "+=250%", scrub: 2, pin: true, pinSpacing: true, preventOverlaps: true, pinReparent: true, refreshPriority: 1, anticipatePin: 1, }, }); master .to(".wrapper", { yPercent: -100, ease: "none", }) .to(".about", { yPercent: -100, ease: "none", onUpdate: () => { const contactElement = wrapperRef.current; if (contactElement) { const progress = master.progress(); if (progress > 0.99) { if (contactElement.style.overflowY !== "auto") { contactElement.style.overflowY = "auto"; contactElement.addEventListener("scroll", handleScroll); } } else { if (contactElement.style.overflowY !== "hidden") { contactElement.style.overflowY = "hidden"; contactElement.removeEventListener("scroll", handleScroll); } } } }, }); }, { dependencies: [tContact], revertOnUpdate: true, }, ); // Context-safe event handler const handleScroll = contextSafe(() => { const contactElement = wrapperRef.current; if (contactElement) { const isScrolledToEnd = contactElement.scrollHeight - contactElement.scrollTop <= contactElement.clientHeight + 1; gsap.to(".footer", { opacity: isScrolledToEnd ? 1 : 0, duration: isScrolledToEnd ? 0.2 : 0.2, ease: "power1.out", }); } }); contact jsx classes: <section ref={wrapperRef} className="contact no-scrollbar panel z-5 relative col-start-1 col-end-2 row-start-2 row-end-2 h-screen w-full bg-thirdBackground will-change-transform dark:bg-secondBackground" > {children} </section> about jsx classes: <section className="about panel absolute top-0 z-10 col-start-1 col-end-2 row-start-1 row-end-2 min-h-screen w-full overflow-hidden bg-secondBackground py-20 shadow-xl will-change-transform lg:py-36 dark:bg-background"> Any tips on what I could do better here? In general, I have scrolltriggers and usegsap in almost all components (but they all work fine, except for the one described below) - is this too much for gsap and hence the performance drops and those annoying skips when starting pinning? PS. Is there any way to implement refresh on resize/rotate , beacuse as you can see - i have dynamic values in my master timeline. Does gsap for react have any built-in methods that I missed when reading the documentation? Or should i use vanilla js methods? DEMO: https://stackblitz.com/edit/stackblitz-starters-fgwgzwmx?file=app%2Fpage.tsx here in the demo we have a closed environment so it works maybe a bit better - but with fast scrolling, there is the same effect of a breaking/jumping animation when the about section is driving into the TECH section. The problem is also reproducible on mobile devices (and is even more pronounced ).
  8. Hi, i have working in cargo collective website then i've added smooth scroll lenis.js and my requirement also one section use animation like card scrolling pin effect horizontally then i have implement gsap scrollTrigger but i have scrolling then smooth scroll lenis.js working perfectly but when enter the section they are hold card's not see only white background showing so please check it and help me.
  9. rantsa jonathan

    Invalid property scrollTrigger set to

    Hi everyone, I’m encountering the following error when deploying my project on Netlify: Invalid property scrollTrigger set to {trigger: section#vertical, start: 'top top', end: 'bottom center', scrub: true}. This works perfectly fine in my local environment, but the error appears on Netlify. Here is what I’ve tried so far: I made sure to register the plugin using gsap.registerPlugin(ScrollTrigger), but the issue persists. I double-checked that all the DOM elements (#vertical and .col_left) exist before initializing ScrollTrigger. I tested the values passed to scrollTrigger using console.log, and they seem correct. Here’s a simplified example of my code: import React, { useEffect } from "react"; import "../styles/SecondScreen1.css"; import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import orange from "../assets/images/Orange.webp"; import mapnazava from "../assets/images/Mpanazava.webp"; import gate from "../assets/images/Gate.webp"; import Lenis from "@studio-freight/lenis"; gsap.registerPlugin(ScrollTrigger); const SecondScreen1 = () => { useEffect(() => { const lenis = new Lenis({ duration: 1.2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), }); function raf(time) { lenis.raf(time); ScrollTrigger.update(); requestAnimationFrame(raf); } requestAnimationFrame(raf); const section1 = document.getElementById("vertical"); const colLeft = document.querySelector(".col_left"); // Gestion responsive avec matchMedia const mm = gsap.matchMedia(); mm.add("(max-width: 449px)", () => { gsap.fromTo( colLeft, { y: 0 }, { y: "90vh", duration: 1, ease: "tick", scrollTrigger: { trigger: section1, start: "top top", end: "bottom center", scrub: true, }, } ); }); mm.add("(min-width: 450px) and (max-width: 950px)", () => { gsap.fromTo( colLeft, { y: 0 }, { y: "115vh", duration: 1, ease: "tick", scrollTrigger: { trigger: section1, start: "top top", end: "bottom center", scrub: true, }, } ); }); mm.add("(min-width: 951px)", () => { gsap.fromTo( colLeft, { y: 0 }, { y: "32vh", duration: 1, ease: "tick", scrollTrigger: { trigger: section1, start: "top top", end: "bottom center", scrub: true, }, } ); }); return () => { ScrollTrigger.getAll().forEach((trigger) => trigger.kill()); mm.revert(); // Supprimer les animations lors du démontage }; }, []); return ( <div className="secondscreen1"> <section id="vertical"> <div className="container"> <div className="vertical__content"> <div className="col col_left"> <h2 className="vertical__heading custom-h2"> <span>Experience</span> <span>That you</span> <span>Can Trust</span> </h2> <h4 className="custom-h4"> MY PROFESSIONAL PATH </h4> <p className="custom-p"> Over my career, I've had the opportunity to consolidate my skills while working with outstanding organizations across various industries. Here are some of the projects and companies I’ve had the pleasure of contributing to. </p> </div> <div className="col col_right"> <div className="vertical__item"> <div className="header-container"> <img src={orange} alt="Logo" className="custom-image" /> <div className="test-xp"> <h3 className="custom-h3">Orange Digital Center</h3> <h3 className="custom-h3">Développeur Mobile et Web</h3> <h3 className="custom-h3 tech"> Flutter - React Js - Node Js </h3> </div> </div> <p> July 2024 - October 2024 ( 4-month internship ) <br /> As part of the Orange Summer Challenge, I created the Mobile application of the SPARE project with Flutter and the website with React Js. </p> </div> <div className="vertical__item"> <div className="header-container"> <img src={mapnazava} alt="Logo" className="custom-image" /> <div className="test-xp"> <h3 className="custom-h3">Mpanazava eto Madagascar</h3> <h3 className="custom-h3"> Développeur d’application Mobile </h3> <h3 className="custom-h3 tech">Flutter- Node Js</h3> </div> </div> <p> February 2024 - June 2024 <br /> Development of a mobile payment application payment form mobile application with Flutter and Node Js with transaction tracking. </p> </div> <div className="vertical__item"> <div className="header-container"> <img src={gate} alt="Logo" className="custom-image" /> <div className="test-xp"> <h3 className="custom-h3">Gate Company Group</h3> <h3 className="custom-h3">Développeur Mobile et Web</h3> <h3 className="custom-h3 tech"> React Native - React Js - Node Js </h3> </div> </div> <p> November 2023 - January 2024 ( 3-months internship ) <br /> Development of GateAfri, GateNews and AfriMuz with React Native. Optimization of the graphical (UI) and technical aspects of the GateAfri and GateNews websites with React Js. </p> </div> </div> </div> </div> </section> </div> ); }; export default SecondScreen1;
  10. Hi there, i'm sharing you a part of my animation i want to achieve. It's working fine if i'm scrolling gradually. I need to fire some timelines depending on scrollTrigger progress one by one. For that i add onUpdate callback on scrollTrigger and depending on the ranges i have defined i want to fire the concerned timelines. Is there a solution to write my callbacks more correctly to be sure that i stop lenis scrolling as a timeline is fire and restart lenis scroll when the timeline is complete or reverseComplete to let lenis scroll to next or previous progressRange ? I try a lots of different writing but i never achieve to make the animation perfect user friendly. If you want to get what i mean about my script issue, you can test scrolling hard up and down until you see a timeline fire even if previous timeLine is not complete and you will se some text on top of the other. Not sure if i get clear on my explanations. Thank you in advance for your help or your opinion on the subject.
  11. rantsa jonathan

    Invalid property scrollTrigger set to

    Thank you for your response! I’ve already tried using useGsap as suggested, but the issue persists. Everything works perfectly in my local environment, but when deployed on Netlify, I encounter this error: experience.js:51 Invalid property scrollTrigger set to I understand the importance of providing a minimal demo. I’ll create a simplified example on Stackblitz or CodePen to illustrate the issue more clearly. Regarding your note about registering ScrollTrigger, I’ll double-check to ensure it’s properly registered before creating any animations. Thank you for the advice and the React starters link; I’ll review them as well. import React from "react"; import "../styles/SecondScreen1.css"; import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import orange from "../assets/images/Orange.webp"; import mapnazava from "../assets/images/Mpanazava.webp"; import gate from "../assets/images/Gate.webp"; import Lenis from "@studio-freight/lenis"; import { useGSAP } from "@gsap/react"; gsap.registerPlugin(useGSAP, ScrollTrigger); const SecondScreen1 = () => { useGSAP(() => { const lenis = new Lenis({ duration: 1.2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), }); function raf(time) { lenis.raf(time); ScrollTrigger.update(); requestAnimationFrame(raf); } requestAnimationFrame(raf); const section1 = document.getElementById("vertical"); const colLeft = document.querySelector(".col_left"); const mm = gsap.matchMedia(); mm.add( { isDesktop: "(min-width: 951px)", isTablet: "(min-width: 450px) and (max-width: 950px)", isMobile: "(max-width: 449px)", }, (context) => { const { isDesktop, isTablet, isMobile } = context.conditions; const yValue = isDesktop ? "32vh" : isTablet ? "115vh" : isMobile ? "90vh" : 0; gsap.fromTo( colLeft, { y: 0 }, { y: yValue, duration: 1, ease: "tick", scrollTrigger: { trigger: section1, start: "top top", end: "bottom center", scrub: true, }, } ); } ); return () => { ScrollTrigger.getAll().forEach((trigger) => trigger.kill()); mm.revert(); }; }, []); return ( <div className="secondscreen1"> <section id="vertical"> <div className="container"> <div className="vertical__content"> <div className="col col_left"> <h2 className="vertical__heading custom-h2"> <span>Experience</span> <span>That you</span> <span>Can Trust</span> </h2> <h4 className="custom-h4"> MY PROFESSIONAL PATH </h4> <p className="custom-p"> Over my career, I've had the opportunity to consolidate my skills while working with outstanding organizations across various industries. Here are some of the projects and companies I’ve had the pleasure of contributing to. </p> </div> <div className="col col_right"> <div className="vertical__item"> <div className="header-container"> <img src={orange} alt="Logo" className="custom-image" /> <div className="test-xp"> <h3 className="custom-h3">Orange Digital Center</h3> <h3 className="custom-h3">Développeur Mobile et Web</h3> <h3 className="custom-h3 tech"> Flutter - React Js - Node Js </h3> </div> </div> <p> July 2024 - October 2024 ( 4-month internship ) <br /> As part of the Orange Summer Challenge, I created the Mobile application of the SPARE project with Flutter and the website with React Js. </p> </div> <div className="vertical__item"> <div className="header-container"> <img src={mapnazava} alt="Logo" className="custom-image" /> <div className="test-xp"> <h3 className="custom-h3">Mpanazava eto Madagascar</h3> <h3 className="custom-h3"> Développeur d’application Mobile </h3> <h3 className="custom-h3 tech">Flutter- Node Js</h3> </div> </div> <p> February 2024 - June 2024 <br /> Development of a mobile payment application payment form mobile application with Flutter and Node Js with transaction tracking. </p> </div> <div className="vertical__item"> <div className="header-container"> <img src={gate} alt="Logo" className="custom-image" /> <div className="test-xp"> <h3 className="custom-h3">Gate Company Group</h3> <h3 className="custom-h3">Développeur Mobile et Web</h3> <h3 className="custom-h3 tech"> React Native - React Js - Node Js </h3> </div> </div> <p> November 2023 - January 2024 ( 3-months internship ) <br /> Development of GateAfri, GateNews and AfriMuz with React Native. Optimization of the graphical (UI) and technical aspects of the GateAfri and GateNews websites with React Js. </p> </div> </div> </div> </div> </section> </div> ); }; export default SecondScreen1;
  12. Arshadali

    Cargo Collective Lenis & Scrolltrigger White background Bug

    <style> [id="X4136400666"] bodycopy { } [id="X4136400666"] bodycopy{ } .page-content{ padding: 0; } .full-page { width: 100%; height: 100vh; display: flex; align-items: center; justify-content: center; font-size: 2rem; } /* Custom CSS */ section.section-wrapper { height: 100%; overflow: hidden; width: 300vw; background-color: #242424; } .container { height: 100vh; display: flex; /* justify-content: space-between; */ align-items: center; gap: 50px; margin: 50px 0; transform: translateX(500px); } .card { width: 500px; height: 400px; border: 1px solid #fff; color: #fff; display: flex; justify-content: center; align-items: center; } </style> <div class="page-wrapper"><section class="full-page" style="background-color:#ffefba"><h1>Section 1</h1></section><section class="full-page" style="background-color:#aedff7"><h1>Section 2</h1></section><section class="section-wrapper"><div class="container"><div class="card one"><h3>Module One</h3></div><div class="card two"><h3>Module 2</h3></div><div class="card three"><h3>Module 3</h3></div><div class="card three"><h3>Module 3</h3></div><div class="card three"><h3>Module 3</h3></div><div class="card three"><h3>Module 3</h3></div></div></section><section class="full-page" style="background-color:#d3c4e3"><h1>Section 4</h1></section></div> <!-- gsap js --> <script src="https://freight.cargo.site/m/U2055329218988265169812608288936/gsap.min.js"></script> <!-- scrollTrigger --> <script src="https://freight.cargo.site/m/O2064440389866436514677162081968/ScrollTrigger.min.js" defer></script> <script src="https://unpkg.com/[email protected]/dist/lenis.min.js"></script> <script> // Initialize Lenis Smooth Scroll const lenis = new Lenis({ duration: 3, smooth: true, }); function raf(time) { lenis.raf(time); requestAnimationFrame(raf); } requestAnimationFrame(raf); // Register GSAP's ScrollTrigger plugin gsap.registerPlugin(ScrollTrigger); // Horizontal Scroll Animation const horizontalContainer = document.querySelector('.container'); const totalScrollWidth = horizontalContainer.scrollWidth - window.innerWidth; // Pin and Horizontal Animation gsap.to(horizontalContainer, { x: -totalScrollWidth, // Move horizontally ease: 'none', scrollTrigger: { trigger: '.section-wrapper', start: 'top top', // Pin starts at the top end: `+=${totalScrollWidth}`, // The horizontal scroll distance scrub: 1, // Smooth animation during scroll pin: true, // Pin the section //markers: true }, }); // Sync Lenis with GSAP's ScrollTrigger lenis.on('scroll', ScrollTrigger.update); </script>
  13. mvaneijgen

    ScrollTrigger Markers Misaligned During Horizontal Scroll Animation

    Hi @Dornor Teye Israel welcome to the forum! You have nested ScrollTriggers on tweens in a timeline, this is logical impossible https://gsap.com/resources/st-mistakes/#nesting-scrolltriggers-inside-multiple-timeline-tweens See the most common mistakes made with ScrollTrigger When using a timeline ScrollTrigger can only be on the whole timeline not on individual tweens. I'm not sure which of your ScrollTrigger is the preferred one, but I changed some logic and to me it now seems to work. I've also removed lenis just to see if that caused any issues, but you can add it back in when everything is working. Do note that lenis is not a GSAP products, so we can provide support for that on this forum and we also have our own smooth scroll library aptly named ScrollSmother (https://gsap.com/docs/v3/Plugins/ScrollSmoother/), which works out of the box with all the GSAP tools. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/jEOMRwa?editors=0010
  14. dominz2005

    Problem with Lenis + GSAP Scroll Trigger

    I have a problem with implementing lenis with the scrollTrigger. Basically when I make the scroll trigger end to be "+=800px" lenis ends up unavailable to scroll to the bottom of the page. gsap.registerPlugin(ScrollTrigger); const lenis = new Lenis({ lerp: 0.15, autoRaf: true, }); ScrollTrigger.create({ trigger: section.value.parentNode, start: "top 89px", end: `+=800px`, pin: section.value, markers: true })
  15. aronanol

    GSAP on mobile with javascript RAF and or three.js

    Hi Rodrigo here one mini demo: https://codesandbox.io/p/sandbox/nskhzh?file=%2Findex.html , the idea is to got gsap , lenis and three.js working together. Currently on my real app I got pretty good perfs ( 40fps to 60 fps), so it's cool, my idea was to sync ScrollTriggers.update at same time as I update my three.js renders, I don't know why but it seems to work on my real project. Here I am stuck: I want to have an html with overflow: hidden, body scrollable, to prevent resize during scroll ( so i dont need to use normalizeScroll which jitter the scroll, and dont need to use syncTouch from lenis which remove the mobile touch inertia ). Actually as you can see on m codesandbox, this demo work on mobile, but doesnt work on desktop... I am trying to get the smoother from Lenis, and the scrubs/scrollTriggers from gsap, and by hidden the overflow on the body, avoid the resizes from ScrollTriggers. And for information, my current three.js scene works perfectly well on mobile, if i remove gsap I got 60 fps non stop, the problem seems to come from the way gsap calculate the scrollTriggers I guess via ScrollTrigger.update or something of thing kind. Your tool is absolutely awesome, soo I am trying to found a way to make this wonderfull tool work with my project. Thank you for your advices/informations! ❤️
  16. vamsi12

    Heading is Jumping on intial sroll

    <html> <head> <link rel="stylesheet" href="./index.css"/> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet"> <script src="https://unpkg.com/@dotlottie/player-component@latest/dist/dotlottie-player.mjs" type="module"></script> <style> *{ scroll-behavior:auto !important; } #text-container { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #000000; font-size: 60px; display: flex; flex-direction: column; justify-content: center; align-items: center; } .container11 { text-align: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, 0%); text-align: center; color: #000000; font-size: 60px; display: flex; flex-direction: column; justify-content: center; align-items: center; } canvas { image-rendering: -webkit-optimize-contrast; image-rendering: crisp-edges; image-rendering: pixelated; -ms-interpolation-mode: nearest-neighbor; } .dunbox{ width: 84px !important; } .text-data{ font-family: "Plus Jakarta Sans", sans-serif; } .badge11 { display: inline-flex; align-items: center; background-color: #F1EDFF; border-radius: 8px; padding: 5px 15px; font-size: 14px; color: #431DC2; font-weight: bold; } #scroll-text{ font-size: 64px; font-family: "Plus Jakarta Sans", sans-serif; font-weight: 600; margin-top: 20px; transform: translate(0%, -180%); } #scroll-text11{ transform: translate(0%, -180%); } .heading-unboxed{ font-size: 40px; font-weight: bold; color: #000; margin-top: 20px; margin-bottom: 20px; font-family: "Plus Jakarta Sans", sans-serif; } #page2{ display: flex; flex-direction: column; justify-content: center; align-items: center; margin-top: 90px; } .badge11 .icon { margin-right: 5px; font-size: 16px; color: #431DC2; } .data-heading{ color: #805AFF; } .cta-button { background-color: #000; color: #fff; padding: 3px; border-radius: 58px; width: 197px; height: 48px; font-size: 16px; display: flex; justify-content: space-between; align-items: center; text-decoration: none; font-weight: bold; transition: background-color 0.3s ease; } #scroll-text11{ margin-bottom: 30px; outline: none; border-width: 0; } .arrow11{ background-color: #F8F75E; width: 44px; height: 44px; display: flex; justify-content: center; align-items: center; border-radius: 46px; } .text-11{ text-decoration: none; color: #FFFFFF; margin-left: 20px; font-size: 13px; display: flex; justify-content: center; font-family: "Plus Jakarta Sans", sans-serif; } @media (min-width:320px) and (max-width:480px){ #image-1{ aspect-ratio: 1000/1000 !important; } } </style> </head> <body> <div id="main"> <div id="main2"> <div id="page2"> <canvas id="image-1" ></canvas> <div id="text-container"> <video width="64" height="64" autoplay muted loop id="scroll-text11" style="opacity: 1;"> <source src="https://dunboxed.com/wp-content/uploads/2024/10/Comp-2.mp4" type="video/mp4"> </video> <p id="scroll-text" style="opacity: 1;">Data Is Powerful</p> </div> <div class="container11" id="container11" style="opacity: 0;"> <div class="badge11"> <span class="icon"><img src="https://dunboxed.com/wp-content/uploads/2024/10/dunboxed-logo.svg" class="img11"/></span> <span class="text-data">Data Is Powerful</span> </div> <h1 class="heading-unboxed">Unbox Your <span class="data-heading">Data Potential</span><br/> with Dunboxed</h1> <div class="cta-button"> <a href="https://dunboxed.com/contact-us/" class="text-11">Get Started Today</a> <div class="arrow11"> <img src="https://dunboxed.com/wp-content/uploads/2024/10/arrow-dunboxed.svg"/> </div> </div> </div> </div> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/Timeline.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/ScrollTrigger.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@studio-freight/lenis@latest/bundled/lenis.min.js"></script> <script> const lenis = new Lenis({ duration: 0.8, // Adjust the smoothness of the scroll easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // Custom easing function smooth: true, }); function raf(time) { lenis.raf(time); requestAnimationFrame(raf); } requestAnimationFrame(raf); ScrollTrigger.scrollerProxy(document.body, { scrollTop(value) { return arguments.length ? lenis.scrollTo(value) : lenis.animatedScroll; }, getBoundingClientRect() { return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight }; }, pinType: document.body.style.transform ? "transform" : "fixed", }); // Update on animation frame lenis.on("scroll", ScrollTrigger.update); const preloadLottie = () => { const lottiePlayer = document.querySelector("dotlottie-player"); return new Promise((resolve, reject) => { lottiePlayer.addEventListener('load', resolve, { once: true }); lottiePlayer.load(); }); }; gsap.registerPlugin(ScrollTrigger); ScrollTrigger.defaults({ }); const canvas = document.querySelector("#page2>canvas"); const context = canvas.getContext("2d"); const canvasWidth = window.innerWidth ; const canvasHeight = window.innerHeight * 0.9; canvas.width = canvasWidth; canvas.height = canvasHeight; window.addEventListener("resize", function () { const canvasWidth = window.innerWidth; const canvasHeight = window.innerHeight * 0.9; canvas.width = canvasWidth; canvas.height = canvasHeight; render(); }); const frameCount = 155; const baseUrl = "https://dunboxed.com/wp-content/uploads/2024/11/final_animation2_"; const images = []; const sequence = { frame: 2 }; for (let i = 0; i < frameCount; i++) { const img = new Image(); img.src = `${baseUrl}${(i + 1).toString().padStart(5, "0")}.jpg`; images.push(img); } gsap.to(sequence, { frame: frameCount - 1, snap: "frame", ease: "none", scrollTrigger: { scrub: 0.4, start: `10% top`, end: `+=5000`, trigger: "#page2", onUpdate: function() { render(); const text = document.getElementById("scroll-text"); const text11 = document.getElementById("scroll-text11"); // Text Opacity and Positioning Logic if (sequence.frame <= 80) { text.style.opacity = 1; text11.style.opacity = 1; } else if (sequence.frame > 80 && sequence.frame <= 90) { const fadeOutProgress = (sequence.frame - 80) / 10; // Calculate fade out progress text.style.opacity = 1 - fadeOutProgress; text.style.transform = `translate(0%, ${-180 - fadeOutProgress * 40}%)`; // Smooth transition upwards text11.style.opacity = 1 - fadeOutProgress; text11.style.transform = `translate(0%, ${-180 - fadeOutProgress * 40}%)`; // Smooth transition upwards } else { text.style.opacity = 0; // Fully faded out after frame 90 text.style.transform = `translate(0%, -220%)`; text11.style.opacity = 0; // Fully faded out after frame 90 text11.style.transform = `translate(0%, -220%)`; } const container1 = document.getElementById("container11"); let textOpacity1 = 0; let textY = 0; if (sequence.frame >= 108 && sequence.frame < 130) { textOpacity1 = (sequence.frame - 108) / 8; textY = -120 + (sequence.frame - 108); } else if (sequence.frame >= 130 && sequence.frame <= 155) { textOpacity1 = 1; textY = -120 + (130 - 108); } else if (sequence.frame < 108) { textOpacity1 = 0; } container1.style.opacity = textOpacity1; container1.style.transform = `translate(-50%, ${textY}%)`; } } }); images[2].onload = render; function render() { scaleImage(images[sequence.frame], context); } function scaleImage(img, ctx) { var canvas = ctx.canvas; var hRatio = canvas.width / img.width; var vRatio = canvas.height / img.height; var ratio = Math.min(hRatio, vRatio); var centerShift_x = (canvas.width - img.width * ratio) / 2; var centerShift_y = (canvas.height - img.height * ratio) / 2; context.clearRect(0, 0, canvas.width, canvas.height); context.drawImage( img, 0, 0, img.width, img.height, centerShift_x, centerShift_y, img.width * ratio, img.height * ratio ); } ScrollTrigger.create({ trigger: "#main", pin: true, start: `top top`, end: `+=5000` }); </script> </body> </html> I am working in wordpress elementor one section i used custom code in that i written a custom code as mention above i am working on image sequence in wordpress can you fix the "data is powerfull" is jumping on intiall scroll and please check the video it should fixed without any jumping and scroll smoothly https://www.loom.com/share/dcffc00fba024515b096428522120775?sid=a54fb642-d31f-4138-9b4e-a95cfbc0722e
  17. mixpofo

    ScrollTrigger and Lenis

    Hello, I am encountering an issue with ScrollTrigger and Lenis on the mobile version of my project. The scrolling experience is laggy and not smooth, whereas everything operates seamlessly on the desktop version. This is my code : useEffect(() => { const lenis = new Lenis({ duration: 2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), infinite: false, }); lenis.on("scroll", ScrollTrigger.update); gsap.ticker.add((time) => { lenis.raf(time * 1000); }); gsap.ticker.lagSmoothing(0); ScrollTrigger.normalizeScroll(true); // Nettoyage lors du démontage return () => { lenis.off("scroll", ScrollTrigger.update); }; }, []); Thanks !!
  18. Hey Cassie, Thanks for the help - upon some further inspection I realized the issue wasn't with my code setup as much as with a confliction with lenis smooth scroll. For some reason when I scroll back to the top of the page the logo is jumping by the amount I scrolled down the page (above the viewport) before animating back into the hero, but when I turn off lenis it works fine. I already have the below code to try to keep lenis and gsap in sync but it seems to not be working. Any chance you've run into this issue before or know any other workarounds? (No worries if not, I know external libraries can be their own beast to work with). You can see the current iteration with the lenis issue here: (https://lvly-tv.webflow.io/). Glad to know I can just remove lenis if need be but would prefer to not have to do that. Do you know if I used the GSAP scrollsmoother instead, would prevent this issue from happening? // Keep lenis and scrolltrigger in sync lenis.on('scroll', () => { if (!ScrollTrigger) return; ScrollTrigger.update(); }); On a separate note - do you have any tips on how to handle code cleanup and re-instating on browser resize? I couldn't find any sample code on the flip page and have been unsure on the best way to approach this. Would something like this be sufficient? //kill flips on browser resize let windowWidth = window.innerWidth; window.addEventListener('resize', function () { if (window.innerWidth !== windowWidth) { windowWidth = window.innerWidth; //input code you want run after the browser width is changed Flip.killFlipsOf(logo); } });
  19. Rodrigo

    GSAP on mobile with javascript RAF and or three.js

    Hi, I don't seem to understand your demo, you have these styles: html { width: 100vw; height: 100%; overflow: hidden; } body { overflow-y: scroll; -webkit-overflow-scrolling: touch; height: 100%; width: 100vw; } That basically takes the scrolling out of the HTML element and into the <body> tag. Any particular reason for that? That's why your ScrollTrigger instances are not working. Here is a fork of that demo without those styles and everything seems to work as expected: https://codesandbox.io/p/sandbox/lenis-scroll-forked-457dk6?file=%2Findex.html%3A24%2C5-35%2C6 Also you're using Lenis, why not ScrollSmoother (your Club GSAP membership grants access to it, which simplifies the setup quite a bit and works on top of ScrollTrigger: https://gsap.com/docs/v3/Plugins/ScrollSmoother/ I'd look into using ScrollSmoother instead. Also you can create a codepen demo using this as a starter that loads all the plugins: https://codepen.io/GreenSock/pen/aYYOdN Hopefully this helps Happy Tweening!
  20. aronanol

    GSAP doesnt work with next.js

    Hi guys, hope you're doing well. I got a problem right now by integrating gsap with next.js What I want to achieve: - Got <body/> and <html/> overflow:hidden to avoid mobile adress bar to show/hide and to avoir to use normalizeScroll - Using a scroll proxy with ScrollTriggers and add a smooth effect on them with Lenis - ScrollTrigger.update on my main RAF to got lenis, gsap, and three.js sync Here you got isolated code : https://stackblitz.com/edit/stackblitz-starters-g1esexap?file=app%2FComponents%2FDom%2FMaSection.tsx I am currently stuggling on this one, I got a vanilla version, everything works well, but when pass the code to next.js It seems like gsap scrollTriggers are no longer working. Help yould be appreciated to found a way to achieve that
  21. Hi, I have no experience with Lenis, but it seems that everything in your HTML has overflow hidden applied to it, that kind of contradicts this demo we have that uses Lenis: https://codepen.io/GreenSock/pen/OPLQbYm As per avoiding the mobile address bar from showing/hiding, the only solution we have for that is normalizeScroll, so you'll have to find a different approach by yourself I'm afraid since we already have one in place. Also why not use ScrollSmoother? Your Club GSAP membership level gives you access to it 🤷‍♂️ Another thing you can try is the ignoreMobileResize config option: https://gsap.com/docs/v3/Plugins/ScrollTrigger/static.config()#details Hopefully this helps Happy Tweening!
  22. Rodrigo

    Smooth Scrolling Effect

    Hi @Coding Bird and welcome to the GSAP Forums! GSAP has it's own smooth scrolling tool called ScrollSmoother: https://gsap.com/docs/v3/Plugins/ScrollSmoother/ This is a Club GSAP benefit though, but with the prices we have you'll most likely get your investment back in a single project and after that is all profits, plus you get one year access to all the bonus tools: https://gsap.com/pricing/ There are other options though, the most popular seems to be Lenis, which can be integrated with ScrollTrigger: https://lenis.darkroom.engineering/ Of course Lenis is not a GSAP product so we can't really offer a lot of support for it though. Hopefully this helps Happy Tweening!
  23. Rodrigo

    Heading is Jumping on intial sroll

    Hi, I don't really get the issue here, without a minimal demo (emphasis on minimal) there is not a lot we can do. On top of that @mvaneijgen already provided a fully working demo that doesn't exhibits any problems: https://codepen.io/mvaneijgen/pen/xxvvdzo That should be the starting point for your project. Start by adding Lenis to that demo and take it from there. If you face issues when Lenis is added to Mitchel's demo, then this is something related to the HTML/CSS in connection with Lenis. In that case start with a blank project with Lenis from the beginning and start adding elements and sections to it. Then start creating ScrollTrigger instances one by one until something breaks and you'll know where/when this is behaving oddly, then you can start trying solutions. At that point you can present a minimal demo with just that part of your project that is causing the issue We've seen many projects work with ScrollTrigger and Lenis without any issues, so there is clearly a compatibility between the two tools, so something specific to your project is what's causing problems here. On top of that Lenis is not a GSAP product, we have our own smooth scrolling solution: ScrollSmoother which is 100% compatible with all the GSAP tools and plugins, so we can't really offer free general consulting here, is beyond the scope of what we do in these free forums.
  24. mvaneijgen

    Cargo Collective Lenis & Scrolltrigger White background Bug

    Hi @Arshadali welcome to the forum! There isn't much we can help with without a minimal demo. We need to see your code in action and be able to edit it to help you debug. Also lenis isn't a GSAP product, so we can't really help you on that front. We have our own scroll smoother plugin aptly named ScrollSmoother which works out of the box with all the GSAP products, so if you want a plug and play solution I would advise using that. If you want to keep using lenis, there are some topics on the forum that might help you https://gsap.com/community/search/?q=lenis ScrollTrigger&quick=1&type=forums_topic&nodes=11 If you still need help please create a minimal demo on one of the platforms above. Codepen is the best place in my opinion. Hope it helps and happy tweening! Edit: Seen that you're new here I've pasted your code in a Codepen and without Lenis everything works great! So you might have to ask lenis for support why it is not working. Again hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/Wbeodde?editors=0010
  25. import React, { useEffect } from "react"; import { Link } from "react-router-dom"; import { ReactLenis } from "lenis/react"; import Transition from "../../components/transition/Transition"; import { useLanguage } from "../../LanguageContext"; import gsap from "gsap"; import { SplitText } from "gsap/SplitText"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); const Vibeup = () => { const { language } = useLanguage(); useEffect(() => { console.log("useEffect triggered"); const observer = new MutationObserver((mutationsList, observer) => { for (let mutation of mutationsList) { if (mutation.type === 'childList') { const splitTextElement = document.querySelector(".split"); console.log("Checking for .split element:", splitTextElement); if (splitTextElement) { observer.disconnect(); let mySplitText = new SplitText(".split", { type: "chars" }); let chars = mySplitText.chars; console.log("SplitText initialized", chars); gsap.from(chars, { yPercent: 130, stagger: 0.02, ease: "back.out", duration: 1, scrollTrigger: { trigger: '.split', start: "top 70%", } }); } } } }); observer.observe(document.body, { childList: true, subtree: true }); return () => observer.disconnect(); }, []); Hello, I deployed my site to Vercel and added the token values to the environment variables. It works fine locally, but when I deployed it, the page just shows up blank—CSS works, but no content. Did I miss something? { "name": "linh-nguyen", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "lint": "eslint .", "preview": "vite preview" }, "dependencies": { "framer-motion": "^11.3.30", "gsap": "npm:@gsap/shockingly@^3.12.7", "i18next": "^24.2.1", "lenis": "^1.1.13", "lucide-react": "^0.474.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-i18next": "^15.4.0", "react-router-dom": "^6.26.1" }, "devDependencies": { "@eslint/js": "^9.9.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.20", "eslint": "^9.9.0", "eslint-plugin-react": "^7.35.0", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.9", "globals": "^15.9.0", "postcss": "^8.5.1", "tailwindcss": "^4.0.0", "vite": "^5.4.1" } }
×
×
  • Create New...