Jump to content
Search Community

Search the Community

Showing results for tags 'usegsap'.

  • 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)

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 14 results

  1. Hi My STACKBLITZ: https://stackblitz.com/edit/react-tbctyjhz?file=src%2FApp.js I seem to be having a logic issue between multiple video scrolltriggers. In my STACKBLITZ example, you can see in my App.jsx, I have: "Introveal", words fade in automatically, then fades out as you scroll "Aerial", fades in, video schrubs, and title appear, then video fades out all good up to this point But I will have multiple "Aerial" type video scrollers with titles, so to simulate it I just duplicated the "Aerial" component for a total of 3 of them in my App.jsx Now I have a weird problem that I'm not sure how to solve. The fading in/out between the IntroReveal/(1st Aerial), works great as the one fades in as soon as the previous fades out. BUT, this is the issue, in the case of the Aerial, duplicated few times as I have it, there seems to be a 100vh between them. IE you have to scroll a lot after the 1st one fades out, before the next one starts fading in. I'm not sure how to fix that, without messing up the timings elsewhere, since as I say after the Introreveal, all is good. AFTER the last, Aerial fades out, the dummy content I added there also comes in fine at correct time.
  2. Hey there, Trying to animated mapped components in my Next.js app. I have succeeded, but something is off.. The animation is not 'fluid'. See clip. I noticed it does not happen with 'a hardcoded array of items'. I also tried to grab all the buttons using gsap.utils.toArray(#button), but the same happens. How can I adjust the code for it to be fluent? Screen Recording 2025-09-18 at 11.55.28.mov Here is my code: const buttonRefs = useRef<HTMLAnchorElement[]>([]); buttonRefs.current = []; tl.fromTo( buttonRefs.current, { autoAlpha: 0, yPercent: 100 }, { autoAlpha: 1, yPercent: 0, ease: "linear", stagger: 0.1 } ); }, []); const addToRefs = (el: HTMLAnchorElement | null) => { if (el && !buttonRefs.current.includes(el)) { buttonRefs.current.push(el); } }; <div className="flex flex-row gap-4 w-fit"> {slice.primary.cta_buttons.map((item) => ( <Button ref={addToRefs} key={item.link.text} className="text-body-base font-medium" buttonStyle={item.style ?? "primary"} field={item.link} > {item.link.text} </Button> ))} </div> Much appreciated!
  3. Hello there, I'm trying to develop a portfolio thumbnail gallery that is horizontally scrollable and have parallax effect with gsap scrollTrigger and with skew applied for animating them based on vertical scroll speed, all this I'm trying to achieve with next.js 15 framework. Dev environment: Next.js 15, GSAP(ScrollTrigger, useGSAP), Lenis Problem: i'm unable the scroll till the last thumbnail. I'm only providing the code of the particular component file where I've implemented the gallery. 'use client'; import { useRef, useLayoutEffect } from 'react'; import { gsap } from 'gsap/dist/gsap'; import { ScrollTrigger } from 'gsap/dist/ScrollTrigger'; import { useGSAP } from '@gsap/react'; import Image from 'next/image'; console.clear(); gsap.registerPlugin(ScrollTrigger, useGSAP); const images = [ '/images/1.jpg', '/images/2.jpg', '/images/3.jpg', '/images/4.jpg', '/images/5.jpg', '/images/6.jpg', '/images/7.jpg', '/images/8.jpg', '/images/9.jpg', '/images/10.jpg', ]; const Gallery = () => { const containerRef = useRef(null); const galleryRef = useRef(null); useGSAP( () => { // Ensure gallery is not empty before calculating dimensions if (!containerRef.current || !galleryRef.current) return; const images = gsap.utils.toArray('.gallery-image-wrapper'); const gallery = galleryRef.current; const totalWidth = images.reduce( (sum, item) => sum + item.offsetWidth, 0, ); // We need to calculate how far to scroll the gallery const scrollDistance = totalWidth - window.innerWidth; // Pin the section and horizontally scroll the gallery wrapper const scrollTween = gsap.to(gallery, { x: -scrollDistance, // Animate to the negative scroll distance ease: 'none', scrollTrigger: { trigger: containerRef.current, pin: true, scrub: 2, start: 'top top', end: `+=${scrollDistance}`, // The end position matches the scroll distance invalidateOnRefresh: true, // Recalculates on resize markers: true, }, }); // quickSetter for optimized velocity skew const skewProxy = { skew: 0 }; const skewSetter = gsap.quickSetter( '.gallery-image-wrapper', 'skewX', 'deg', ); const clamp = gsap.utils.clamp(-10, 10); // Max skew amount in degrees ScrollTrigger.create({ onUpdate: (self) => { let skew = clamp(self.getVelocity() / -100); // Only update the skew if the absolute value is greater than the current one if (Math.abs(skew) > Math.abs(skewProxy.skew)) { skewProxy.skew = skew; gsap.to(skewProxy, { skew: 0, duration: 0.8, ease: 'power3.in', overwrite: true, onUpdate: () => skewSetter(skewProxy.skew), }); } }, }); // Parallax for individual images images.forEach((wrapper) => { const image = wrapper.querySelector('img'); gsap.to(image, { y: '20%', // Adjust the parallax intensity ease: 'none', scrollTrigger: { trigger: wrapper, containerAnimation: scrollTween, // Tie the animation to the horizontal scroll start: 'left right', end: 'right left', scrub: true, }, }); }); // Ensure GSAP recalculates on image load completion // You may need a more robust solution if using a complex image lazy-loading library const imagesLoadedPromise = new Promise((resolve) => { let loadedCount = 0; const totalImages = images.length; if (totalImages === 0) { resolve(); } images.forEach((imgWrapper) => { const img = imgWrapper.querySelector('img'); img.onload = () => { loadedCount++; if (loadedCount === totalImages) { resolve(); } }; }); }); imagesLoadedPromise.then(() => { ScrollTrigger.refresh(); }); }, { scope: containerRef, dependencies: [], revertOnUpdate: true }, ); return ( <section ref={containerRef} className='gallery-container'> <div ref={galleryRef} className='gallery-wrapper'> {images.map((src, index) => ( <div key={index} className='gallery-image-wrapper'> <div className='gallery-image-content'> <Image src={src} alt={`Gallery Image ${index + 1}`} width={400} height={500} className='gallery-image' priority={index === 0} // Optional: Prioritize the first image for faster loading /> </div> </div> ))} </div> </section> ); }; export default Gallery; I'm fetching this Gallery.js inside page.js in the app folder and usinng Lenis wrapper for react in the layout.js file. Please guide me with a prfoper solution.Gallery.js layout.js page.js LenisProvider.js
  4. After reading react-advanced for several times, having chatgpt, deepseek and claude helping me to debug and trying my best I decide to create minimal demo to ask for help. I also did search forums but I didn't find clear solution for my problem that is not some kind of overengineering that I dont even understand. I created parent component (App.jsx) which creates the timeline. I created two child components, Heading.jsx and Loader.jsx and I pass them timeline with prop drilling (like gsap react-advanced article suggest). In each child, with useGSAP hook and timeline.add I add proper animations to timeline. I want Loader.jsx animation to run first and only then Heading.jsx. How do I do it? Obviously if I swap component order in DOM (in app.jsx) I can make Loader.jsx run first, but this will get messy in real project where I have more components and animations to add in timeline, and I also dont want to change my DOM order. I tried with labels but it didnt help me at all. I obviously dont want to use fixed seconds to decide what will run when, because real timeline is much more complex than these two components. I just want a way to control order of these animations, and let timeline handle when animation is finished and when next one will run. How do I control sequence of animations inside timeline that is created in parent component, and where child component add animations to parent timeline? Demo: https://stackblitz.com/edit/gsap-react-basic-f48716-kbuaghjm?file=src%2FApp.js,src%2Fcomponents%2FLoader%2FLoader.jsx,src%2Fcomponents%2FHeading%2FHeading.jsx Thank you
  5. LIR

    Animation Focus on ViewPort

    Hello, I hope you are well. First of all may I note that I am new using GSAP and that I am using it in React ("gsap" and "gsap/react" libraries). I want to reuse an animation, that basically is an horizontal scroll. Even though the animation works perfectly, I need the viewport to be centered on the whole parent section (so the title "Algunos proyectos_" and filter stays on sight). I tried setting the trigger by the section ID that is 'projects', by using document.querySelectorAll("sections.projects"), etc but always without the expected results. Can you guide me through or give me some assistance please? Thanks in advance! P.S.: This is how is seen while the animation takes place: P.S.2: This is how it should be seen while the animation takes place:
  6. gabriel.ortiz

    useGSAP not registering `useRef`

    I'm just starting out with React and `useGSAP` and I'm running into an issue with out what appears to be the hook registering: react.development.js:1630 Uncaught TypeError: Cannot read properties of null (reading 'useRef') at useRef (react.development.js:1630:1) at useGSAP (index.js:32:1) However, despite this error - I can console.log the `useGSAP` hook, and also the `gsap` package and both are successfully loaded. This error message happens when I try to use useGSAP. This is the error message i'm getting: Segment.tsx:39 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. printWarning @ react.development.js:209 error @ react.development.js:183 resolveDispatcher @ react.development.js:1592 useRef @ react.development.js:1629 useGSAP @ index.js:32 (anonymous) @ Segment.tsx:39 react.development.js:1630 Uncaught TypeError: Cannot read properties of null (reading 'useRef') at useRef (react.development.js:1630:1) at useGSAP (index.js:32:1) at Segment.tsx:39:1 at renderWithHooks (react-dom.development.js:16305:1) at updateForwardRef (react-dom.development.js:19226:1) at beginWork (react-dom.development.js:21636:1) at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1) at invokeGuardedCallback (react-dom.development.js:4277:1) at beginWork$1 (react-dom.development.js:27451:1) here's what i have so far: import React, { forwardRef, useEffect, useCallback, useRef } from "react"; import { useActiveSegment, BkExpeditionContextValues, } from "src/BkExpedition/index"; import { mergeRefs } from "src/util/mergRefs"; import clsx from "clsx"; import gsap from "gsap/dist/gsap"; import { useGSAP } from "@gsap/react"; gsap.registerPlugin(useGSAP); export type SegmentProps = Omit< React.ComponentPropsWithoutRef<"section">, "onAnimationStart" | "onDragStart" | "onDragEnd" | "onDrag" | "onDragOver" > & { segmentKey: BkExpeditionContextValues["activeSegment"]; }; export const Segment = forwardRef<HTMLDivElement, SegmentProps>( (props, ref) => { const { segmentKey, className, children, ...restOfHtmlAttrs } = props; const { activeSegment, previousSegment } = useActiveSegment(); const isActive = activeSegment === segmentKey; const sectionRef = useRef<HTMLDivElement>(null); const animateInTL = useRef<gsap.core.Timeline>(); const animateOutTL = useRef<gsap.core.Timeline>(); useGSAP(() => { // console.log("sectionRef", sectionRef.current); // if (sectionRef.current === null) return; // // animateInTL.current = gsap // .timeline({ paused: true }) // .fromTo(sectionRef?.current, { x: "100%" }, { x: "0%" }); // animateOutTL.current = gsap // .timeline({ paused: true }) // .fromTo(sectionRef?.current, { x: "0%" }, { x: "-100%" }); }); useEffect(() => { if (previousSegment === null) { return; } if (activeSegment === segmentKey) { animateInTL?.current?.play(); return; } if (previousSegment === segmentKey) { animateOutTL?.current?.play(); return; } }, [activeSegment, previousSegment, segmentKey]); return ( <section ref={mergeRefs(ref, sectionRef)} {...restOfHtmlAttrs} aria-hidden={!isActive} className={clsx(className, styles.segment, isActive && styles.isActive)} style={{ transform: isActive ? "translateX(0%)" : "translateX(100%)", }} > {children} </section> ); }, ); Segment.displayName = "Segment"; Am i not registering the book in the right place? Should it be registered inside the function component? FWIW - I plan to use this component in Next.js. Any help would be really appreciated -Gabriel
  7. const DotCursor: React.FC = () => { const dotRef = useRef<HTMLDivElement>(null); const { clientX, clientY } = useMousePosition(); const [isVisible, setIsVisible] = useState(false); const handleMouseEnter = () => { setIsVisible(true); }; const handleMouseLeave = () => { setIsVisible(false); }; const handleMouseMove = () => { setIsVisible(true); }; useGSAP( () => { const dot = dotRef.current; if (!dot) return; window.addEventListener("mousemove", handleMouseMove); document.addEventListener("mouseenter", handleMouseEnter); document.addEventListener("mouseleave", handleMouseLeave); const animateDot = () => { gsap.set(dot, { x: clientX, y: clientY, }); }; gsap.ticker.add(animateDot); return () => { window.removeEventListener("mousemove", handleMouseMove); document.removeEventListener("mouseenter", handleMouseEnter); document.removeEventListener("mouseleave", handleMouseLeave); gsap.ticker.remove(animateDot); }; }, { dependencies: [clientX, clientY] } ); return ( <div ref={dotRef} className="dot-cursor bg-orange-700" style={{ opacity: isVisible ? 1 : 0, position: "fixed", width: "10px", height: "10px", border: "solid 1px black", borderRadius: "20%", pointerEvents: "none", transform: "translate(-50%, -50%)", zIndex: 9999, }} /> ); }; export default DotCursor;
  8. Leptitnouveau

    Scope issue with useGSAP

    Hello, For my final university college project I want to create a "Your own adventure webcomic". I've recently started my React journey, and I wanted to animate some stuffs in this project. Here you can access a codesandbox for a better understanding for what is coming. I think that I have a misunderstanding of how the scope of useGsap works. Here is my problem, I have a parent component (StoryNarrative) and its child (StoryFragment). StoryNarrative create multiple iteration of StoryFragment. It is important to also note that a new StoryFragment is created whenever the state displayToNumber changes. displayToNumber is a number that changes everytime that the user clicks on a button. It tells StoryNarrative to loop StoryFragment based on an array from 0 to displayToNumber. I want the scope to be a div within the last iteration of StoryFragment that has been created. In order to do so, I have created a ref array (animatedRef) that refers every div. Once done, I have written that the scope should be the last element created. I thought that I could have two different ways to do so. Use animatedRef.current[animatedRef.current.length - 1] or animatedRef.current.[displayToNumber]. But it does not work as I thought. The console shows that for some reason, even after that a new div is created, React keeps using the old length for the first build of the component before changing when I use "animatedRef.current[animatedRef.current.length - 1]" but it does not do so when I use animatedRef.current.[displayToNumber]. But the problem is, however I write animatedRef.current.[displayToNumber] or animatedRef.current[animatedRef.current.length - 1] as the scope, it never refers to the last element created. With animatedRef.current[animatedRef.current.length - 1] it animates the element before the last and with animatedRef.current.[displayToNumber] it seems like the scope does not work at all. So if anyone have any idea of why this is happening please let me know. English is not my mothertongue so I may have done some mistakes, if something is not clear enough please let me know. And thanks in advance for your answers.
  9. I'm using the new useGSAP hook with gsap + scroll trigger. When I use the hook, my scrolltrigger pinned section seems to disappear. When I use the original way (using useIsomorphicLayoutEffect with GSAP Context) it seems to work exactly as expected. Im using packages: - GSAP business - useGSAP version 2.1.1. - React version 18.3.1 - React DOM version 18.3.1 Unfortunatley when I create a minimal demo, both methods work fine Is there something I should be looking for, or am i not using the hook correctly? See video here for example => https://vimeo.com/947131601?share=copy // this works useIsomorphicLayoutEffect(() => { const ctx = gsap.context(() => { gsap.to("#voting", { scrollTrigger: { trigger: "#voting", pin: "#voting", start: "top top", end: "bottom top", }, }); }); return () => ctx.revert(); }, []); // this does not work useGSAP(() => { gsap.to("#voting", { scrollTrigger: { trigger: "#voting", pin: "#voting", start: "top top", end: "bottom top", }, }); }, []);
  10. tatanka

    Switch Array of SVG Component

    Hello everyone, I want to make some animations just like here: https://gsap.com/community/forums/topic/32504-loop-through-an-array-of-text-and-display-on-screen/?do=findComment&comment=175412&_rid=151858 but using Svg components. I basicaly want to switch between svg components instead of texts. My current work is here: https://stackblitz.com/edit/stackblitz-starters-egrwn8?file=components%2FLogo%2Findex.tsx Any help really appreciated!
  11. Hi everyone. I'd like to create an animation that plays in a loop and also plays when I scroll. Animation: animates the css clip-path property of the images according to the current index. Currently, when the component is mounted, the animation plays correctly but remains stuck on the last image of the array. And when I scroll, nothing happens. Does anyone have a solution or know where to find the bug ? Thank you in advance Demo link : https://stackblitz.com/edit/gsap-react-basic-f48716-ebgh4d?file=src%2FApp.js I was inspired by the following examples: https://codepen.io/GreenSock/pen/wvZjeGN?editors=1010 https://codepen.io/GreenSock/pen/XWzRraJ?editors=1010
  12. Hello! I encountered a problem when I was using the useGSAP hook for React, scrollTrigger, and content with dynamic height. The situation is as follows: somewhere on the page, we have a component with dynamic height, in this particular case we have tabs with their own content. Just below, there are expanding accordions. The height of the content in the tabs and accordions can vary. Further down the page, there is a block with GSAP animations (there will be several of them), which uses the React useGSAP hook. I have encountered 2 problems. The first problem is that, for example, the block with animation is not updated while opening an accordion. This can be clearly seen in this example - it contains the necessary minimum to see the error. When clicking on the accordion toggler, the animation start label remains in the same place. When scrolling to it with the accordion open, the animation fails. https://codepen.io/tis-cake/pen/OJGxdVG The second issue is related to passing dependencies into the useGSAP hook. If I understand correctly, one of the solutions to my problem is to pass the height of, for instance, the body tag as a dependency. When the accordion is expanded, the height of the body changes - and at this stage, do I need to update the animation? When passing this value into the dependencies array, the animation fails even with the accordion closed. Would u mind helping me with the understanding of the direction in order to solve this problem? I'm convinced I'm doing something wrong?
  13. Supachai

    Grid item view in React.js

    I'm new to GSAP and try to use it with Next.js (React.js). I understand Tween and Timeline, but still can't get my head around Flip. I want to make Grid item view just like the example, but with useGSAP in React. I still can't make it flip. Is there any similar example I can follow?
  14. gandarufuuu

    useGSAP() scope acting weird

    Hi all, I'm trying to apply an animation to a certain scope only, using useGSAPs scope option. The weird thing is, on my local react project it only works, if I add ".current" in {scope: ref.current}. Then, however, it also affects elements outside of the scope. If I only write {scope: ref}, the elements outside the scope aren't affected, but neither are the ones inside the scope. I tried recreating the issue in this stackblitz, but here's it's working as intended ?? https://stackblitz.com/edit/react-avrbpg?file=src%2FApp.js Any idea, what I could be doing wrong locally? I checked a million times that the ref is on the right div...
×
×
  • Create New...