epenflow Posted December 24, 2024 Posted December 24, 2024 I'm attempting to replicate the "One Element Scroll" animation from Tympanus.net (https://tympanus.net/Development/OneElementScroll/) using GSAP Flip.fit within a NextJs. However, i'm experiencing an issue where the width and height of the element with the class .one flicker between its full size and the final size set by Flip.fit. Minimal reproduction : i've created a simplified NextJs project on StackBlitz to isolate the issue: https://stackblitz.com/edit/stackblitz-starters-dykskccl?file=app%2F_components%2Fmain.tsx
Solution Rodrigo Posted December 24, 2024 Solution Posted December 24, 2024 Hi @epenflow and welcome to the GSAP Forums! Your demo is far from being minimal (over 300 lines of code) and seems to be working as expected. Please reduce the demo to the bare minimum or just the part that is not working, or the first thing that is not working so we can have a look at some isolated code and behaviour. We don't have the time resources to go through all that code trying to figure it out how everything works while trying to find possible problems and issues, is beyond the help we provide in these free forums. Maybe a simple codepen demo of the part that is not working might be enough, regardless of the framework is just JS, HTML and CSS, so that should be enough as well.
epenflow Posted December 24, 2024 Author Posted December 24, 2024 Hi thank you for your response. I apologize if the length caused any incovenience. I'm encounter an issue with Flip.fit where the element with the class .one flickers during the animation. It seems to render twice, first at its full width and height, then abruptly transition to the final size of the Flip states function createFlipOnScrollAnimation( oneElement: Element | null, parentElement: Element | null ) { const stepElements: HTMLElement[] = gsap.utils.toArray('[data-step]'); if (flipContext.current) flipContext.current.revert(); flipContext.current = gsap.context(() => { const states = stepElements.map((step) => Flip.getState(step)); const timeline = gsap.timeline({ scrollTrigger: { trigger: parentElement, start: 'clamp(center center)', endTrigger: stepElements[stepElements.length - 1], end: 'clamp(center center)', scrub: true, immediateRender: false, // markers: true, }, }); states.forEach((state, index) => { timeline.add( Flip.fit(oneElement, state, { duration: 1, ease: index === 0 ? 'none' : 'sine.inOut', }) as GSAPAnimation, index ? '+=0.5' : 0 ); }); }); }
Rodrigo Posted December 24, 2024 Posted December 24, 2024 Yeah that doesn't really help I'm afraid, since there is nothing wrong GSAP-wise in that code you posted. The only thing I can think about it is that there could be a flaw in the way you're implementing the useGSAP hook here: useGSAP( () => { if (!containerRef.current) throw new Error( `Missing Container Reference : Please ensure containerRef is properly injected.` ); const oneElement = containerRef.current.querySelector('.one'); const parentElement = oneElement!.parentElement; createFlipOnScrollAnimation(oneElement, parentElement); animateSpansOnScroll(); animateImageOnScroll(); addParallaxToText(); animateFilterOnFirstSwitch(oneElement); addParallaxToColumnImages(); window.addEventListener('resize', () => { createFlipOnScrollAnimation(oneElement, parentElement); }); }, { scope: containerRef, dependencies: [] } ); Then your methods look like this: function createFlipOnScrollAnimation( oneElement: Element | null, parentElement: Element | null ) { const stepElements: HTMLElement[] = gsap.utils.toArray('[data-step]'); if (flipContext.current) flipContext.current.revert(); flipContext.current = gsap.context(() => { const states = stepElements.map((step) => Flip.getState(step)); const timeline = gsap.timeline({ scrollTrigger: { trigger: parentElement, start: 'clamp(center center)', endTrigger: stepElements[stepElements.length - 1], end: 'clamp(center center)', scrub: true, immediateRender: false, // markers: true, }, }); states.forEach((state, index) => { timeline.add( Flip.fit(oneElement, state, { duration: 1, ease: index === 0 ? 'none' : 'sine.inOut', // scale: true, // absolute: true, }) as GSAPAnimation, index ? '+=0.5' : 0 ); }); }); } There are a few things that caught my attention. You're using GSAP Context inside your method, there is no need for that since useGSAP uses GSAP Context internally. Second is about the fact that you're just creating the GSAP instances inside your methods. That doesn't work since useGSAP is not aware of those instances since they are created in a different execution context so the hook can't revert them properly. For that your methods either have to return every instance they create (more convoluted and verbose) or they should be wrapped around the contextSafe method the useGSAP hook returns: https://gsap.com/resources/React#making-your-animation-context-safe Finally by default the useGSAP hook uses an empty dependencies array, so there is no need to pass that. Give that a try and if you keep having issues, please reduce the demo to just that initial Flip instance being created inside the useGSAP. Happy Tweening!
epenflow Posted December 26, 2024 Author Posted December 26, 2024 Here's my minimal demo. i set the box to have height and width 400px. it seems my demo on stackblitz doesn't work it always flickering on the first render to height and widht to the last state of flip state. https://stackblitz.com/edit/vitejs-vite-pxnttuhb?file=src%2Fstyle.css See the Pen ZYzygRV by epenflow (@epenflow) on CodePen.
Rodrigo Posted December 26, 2024 Posted December 26, 2024 Hi, I'm not really sure what the problem is in the codepen you posted (the stackblitz demo seems to be working as expected) but this is how it looks without any GSAP code in it: See the Pen wBwqWrB by GreenSock (@GreenSock) on CodePen. As you can see the width of the box is never 400px, so there is something in the CSS that could be causing this 🤷♂️ As for what you're trying to achieve maybe this simpler demo can get you on the right direction: See the Pen VYZzjMV by GreenSock (@GreenSock) on CodePen. Hopefully this helps Happy Tweening!
epenflow Posted December 27, 2024 Author Posted December 27, 2024 I recreate your given example to next js but still i've encountered the same issue. I don't know why this is happens, but i think i'll use gsap set to set the initial height and width.
AmethystKhoa Posted January 19 Posted January 19 Hi, i got the same issue as @epenflow, the height and width of target element are set immediately before the flip animation, here is a minimal demo using NextJS and Flip plugin: https://stackblitz.com/edit/stackblitz-starters-sgqwnjcr?file=app%2Fpage.tsx I tested in many ways, with vanilla JS and React only, it worked as expected, but not with Next JS 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now