Jump to content
Search Community

Search the Community

Showing results for tags 'react'.

  • 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 278 results

  1. Hi GreenSock team 👋 I'm working with Next.js 15 and trying to orchestrate animations across multiple components using a shared masterTimelinethrough context. Each component defines its own gsap.timeline() and then adds it to the global timeline via masterTimeline.add(). For example: I have two components: Boxand Nav. - Box has its tl with 4 tweens and inserts a label after the second tween (addLabel('afterSecondTween')). - Nav defines its own timeline and tries to insert it at that label inside the master timeline using masterTimeline.add(navTL, 'afterSecondTween'). 🎯 My goal is to synchronize timelines between different components, so that they run in sequence or in specific positions. 💣 The result: Nav always animates at the start of the timeline. ✅ I’ve confirmed that: - The Nav timeline is added with the same label name. - But it still plays immediately (as if the label had time = 0). 💬 My question is: Is it correct to insert timelines at labels from other components in GSAP + React? Is this synchronization possible? What is the correct or recommended way to synchronize animations between different components in GSAP and React? Is this pattern okay: 1. Each component creates its own timeline 2. One of them defines a label at a specific point 3. Another component inserts its timeline at that label Or... is there a better / more robust way to orchestrate animations across components in React using GSAP? Thanks in advance for your insights 🙏 Here’s a minimal CodePen that replicates the problem: 📎 CodePen
  2. Hi All. I am building a site based on shopify hydrogen (react, remix). SmoothScroll works correctly everywhere except where I need to reactively change the url without changing the current location on the page. I.e. for the user everything happens unnoticeably, it can be a simple add to cart via fetch or it can be a link click on NavLink component using preventScrollReset={true} flag. This means that no matter how high the user is on the page, he remains on it, without visible changes. However, when using SmoothScroll, every such action means that it must animate a smooth scroll to the block of the screen the user was on. Is there any way to disable scrolling after a reactive url change? Unless of course it's an anchor, anchors require scrolling.
  3. maruf3000

    How to create this kind of slider?

    The content on the right should change as I scroll down, vise versa. I wonder if you happen to know any website that has this kind of feature or the implementation way please. The above demo is from figma. Thanks.
  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. I've been tinkering with fabric.js in a SharePoint React webpart today, which worked fine - allowing me to render shapes. I added gsap to test animating shapes, and for basic movement of shapes it worked straight away. However - if I use the "rotation" property, it immediately throws "Invalid property", and "Missing Plugin" errors. I've narrowed it down specifically to rotation - moving shapes around, and easing them seems to work perfectly. Here the core code of the component in the webpart: import * as React from 'react'; import type { IMySharePointMenuProps } from './IMySharePointMenuProps'; import * as fabric from 'fabric'; import { gsap } from 'gsap'; export default class MySharePointMenu extends React.Component<IMySharePointMenuProps> { private canvasRef = React.createRef<HTMLCanvasElement>(); private canvas: fabric.Canvas | null = null; public componentDidMount(): void { if (this.canvasRef.current) { // instantiate canvas this.canvas = new fabric.Canvas(this.canvasRef.current, { backgroundColor: 'lightgray' }); // create a rectangle const rect = new fabric.Rect({ left: 100, top: 100, width: 30, height: 30, fill: 'blue', angle: 0, hasControls: false }); // add the rectangle to the canvas this.canvas.add(rect); // render this.canvas.renderAll(); // add a click handler to the rectangle rect.on('mousedown', function(options){ // when clicked, animate the rectangle to a new location, and rotate it gsap.to(rect, { duration: 2, left: 200, top: 100, rotation: 45, ease: "power1.inOut", onUpdate: () => { if (this.canvas) { this.canvas.renderAll(); } }, onComplete: () => { // do something else } }); }); } } public render(): React.ReactElement<IMySharePointMenuProps> { return ( <div> <canvas ref={this.canvasRef} style={{ width: 500 , height: 500 }}></canvas> </div> ); } // Clean up the canvas object public componentWillUnmount(): void { if (this.canvas) { this.canvas.dispose(); this.canvas = null; } } } Any ideas what's causing it ?
  7. Initially, I wanted to create a GSAP ScrollTrigger responsive split-screen pinning effect similar to what is showcased on deveb.co. However, I was never able to get it to work. As a result, I decided to simplify and go back to the basics, using this codepen project: OLD scroll left pin right mockup -- not responsive. It was during this process that I realized the root of my issue had always been the same: whenever the column pinning starts, it disappears, and when the animation ends, it reappears. I've spent hours searching through forums for solutions but haven't found a fix. I first tried using gsap.context(); to resolve the issue: // Scroll.jsx import React, { useLayoutEffect } from 'react'; import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; import './Scroll.css'; gsap.registerPlugin(ScrollTrigger); const Scroll = () => { useLayoutEffect(() => { let ctx = gsap.context(() => { ScrollTrigger.create({ trigger: ".gallery", start: "top top", end: "bottom bottom", pin: ".right", pinSpacing: true, markers: true, scrub: true, }); }); return () => ctx.revert(); }, []); return ( <> <div className="spacer"></div> <div className="gallery"> <div className="left"> <div className="detailsWrapper"> <div className="details"> <div className="headline"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> </div> <div className="details"> <div className="headline"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> </div> <div className="details"> <div className="headline"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> </div> </div> </div> <div className="right"> <div className="photos"></div> </div> </div> <div className="spacer"></div> <div className="spacer"></div> <div className="spacer"></div> </> ); }; export default Scroll; That didn't work, so I decided to use useGSAP(), but it still produces the same result. // Scroll.jsx import React, { useRef } from 'react'; import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; import { useGSAP } from '@gsap/react'; import './Scroll.css'; gsap.registerPlugin(ScrollTrigger); const Scroll = () => { const galleryRef = useRef(null); useGSAP( () => { ScrollTrigger.create({ trigger: galleryRef.current, start: "top top", end: "bottom bottom", pin: ".right", pinSpacing: true, scrub: true, markers: true, }); }, { scope: galleryRef } ); return ( <> <div className="spacer"></div> <div ref={galleryRef} className="gallery"> <div className="left"> <div className="detailsWrapper"> <div className="details"> <div className="headline"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> </div> <div className="details"> <div className="headline"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> </div> <div className="details"> <div className="headline"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> <div className="text"></div> </div> </div> </div> <div className="right"> <div className="photos"></div> </div> </div> <div className="spacer"></div> <div className="spacer"></div> <div className="spacer"></div> </> ); }; export default Scroll; I have reviewed the React & GSAP | GSAP | Docs & Learning, countless forums, and YouTube tutorials, but I’m still struggling to find a solution. I’m reaching out to you in the hope that you can help me. /* Scroll.css */ body { background: #EEF4FF; margin: 0; } .spacer { width: 100%; height: 50vh; background: #ddd; } .headline { background: #2D4E86; border-radius: 6px; height: 4em; width: 100%; } .text { margin: 0.8em 0 0 0; background: #2D4E86; border-radius: 6px; height: 1em; width: 100%; } .gallery { display: flex; outline: 1px solid red; height: auto; } .left { width: 50%; } .detailsWrapper { margin: auto; width: 80%; } .details { height: 100vh; outline: 1px solid green; display: flex; flex-direction: column; justify-content: center; } .right { position: sticky; top: 0; outline: 1px solid purple; width: 50%; height: 100vh; display: flex; flex-direction: column; justify-content: center; /* overflow: hidden; */ z-index: 1; } .photos { width: 40vw; height: 40vw; background: maroon; /* visibility: visible; */ } I’ve attached a video that visually demonstrates the issue, and I would be incredibly grateful for your assistance in resolving this. ScrollTrigger Pin Issue.mp4
  8. I use GSAP’s ScrollTrigger in my React app, and everything works perfectly in the local environment. However, after deploying to Vercel, I’ve encountered an issue with ScrollTrigger when switching routes. Here’s the behavior: When I navigate to a page, the ScrollTrigger positions (start and end markers) are not aligned with the actual content. For example, the start and end markers appear above the intended elements. (I noticed it in all my sections) If I refresh the page, the ScrollTrigger recalculates correctly, and everything works perfectly. Navigating to another route causes the same issue to arise until I refresh the page again. I’ve also noticed that I’m using the Swiper component in two routes at the bottom of the page, reusing the same component. This seems to cause similar issues even in my development server. (I have properly used context for this component) [Note: I have added lazy loading for components and don't have any lazy loading images] const Home = lazy(() => import("@/pages/Home/Home")); Here is a minimal useGsap code from my code: useGSAP(() => { const cards = gsap.utils.toArray( ".card" ) as HTMLElement[]; cards.forEach((item, i) => { gsap.from(item, { y: 50, duration: 1, opacity: 0, delay: i * 0.1, ease: "power2.out", scrollTrigger: { trigger: item, start: "top 90%", toggleActions: "play none none none", markers: true, }, }); }); }, []); Any advice on how to ensure ScrollTrigger recalculates properly? And the best practices to follow when using GSAP with React or Next.js
  9. Hi! I hope you're doing great. I'm facing some issues with the code. First of all, I couldn't figure out how to use the pin feature because I've mostly used GSAP with plain HTML, CSS, and JavaScript. Secondly, I couldn't understand the strange behavior of the animation. When I enter the start marker, the content disappears. However, the animation triggered by ScrollTrigger runs smoothly when I exit and re-enter through the end marker. import React, { useEffect, useRef } from "react"; import { gsap } from "gsap"; import pakistanMap from "./assets/pakistanMap.svg"; import worldMap from "./assets/worldMap.svg"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); const Extra = () => { const worldRef = useRef(null); const pkRef = useRef(null); const containerRef = useRef(null); useEffect(() => { gsap.to(worldRef.current, { scale: 0.1, opacity: 0, duration: 4, scrollTrigger: { trigger: containerRef.current, start: "top 30%", end: "bottom 30%", markers: { start: "start", end: "end", }, scrub: 1, // pin: true, // pin: worldRef.current, // pin: containerRef.current, }, }); }, []); return ( <main className="w-full overflow-x-hidden"> <header className="w-screen h-[70vh] bg-gray-800"></header> <section ref={containerRef} className="container flex flex-col gap-4 items-center justify-center bg-white" > {/* World Map */} <div ref={worldRef} className=" w-[500px] h-auto bg-black/20 z-20"> <img className="w-full h-full object-contain" src={worldMap} alt="World Map" /> </div> {/* Pakistan Map */} <div ref={pkRef} className=" w-[500px] h-auto bg-green-100"> <img className="w-full h-full object-contain" src={pakistanMap} alt="Pakistan Map" /> </div> </section> <footer className="w-screen h-[80vh] bg-gray-800"></footer> </main> ); }; export default Extra;
  10. Spaghetti

    Simple staggered animation issue

    I don't know why this isn't working as intended function MoviesList({ movies, onSelectMovie }) { const moviesList = useRef(null); useGSAP( () => { if (!movies.length) return; gsap.from(moviesList.current.querySelectorAll("li"), { opacity: 0, x: 120, // If you want movement, otherwise remove this line stagger: 0.2, duration: 0.5, ease: "power2.out", }); }, { scope: moviesList, dependencies: [movies] } ); return ( <ul className="list list-movies" ref={moviesList} > {movies?.map((movie) => ( <Movie movie={movie} key={movie.imdbID} onSelectMovie={onSelectMovie} ></Movie> ))} </ul> ); } function Movie({ movie, onSelectMovie }) { return ( <li onClick={() => onSelectMovie(movie.imdbID)}> <img src={movie.Poster} alt={`${movie.Title} poster`} /> <h3>{movie.Title}</h3> <div> <p> <span>🗓</span> <span>{movie.Year}</span> </p> </div> </li> ); } but this one which is exactly the same is working perfectly function WatchedMoviesList({ watched, onDeleteWatchedMovie }) { const watchedContainerRef = useRef(null); useGSAP( () => { if (!watched.length) return; gsap.from(".watched-list li", { opacity: 0, x: 120, stagger: 0.2, duration: 0.5, ease: "power2.out", }); }, { scope: watchedContainerRef } ); return ( <ul className="list watched-list" ref={watchedContainerRef} > {watched.map((movie) => ( <WatchedMovie movie={movie} onDeleteWatchedMovie={onDeleteWatchedMovie} key={movie.imdbID} /> ))} </ul> ); } function WatchedMovie({ movie, onDeleteWatchedMovie }) { return ( <li> <img src={movie.poster} alt={`${movie.title} poster`} /> <h3>{movie.title}</h3> <div> <p> <span>⭐️</span> <span>{movie.imdbRating}</span> </p> <p> <span>🌟</span> <span>{movie.userRating}</span> </p> <p> <span>⏳</span> <span>{movie.runtime}</span> </p> <button className="btn-delete" onClick={() => onDeleteWatchedMovie(movie.imdbID)} > x </button> </div> </li> ); } This is the issue I'm facing that the animation left isn't working properly and I can't figure it out
  11. hey that is a SOS call I going to develop a commecrial website in react, and need drawSvgPlugin. currently i make an sample little project in stackBlitz, and it is not recognize the llugin from the gsap lib - only from the gsap-trial lib I saw in pricing that the drawSvg is free use feature - even for commecrial websites. if i took it from gsap-trial - does it mean i have to pay on it? something n0t clear to me help please 🙏!! thanks
  12. I am trying to build a portfolio with multiple pages. The very first page is a loader screen with some text. Right after the loader screen finishes, the landing page shows up. The issue is that the text animation of "JAVED RASIN" gets triggered and completed while the loader screen is being displayed. It's simply not waiting for the loader to finish and then start the animation. Here is the stackblitz project - https://stackblitz.com/edit/github-sq9mef9f?file=app%2Fpage.tsx
  13. Saeiko

    Alternate overlapping sections

    I've started using gsap about a month or so ago in a nextJs project. It is phenomenal and I'm really enjoying using it, but I have hit a wall when trying to make certain overlapping animations. Here's what I want: - I have 4 containers. A, B C and D. - step 1: Container A is pinned and some animations run inside it. - Step 2: When A's pin is done, B is pinned behind it and is revealed when scrolling down (A goes up and we find B pinned underneath). - When A is out of the view, do some animations inside B, when they're done B is unpinned and by scrolling down C is revealed (kinda like the opposite of step 1) - Step 3: repeat step 1 Each container is its own component. I have done some research and found some threads that suggest putting the containers in an gsap.utils.toArray but I didn't think that would give me the effect I want. Please correct me if I'm wrong. I have made a simple demo that's a bit close to what I want. In the demo A is pinned, but when the pin is done B pushes A up. I managed to make the 2nd step work (B is pinned and when it's unpinned C is revealed) I have been trying to solve this for about a week now without proper results, your help would be much appreciated.
  14. It has to look so: but the most I manage to achive is: I don't know how to make the second side of the V shape, I will be thirled for help by fixing my code or simply give me a new match code. thanks in advanced. attached is the current react code I'm using: css: * { box-sizing: border-box; } html, body { height: 100%; min-height: 100%; font-family: Roboto, sans-serif; background: #e2e0e0; } main { display: flex; position: relative; flex-direction: column; width: 100vw; height: 100vh; overflow: hidden; align-items: center; justify-content: center; } .cell { position: absolute; top: 0; left: 0; width: 100%; font-size: 26px; font-weight: 500; color: rgba(0, 0, 0, 0.87); user-select: all; display: flex; align-items: center; justify-content: center; background: #eee; height: 70%; transform-origin: center center; } .picker { position: relative; overflow: hidden; width: 80vw; height: 90vh; border-radius: 2px; background-color: #fff; box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); } js: import { useRef } from 'react'; import gsap from 'gsap'; import { Draggable } from 'gsap/all'; import { useGSAP } from '@gsap/react'; gsap.registerPlugin(Draggable); const App = () => { const pickerRef = useRef(null); const cellsRef = useRef([]); useGSAP(() => { gsap.defaults({ ease: 'none' }); const picker = pickerRef.current; const cells = cellsRef.current; const proxy = document.createElement('div'); const myWrapper = gsap.utils.wrap(0, 0.871); const cellWidth = 75; const numCells = cells.length; const cellStep = 1 / numCells; const wrapWidth = cellWidth * numCells; const baseTl = gsap.timeline({ paused: true }); gsap.set(picker, { width: wrapWidth - cellWidth, }); cells.forEach((cell, i) => { initCell(cell, i); }); const animation = gsap .timeline({ repeat: -1, paused: true }) .add(baseTl.tweenFromTo(1, 2)); const draggable = Draggable.create(proxy, { type: 'x', trigger: picker, inertia: true, onDrag: updateProgress, onThrowUpdate: updateProgress, snap: { x: snapX, }, onThrowComplete: () => { console.log('onThrowComplete'); // TODO: animation that injects selected card title }, })[0]; function snapX(x) { return Math.round(x / cellWidth) * cellWidth; } function updateProgress() { animation.progress(myWrapper(draggable.x / wrapWidth)); } function initCell(element, index) { gsap.set(element, { width: cellWidth, scale: 0.6, x: -cellWidth, y: 0, }); const tl = gsap .timeline({ repeat: 1 }) .to(element, { duration: 1, x: `+=${wrapWidth}`, y: '+=70' }, 0) .to( element, { duration: cellStep, color: '#009688', scale: 0.778, repeat: 1, yoyo: true, }, 0.5 - cellStep ); baseTl.add(tl, index * -cellStep); } }, []); return ( <main> <div ref={pickerRef} className="picker"> {Array.from({ length: 5 }, (_, index) => ( <div key={index} ref={(el) => (cellsRef.current[index] = el)} className="cell" > <div className="cell-content">{`Card ${index + 1}`}</div> </div> ))} </div> </main> ); }; export default App;
  15. NadeemNJZ

    morphSVG TypeScirpt

    Hi, guyz I am Nadeem I am running into error that my svg is not actually morphing . Can anyone help me with this ....
  16. 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
  17. lebovsky

    dangerouslyInnerHTML

    Hey, everybody! I want to ask you. How can I work with elements with GSAP that come with dangerouslySetInnerHtml, because during animation inline styles are not written in them, although I can see through devtools that such an attempt is made (elements are highlighted, but nothing appears in them)
  18. Hi there, I've been learning and really enjoying GSAP! Thanks for the wonderful docs, learning materials, and forum. I want to create an effect of an infinitely moving horizontal line, which moves FASTER or SLOWER in reaction to scroll. So passively, let's say the line scrolls at "duration 5". - If I scroll down, I want the line to move faster, e.g. at duration 5 - adjusted scroll velocity = 2. - If I scroll up, I want the line to move slower, e.g. at duration 5 + adjusted scroll velocity = 8. Here's a minimal demo of both effects individually, but I haven't been able to successfully combine them. I've tried to manually adjust the duration variable through ScrollTrigger's onUpdate, using "getVelocity()", but that didn't seem to work. I've left it blank in the demo. If someone could point me in the right direction of how to approach this, I can try to do it in the demo myself! Thanks again. (not sure how to embed stackblitz demo directly) https://stackblitz.com/edit/react-ejg7zb?embed=1&file=src%2FApp.js
  19. I 've been trying to solve this for days seeing the community and referring topics here in GSAP and tried various method but still could not solve this issue. As you can see from the code there are three div's and the second div has some content and I need to make one of the div's in it scroll horizontally while scrolling vertically. I have pinned the second div inorder to complete the horizontal scroll. It works sometime when I make corrections on the code and hit save. But when I refresh the page it stops working all the same. Also sometimes it works only when the cursor is on the left most side the horizontal scroll works. Any suggestions / help ? I have provided the codesandbox link for the same. https://codesandbox.io/p/sandbox/horizontal-scroll-q55rs3
  20. I have some simple sections being rendered in my React component but they are dynamically generated from a JSON file. All I need to do is pin each section to the top of the screen for an amount of time and then allow scrolling to the next section. I need to get the selector ID for each section and use that to identify the section as I scroll in and out. Do I need to create an animation for each section like this or can I use the class storymode-section and hit them all in one go? 'use client'; import React, { useEffect, useRef, useState } from 'react'; import { gsap } from "gsap"; import { useGSAP } from '@gsap/react'; import { ScrollTrigger } from "gsap/ScrollTrigger"; import { FakeStorymodeData } from '@/utils/FakeStorymode'; gsap.registerPlugin(useGSAP); gsap.registerPlugin(ScrollTrigger); interface StorymodeContentGSAPProps { } export const StorymodeContentGSAP: React.FC<StorymodeContentGSAPProps> = (props: StorymodeContentGSAPProps) => { const scrollRef = useRef<HTMLDivElement>(null); const [activeSection, setActiveSection] = useState<string>('Section 1'); const [selectors, setSelectors] = useState<string[]>([]); useGSAP(() => { // add a ScrollTrigger for each section that will pin it to the top of the viewport for the duration of the viewport selectors.forEach((selector) => { const sectionElement = scrollRef.current?.querySelector(`#${selector}`); if (!sectionElement) return; gsap.to(sectionElement, { scrollTrigger: { trigger: sectionElement, start: "top top", end: "bottom top", pin: true, pinSpacing: false, onEnter: () => setActiveSection(selector), onLeaveBack: () => setActiveSection(selector), } }); } ); }, {dependencies: [selectors], scope: scrollRef}); useEffect(() => { // create an array of the section.id's const sectionIds = FakeStorymodeData.map((section) => section.id); setSelectors(sectionIds); }, []); return ( <div ref={scrollRef} className="w-full h-full flex flex-col justify-start flex-shrink-0 overflow-y-auto prose "> { FakeStorymodeData.map((section, index) => { return ( <section id={section.id} key={index} className={"storymode-section flex flex-col justify-start w-full p-2 mb-64 " }> <header className="w-full bg-gray-300 p-2 rounded"><strong>STICKY HEADER</strong></header> <h2>{section.header}</h2> <p>{section.content}</p> </section> ); }) } </div> ); }
  21. Hello! I Next.js I got a SectionHeadline component that I need to split into lines to apply animations. The problem is that when I apply SplitText plugin (like I do below) it messes with all of my nested components (it includes things lik WordsLoop slider that has some ScrollTriggers within. All of those scrolltriggers break and nothing works like expected. I wonder what am I doing wrong. The line splitting code (adding divs for each line works), but interestingly on autoreload it gives an error: NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. When I refresh the page, it's fine. What am I doing wrong? Thank you! "use client"; import { useGSAP } from "@gsap/react"; import gsap from "gsap"; import { SplitText } from "gsap/SplitText"; import type { PortableTextProps } from "next-sanity"; import { PortableText } from "next-sanity"; import { useRef } from "react"; import { WordsLoop } from "~/components/words-loop"; import { cx } from "~/lib/utils/styled"; export function SectionHeadline({ value, className, ...rest }: Pick<PortableTextProps, "value"> & React.ComponentPropsWithoutRef<"div">) { const headlineRef = useRef<HTMLDivElement>(null); useGSAP( () => { gsap.registerPlugin(SplitText); const split = new SplitText("p", { type: "lines" }); }, { scope: headlineRef } ); return ( <div ref={headlineRef} className={cx("block px-32 text-center font-serif text-title-90", className)} {...rest} > <PortableText value={value} components={{ marks: { strong: (p) => { return <strong className="font-heading text-title-70">{p.children}</strong>; }, em: (p) => { return <em className="italic">{p.children}</em>; }, wordsLoop: (p) => { if (!p.value.words) { return <span className="font-heading text-title-70">{p.children}</span>; } return <WordsLoop words={p.value.words} />; }, }, }} /> </div> ); }
  22. useEffect(() => { gsap.registerPlugin(ScrollTrigger, ScrollToPlugin); const section: any = scrollRef.current; const scrollContainer = section.querySelector(".scroll-container"); const scrubTween= gsap.to(scrollContainer, { x: () => -(scrollContainer.scrollWidth - section.offsetWidth + 104) + "px", ease: "none", scrollTrigger: { trigger: section, start: "center center", end: () => "+=" + (scrollContainer.scrollWidth - section.offsetWidth), pin: true, anticipatePin: 1, invalidateOnRefresh: true, scrub:0, onUpdate: (self) => { if (self.direction === -1) { // Scrolling upwards gsap.set(scrollContainer, { x: 0 }); // Reset horizontal scroll position } }, }, }); return () => { ScrollTrigger.getAll().forEach((trigger) => trigger.kill()); }; }, [])
  23. Hello, first of all I apologize if my English is not very good. I don't write the language fluently This is my first post and I'm new to GSAP. Believe me, I didn't want to post this without trying to solve the animation problem first. I have an animation where, at the starting point, the cards appear stacked one below the other. As you scroll, each card moves up and eventually exits the screen, while the bottom card adjusts to position y:0. The problem arises when the animation is reversed. As shown in the preview, the cards do not return to their correct positions and the animation does not complete as expected. I hope someone can help me with this. Thank you! PD: Reload the page if the animation doesn't work as expected, I don't know what's going on. After reloading, it works fine. PREVIEW: https://stackblitz.com/edit/gsap-react-basic-f48716-vwwr1u?file=src%2FApp.js
  24. I've been trying all night to install and import Split text on react, I've tried various ways to import the plugin and this is my current code. import React, {useRef} from 'react' import { useGSAP } from '@gsap/react' import gsap from 'gsap' import { SplitText } from "gsap/SplitText" gsap.registerPlugin(SplitText) Here's the error message I keep getting: Internal server error: Failed to resolve import "gsap/SplitText" from "src/components/Onboarding.jsx". Does the file exist? On further investigation in the node_modules/gsap directory, I realized the SplitText.js file actually doesn't exist, has this feature been deprecated or am I just installing it wrong?
  25. Hello there, at first it works good, but after i enable pin it just jumps to the bottom and only works when scrolling back up, how can i pin it the same position and after the revealing is done, and then i can scroll pass that, thank you in advance, i attached a video (sorry for the compression, 1mb limit) const About = () => { gsap.registerPlugin(useGSAP,ScrollTrigger); const text = new SplitType('#target') gsap.from(text.chars, { scrollTrigger: { trigger: "#target", start: 'top 70%', end: 'top 00%', scrub: true, pinSpacing: false, markers: false }, opacity: 0.1, y: 20, stagger: 0.01 }) return ( <div className='about content-center items-center text-center overflow-hidden py-12 p-5 lg:px-72'> <p id='target' className='lg:text-5xl text-3xl font-bold text-neutral-200'> I’m Dilukshan, a fullstack web developer from Sri Lanka with a passion for creating dynamic and engaging digital experiences. </p> </div> ) } Desktop 8-6-2024 1-34-01 Am (2) (2) (2) (2).mp4
×
×
  • Create New...