Jump to content
Search Community

Rodrigo last won the day on April 28

Rodrigo had the most liked content!

Rodrigo

Administrators
  • Posts

    6,633
  • Joined

  • Last visited

  • Days Won

    287

Everything posted by Rodrigo

  1. Hi, That's an interesting site to say the least. I inspected with devtools and saw that it actually uses two different sets of images. This is the thumbs container: And this is the feed (single column) one Now how the animation is achieved and which elements are being animated, honestly I couldn't tell you but if you set the opacity of the thumbs container to zero like this: <div class="page__modal home__index__modal" style="visibility: initial; opacity: 0;"> You'll see the scroll bar of the feed element right behind this, so basically the developer uses two different elements, hides immediately the thumbs view using visibility (hidden/initial) and then only animates the elements in the feed section, that's why the scroll position is remembered for saying it in some way, because when you're on the thumbs view only that scroll changes. Here you can see the first image behind the thumbs: The trick in this website is all about timing and which set of images are the ones being animated. As you can see your setup and approach is far different than this website so I doubt you'll get the same result, especially when it comes to the scrolling part. I'd recommend you to have a look at this demo in order to get an idea of switching between a grid and columns, of course this uses Flex and not Grid, but the approach should be similar: https://codepen.io/GreenSock/pen/zYqLjre Hopefully this helps. Happy Tweening!
  2. Hi @Jc Denton and welcome to the GSAP Forums! I'm not 100% sure how feasible this is, at least not in a simple way. It must be possible but it could require quite a bit of custom logic, but again I'm not sure. We have this demo that predicates on every section's height being 100vh with the snapping you're looking for: https://codepen.io/GreenSock/pen/NWxNEwY The issue is that IDK, at the top of my head, how to make this work with different heights TBH. Then we have this demo that layers the elements with different heights but there is no jump to section in them: https://codepen.io/GreenSock/pen/jOerKOb It's a matter of mix and matching that, again, I don't know right now how to approach in a quick and simple way. I'll see if I can think of something or if another user can chime in and shed some light on this. Sorry I can't be of more assistance. Happy Tweening!
  3. Hi, I think this is a bit of an edge case. This is the best solution I was able to come up with and I can't guarantee you that it'll work 100% of the times, so you'll have to test and see what happens: https://codepen.io/GreenSock/pen/eYojqEB Here is the debug view: https://cdpn.io/pen/debug/eYojqEB Hopefully this helps. Happy Tweening!
  4. Hi, Mainly the issue is that when using invalidateOnRefresh with ScrollTrigger your values need to be function based. This is what was happening, invalidateOnRefresh was flushing the starting values of the scale tween, but nothing more. The final value was always the same. This seems to fix the problem: let logoToScale = () => (window.innerWidth / logo.getBBox().width) * 5; const timelineHeader = gsap.timeline({ scrollTrigger: { id: "ZOOM", trigger: "div.landing", scrub: true, start: "top top", end: "+=100% 0", pin: true, markers: true, invalidateOnRefresh: true } }); timelineHeader.to(logo, { duration: 1.5, ease: "none", scale: () => logoToScale() }); Here is a fork of your demo: https://codepen.io/GreenSock/pen/WNWgaqZ Hopefully this helps. Happy Tweening!
  5. Hi, You might want to have a look at our learning resources regarding useGSAP: https://gsap.com/resources/React Most specifically at how contextSafe works, because that could be the missing piece for you here. Also check this video as well: We have a collection of React starter templates on Stackblitz that could help as well: https://stackblitz.com/@gsap-dev/collections/gsap-react-starters Happy Tweening!
  6. Hi, Yeah I think the issue was more an order of operation one rather than anything else. When to clear the styles from the gallery items was the key. Also I used scale: true because in your original demo you have that setting. I changed the image as well in order to make it more clear if it gets distorted as well. Here is the demo updated: https://codepen.io/GreenSock/pen/vYMzKZx Happy Tweening!
  7. Hi, I don't have time to go through all your HTML and CSS, but I believe that is creating a problem where not enough scrolling is generated to accommodate all the animations you want to create, that's why using clamp in the end configuration object forces the animation to be completed in that amount of scroll: let scrollHome = gsap.timeline({ scrollTrigger: { trigger: '#main', start: "top top", end: 'clamp(+=5000)', pin: true, markers: { startColor: 'green', endColor: 'red', }, scrub: 1 } }); You might want to have a look at this video @Cassie made on the subject: Hopefully this helps. Happy Tweening!
  8. Hi @aleks3650 and welcome to the GSAP Forums! There is far too much code in here and without a minimal demo there is not a lot we can do. The first error you're getting is mostly a React related one and not a GSAP related one: https://dev.to/collegewap/fix-rendered-fewer-hooks-than-expected-in-react-3757 https://medium.com/@jonchurch/how-to-fix-react-error-rendered-fewer-hooks-than-expected-e6a378985d3c The issue with the target undefined, that means that the element you're passing to GSAP is undefined most likely because of that conditional rendering block you have here: {choosed ? ( <h3> <span className="AreaInfo" ref={lowerref}> XXXXXXXXXXX km² </span> </h3> ) : ( // {NameFun(newSize) || "Area"} <div className="buttonContainer"> <button className="less" onClick={() => handleCompare("less")}> smaller </button> <button className="more" onClick={() => handleCompare("more")}> bigger </button> </div> )} When choosed is falsy lowerref is no longer a DOM element but is undefined: useGSAP( () => { gsap.to(lowerref.current, { // UNDEFINED -> WARNING! duration: 0.9, delay: 0.1, text: newSize, ease: "bounce.inOut", }); }, { dependencies: [AnotherCountryInfo] } ); I would suggest you to use revertOnUpdate in the useGSAP hook, but I'm afraid that it won't fix the logic issue of the ref not being defined. You should look into that first. We have a collection of starter templates in Stackblitz where you can fork one of those and create a minimal demo: https://stackblitz.com/@gsap-dev/collections/gsap-react-starters Happy Tweening!
  9. Yeah this is mostly a React related thing and not a GSAP related one. We need to keep our focus on GSAP related issues. You should get more knowledge on react components, components communication and state management, all react features that fall outside the scope of these free forums. If you have a specific GSAP related question we'd be happy to look into that. Good luck with your project! Happy Tweening!
  10. Hi, In React always use the useGSAP hook, is far simpler and cleaner: https://gsap.com/resources/React Here is a simple demo that uses the useGSAP hook with GSAP MatchMedia: https://stackblitz.com/edit/vitejs-vite-pfhzkf?file=src%2FApp.jsx Also in your codepen you're using the same element as the trigger: gsap.to(".work-block", { x: () => horizontalSection.scrollWidth * -1, xPercent: 100, scrollTrigger: { trigger: ".work-block", // FIRST TRIGGER start: "center center", start: "0% 50%", end: "+=2000px 30%", pin: ".work-wrapper-main", scrub: true, invalidateOnRefresh: true, markers: true } }); gsap.to(".work-block-2", { x: () => horizontalSection2.scrollWidth * -1, xPercent: 100, scrollTrigger: { trigger: ".work-block", // FIRST TRIGGER AGAIN HERE!!! start: "center center", start: "0% 50%", end: "+=2000px 30%", pin: ".work-wrapper-main-2", scrub: true, invalidateOnRefresh: true, markers: true } }); Changing that to trigger: ".work-block-2" seems to work the way you expect. Hopefully this helps. Happy Tweening!
  11. You have a Section component like this: <Section> <Box /> </Section> Instead of that just have everything inside that Section component and create the ScrollTrigger instance inside that component. Creating the instance in the child component, while needing or using a selector from a parent component is a far more complex setup that you should avoid if possible, instead of having the code in the Box component have the code in the Section component. Happy Tweening!
  12. Hi, In this case the Observer Plugin might be a better fit actually: https://gsap.com/docs/v3/Plugins/Observer/ https://codepen.io/GreenSock/pen/XWzRraJ Here is a demo that mixes ScrollTrigger with Observer: https://codepen.io/GreenSock/pen/ExEOeJQ Hopefully this helps. Happy Tweening!
  13. Yeah I missed that, sorry. That is a more convoluted case, in React child components are rendered before their parents so the element with the section class won't be rendered when that runs. If I was you I'd avoid this setup and keep everything inside the same component in order to make your life easier. If you can't then this is more related to how these type of situations are handled in React rather than a GSAP related issue or even a scoping issue TBH. Happy Tweening!
  14. Hi, There are no type definitions for the helper function, what you can do is tell TS that there will be an error above the import statement and provide a short description about it so other devs know about it: // @ts-expect-error: No defs provided import { horizontalLoop } from './helpers/horizontal-loop'; https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#-ts-expect-error-comments That is actually working on a demo here in my local machine. Hopefully this helps. Happy Tweening!
  15. Hi, There is nothing wrong with adding event listeners by hand, the code in the docs is good as long as you remove the event listener. I'm just saying that is better to just use the React way for this, nothing more. There will be times when you'll have to manually add an event listener, but most of the time using the approach React provides is the best choice. Yep, keep in mind that useGSAP uses GSAP Context under the hood: https://gsap.com/docs/v3/GSAP/gsap.context() So basically is a cleaner and simpler way to use the context add method: https://github.com/greensock/react/blob/main/src/index.js#L34 Happy Tweening!
  16. Hey @NickWoodward, Since you already created a thread where we're discussing this, let's better focus our attention to that thread, ok? Happy Tweening!
  17. You're right but you can always use a ref for that: <Section className="section-1" ref="section"> <Box></Box> </Section> useGSAP(() => { const boxTl = // some irrelevant paused tl ScrollTrigger.create({ trigger: section.current, start: "top 80%", onEnter: () => boxTl.play(), }); }, { scope: section, }); Hopefully this helps. Happy Tweening!
  18. Hi, I looked at your demo and I can't see any jumps, maybe the issue is just a perception that stems from the easing function you're using right now. By default you have expo.out, that will accelerate the animation a lot at the start of it. You can check our ease visualizer to see that. If you change that to none, you won't see any jumps in the animation: https://gsap.com/docs/v3/Eases/ Hopefully this helps. Happy Tweening!
  19. Hi, Why are you attaching an event handler like this in React? ref?.current?.addEventListener('click', contextSafeClick); That is most definitely not the way to do this, use onClick on the element and use contextSafe to wrap that event handler outside the scope of the useGSAP hook, like this: const { contextSafe } = useGSAP(() => {}); const clickHandler = contextSafe(() => { gsap.timeline(); // ... }) as React.MouseEventHandler; Then in your JSX <div {...props} className={classes} ref={ref} onClick={clickHandler}> <div className="line w-full h-[2px] bg-slate-400"></div> <div className="line w-full h-[2px] bg-slate-400"></div> <div className="line w-full h-[2px] bg-slate-400"></div> <div className="line-wrapper absolute top-0 left-0 flex items-center h-full w-full"> <div className="line hidden w-full h-[2px] bg-slate-400"></div> </div> </div> Using your current approach the event handler is being added twice as well since you have to remove the event handler manually, that is why is better to use the attributes React offers to do this: https://react.dev/learn/responding-to-events https://react.dev/reference/react-dom/components/common#react-event-object Hopefully this helps. Happy Tweening!
  20. Hi, I'm afraid that even using vector-effect as an attribute still causes the same problem, here is a fork of the last demo without it: https://codepen.io/GreenSock/pen/VwNGXZL Beyond that and dynamically adjust the path on screen resize (as suggested in the thread @PointC linked) I don't know what else can be done TBH. Sorry I can't be of more assitance. Happy Tweening!
  21. Hi, Everything looks OK to me, the only thing you might want to check is the type definition you're using for contexSafe in this case: const handleMouseMove = contextSafe((e: React.MouseEvent) => { const rect = buttonRef.current.getBoundingClientRect(); const { top, left } = rect; xTo.current(e.clientX - left); yTo.current(e.clientY - top); }); This thread and the link in it can help you if you run into any issues when typescript is compiling: Happy Tweening!
  22. This is about type casting as explained in this thread Hopefully this helps Happy Tweening!,
  23. Hi, Is better in this cases to just clear the inline styles before creating the Flip animation and store everything in a GSAP Context instance in order to easily revert everything: https://gsap.com/docs/v3/GSAP/gsap.context() Here is a fork of your demo that actually uses Flip.from() instead of to(), also is a good idea to not add ScrollTrigger configuration to a Flip instance but rather to store the Flip animation in a constant and then use that in a ScrollTrigger config, because of the way Flip instances work internally: https://codepen.io/GreenSock/pen/vYMzKZx Hopefully this helps. Happy Tweening!
  24. Hi, Yeah that sounds like a more convoluted thing to do and a bit beyond the scope of these free forums. Unfortunately we don't have the time resources to create custom complex solutions for our users, sorry. We do offer paid consulting services and you can post in the Jobs & Freelance forums to get help there. The one advice I can give you is to forget about React and ScrollTrigger right now, the reason? Super simple you just want to animate some elements horizontally, nothing more. Sure the animation and HTML/CSS setup is the complex part here but both React and ScrollTrigger will be adding an extra layer of complexity to this that you don't have to focus on at this point. Try to move the elements to the left, maybe give the panels a position relative and the cards position absolute, and then as the panels move to the left move those elements to the right using the container animation feature: https://gsap.com/blog/3-8/#containerAnimation Also you can translate the cards to the right using just regular animations as part of the same timeline as well. As you can see there are options but what you're trying to achieve is not the simplest thing. Not the most complex one but definitely not simple. This is more about taking it one step at a time and build from there. If in that process you have some GSAP related questions, don't hesitate to post either in this thread or create a new one if you prefer. Happy Tweening!
  25. Hi, You shouldn't have to worry about scoping with contextSafe because the scope being used for the selectors you passed in the useGSAP hook is the same. Take this for example: const { contextSafe } = useGSAP(() => {}, { scope: container // React ref }); So we're passing a scope that is actually a ref. Then in a specific method you do this: const myHandler = contextSafe(() => { gsap.to(".box", { x: 200, duration: 1, stagger: 0.1, }); }); That will basically target all the elements with the class box inside the scope you passed in the useGSAP hook, so it would be like this: gsap.to(container.current.querySelectorAll(".box"), { ... }); Finally you're right about contextSafe and recording GSAP instances for cleaning up. Under the hood what the useGSAP hook is doing is creating a GSAP Context instance, so contextSafe adds the GSAP Tweens/Timelines and other instances to that particular GSAP Context instance, so that's why it uses the same scope and everything gets reverted when the component is unmounted. Hopefully this clear things up. Happy Tweening!
×
×
  • Create New...