Jump to content
Search Community

Rodrigo last won the day on April 17

Rodrigo had the most liked content!

Rodrigo

Administrators
  • Posts

    6,507
  • Joined

  • Last visited

  • Days Won

    282

Everything posted by Rodrigo

  1. The logic for the text elements seems to be working as expected in my demo, here is a fork without ScrollTrigger, just a timeline that runs endlessly and loops back and forth just to show that: https://codepen.io/GreenSock/pen/YzMLmVM The whole idea with that loop is to add animations to the timeline for every element except the first one: d1sections.forEach((section, i) => { const previous = d1sections[i - 1]; if (previous) { tl.from( section, { y: 700, opacity: 0 }, "+=1.5" ).to( previous, { y: -20, opacity: 0 }, "<" ); } }); This is the same codepen with the ScrollTrigger configuration in it: https://codepen.io/GreenSock/pen/vYMjodo That does what you said you need, have the first one visible, fade out/in the current and next and leave the final visible. The tricky part here is tie everything to the videos. This fork of the last codepen seems to use the onEnter and onEnterBack callbacks correctly to play/reverse the videos (open it in a new window and check devtools for the logs in the console as you scroll): https://codepen.io/GreenSock/pen/xxezKOo Is important to note that I created the ScrollTrigger instances for the videos before creating the ScrollTrigger that pins the content in order to avoid issues with the calculations ScrollTrigger needs to make. Hopefully that will give you a good starting point and help you understand the logic to do the rest of the things you want to. Happy Tweening!
  2. Hi, The logic for the texts in your last demo is completely different from the one I posted in my demo. A solution has already been provided and you stated that it works, yet you changed the logic for something that it doesn't. Any particular reason why did you changed it?
  3. Couldn't really tell you TBH. We don't have the time resources to solve HTML/CSS issues for our users, is beyond the scope of what we don in these free forums. Finally I forgot to set the sandbox permissions sorry. By default forks are set as drafts and are private. I updated it and it should be public now: https://codesandbox.io/p/sandbox/gsap-scrolltrigger-forked-r5q7k8?file=%2Fsrc%2Fcomponents%2FExperiencePage%2FExperiencePage.tsx Happy Tweening!
  4. Yeah that sounds more like a browser rendering specific problem rather than a GSAP one, honestly I don't know what else can be done. Maybe this threads can help: Happy Tweening!
  5. Hi, I never used Lenis with GSAP and React so I couldn't really tell you about it. This does look odd to me TBH: useEffect(() => { function update(time) { lenisRef.current?.lenis?.raf(time * 1000) } gsap.ticker.add(update) return () => { gsap.ticker.remove(update) } }) That useEffect hook doesn't have any dependencies, so every time that component re-renders all that is called again, I would use an empty dependencies array, but they must have a reason for suggesting that. Also Lenis is not a GSAP product so we can't really offer support for it, we have our own smooth scrolling solution in ScrollSmoother: https://gsap.com/docs/v3/Plugins/ScrollSmoother/ Finally performance is a really deep topic and most likely this is tied to perhaps the Lenis react wrapper eating quite some resources and creating this rather than a GSAP specific problem and I don't recall other threads in the forums on this particular subject. Sorry I can't be of more assistance, hopefully other users with more experience with lenis and react can chime in. Happy Tweening!
  6. Hi, I forgot to mention in my previous post, we have our own useGSAP hook that simplifies using GSAP in React quite a bit. You can learn more about it here: https://gsap.com/resources/React Finally we have a collection of React starter templates in Stackblitz: https://stackblitz.com/@gsap-dev/collections/gsap-react-starters Happy Tweening!
  7. Hi @AaronRF and welcome to the GSAP Forums! Thanks for the kind words, we certainly hope seeing you around and creating amazing stuff with GSAP! The issue is super simple, even though MatchMedia was reverting when the breakpoint was passed, you weren't removing the event handler on the click event, so once the event handler was added to the click event was still there. This seems to work the way you intend: let mm = gsap.matchMedia(); mm.add("(min-width: 800px)", () => { const sliderContainer = document.querySelector("#CardContainer"); const buttonsContainer = document.querySelector("#buttons-container"); // ... function clickHandler(event) { const buttonId = event.target.id; event.target.disabled = true; if (buttonId === "btnLeft" && currentIndex > 0) { moveSlider("left"); } else if (buttonId === "btnRight" && currentIndex < totalCards - 4) { moveSlider("right"); } }; buttonsContainer.addEventListener("click", clickHandler); return () => { buttonsContainer.removeEventListener("click", clickHandler); }; }); This is a fork of your demo: https://codepen.io/GreenSock/pen/KKYRJwo Hopefully this helps. Happy Tweening!
  8. Hi, Indeed using a fix height is a solid approach and if it works then use it. Just as an FYI you can also use the refresh method after a new image(s) are loaded: https://gsap.com/docs/v3/Plugins/ScrollTrigger/static.refresh() Here is a demo that adds new elements emulating an ajax response, but the approach is the same: https://codepen.io/GreenSock/pen/OJdvNpq Happy Tweening!
  9. Ahh yeah I see what you mean now. That can definitely be done but requires a bit of custom logic in order to get those elements. That is beyond the scope of what we do in these free forums, unfortunately we don't have the time resources to provide free general constulting and create complex custom solutions for our users. We offer paid consulting services and you can post in the Jobs & Freelance forums to get help there as well. My first approach would be to loop through the elements and create a lookup table/object that stores the position of each element either using getBoundingClientRect or the offset positions (based on the positioned parent element) and based on the x and y values reported by Draggable you can check which elements are in the visible section of the container: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft Happy Tweening!
  10. Hi, I don't have time to update your demo now, but you should look into the Flip Plugin: https://gsap.com/docs/v3/Plugins/Flip/ This demo uses Flip and ScrollTrigger scrub and is fully responsive, it should provide a solid starting point: https://codepen.io/GreenSock/pen/bGxOjeP Hopefully this helps. Happy Tweening!
  11. Hi @Joseph L and welcome to the GSAP Forums! This mostly comes from the fact that you are overcomplicating this quite a bit and your JS is super convoluted. I simplified the part of the texts for you in this demo: https://codepen.io/GreenSock/pen/jORxaOo I left the part of the videos almost intact with the exception of the onLeave and onLeaveBack callbacks in order to not hide the first element when the user scrolls back and the last one when the user scrolls past the final section. I believe that this part can be simplified as well and maybe added to the initial loop, but we don't have the time resources to solve this logic for you. You can look into adding some call methods to the timeline in order to do that: https://gsap.com/docs/v3/GSAP/Timeline/call() Hopefully this helps. Happy Tweening!
  12. Hi, We have a collection of GSAP and React starter templates in Stackblitz: https://stackblitz.com/@gsap-dev/collections/gsap-react-starters This demo uses the approach of storing a GSAP Timeline in a ref: https://stackblitz.com/edit/gsap-react-basic-f48716?file=src%2FApp.js Just to be clear, you can store GSAP Tweens/Timelines and other instances in state. The main thing to consider if is actually necessary to do that, like the need to pass said instance onto the JSX or as a prop to a child component. Normally that is not needed and instances are used inside the same component in the JS part of it (before the return statement of the functional component), so using a ref doesn't trigger a re-render that could be completely unecessary. Hopefully this helps. Happy Tweening!
  13. You can always try the search in our main forums: https://gsap.com/community/forums/forum/11-gsap/ Although, as with any other search tool, you could get a lot of results based on your search terms. Other option is to search in google using the forums URL as the site parameter. Just type this in the search input on google: scrolltrigger modal site:gsap.com And it'll search for all the indexed results for scrolltrigger modal on our forums. Of course replace scrolltrigger modal with your terms. The demo was made yesterday in the afternoon so is fresh out of the oven 👨‍🍳 🤌 Happy Tweening!
  14. Hi @Jumaworks, In fact with the latest update of the Horizontal Loop helper function Jack made, there is no need for convoluted conditional logic blocks like the one you have in your demo: useGSAP( () => { const boxes = gsap.utils.toArray('.box'); gsap.set(boxes, { backgroundColor: gsap.utils.wrap(colors), }); const mm = gsap.matchMedia(); mm.add('(min-width: 769px)', () => { const loop = horizontalLoop(boxes, { repeat: -1, }); }); }, { scope: boxesContainer, } ); Just let MatchMedia and GSAP Context do the reverting work and heavy lifting for you! Simple, easy and clean (like we love our code around here! 😉) Here is a simple demo: https://stackblitz.com/edit/vitejs-vite-wunbqy?file=src%2FApp.jsx&terminal=dev Happy Tweening!
  15. Hi, Actually if you inspect the lenis website you'll see that they're using an ::after pseudo element: Have you tried masking? @mvaneijgen created this super useful thread on the subject, that could really help: Happy Tweening!
  16. Hi, I believe the API hasn't changed over the years, just use the autoKill config: gsap.to(myDiv, { duration: 2, scrollTo: { y: 400, autoKill: true }, ease: "power2", }); Hopefully this helps. Happy Tweening!
  17. Hi @Jean-francois and welcome to the GSAP Forums! Creating something like that is not really simple but I think the best option here could be to use the Observer Plugin and the callbacks it offers such as onChangeX, onChangeY, onUp, onDown, onLeft and onRight: https://gsap.com/docs/v3/Plugins/Observer/ You beat me and found a solution, but still Observer could be helpful and you could take a look at it. Anyways, is great to hear that you were able to solve it 🥳 Happy Tweening!
  18. Hi, Just move the configs for duration, ease, scrolltrigger and stagger to the to config section: gsap.fromTo( titleSplit.chars, { y: -100, }, { y: 0, stagger: 0.1, duration: 1, scrollTrigger: { trigger: titleSplit.chars, start: isDesktop ? 'left 80%' : 'top 80%', end: isDesktop ? 'right 20%' : 'bottom 20%', toggleActions: 'play reverse play reverse', containerAnimation: isDesktop ? containerAnimation : '', markers: true, }, } ); Here is a fork of your demo with those changes: https://stackblitz.com/edit/stackblitz-starters-rdigb3?file=app%2Fpage.js Hopefully this helps. Happy Tweening!
  19. Hi, That's because of the way the Horizontal Loop helper function works, nothing more. The helper function moves a group of items in the direction you tell it to (reversed config option) and when that element reaches the edge of it's parent is move to the opposite side nothing more. Sure enough sounds simple but the logic behind it in order to make it fully responsive and performant is not 😉. https://gsap.com/docs/v3/HelperFunctions/helpers/seamlessLoop With that being said, why are you trying to animate elements in different parents or outside the parent? I fail to see the logic behind it. We have these demos that use the Observer Plugin and ScrollTrigger to change the direction and speed of the loop instance: https://codepen.io/GreenSock/pen/zYaxEKV https://codepen.io/GreenSock/pen/GRwePYw Finally is worth noticing that you have only two elements in your loop, so for obvious reasons there is going to be a jump and empty space when the elements have to be placed at the start again. Is a good idea to have enough elements to use the entire width of the screen ( in large screens of course). Hopefully this clear things up Happy Tweening!
  20. Hi @Jay LV and welcome to the GSAP Forums! Sorry to hear about the troubles. Unfortunately without a minimal demo there is not a lot we can do, perhaps you can share a small code snippet here in the thread (keep it as small as possible please) and also follow the instructions in this guide: https://gsap.com/resources/Wordpress/ Hopefully this helps. Happy Tweening!
  21. Hi, Is really hard to know what you're trying to do without a minimal demo. I don't know any limitation that wouldn't allow you to drag elements of a grid, maybe the only suggestion would be to not drag the direct child of the grid parent container, just as a precaution if you end up reparenting the elements, if not that shouldn't be an issue at all. Maybe this demo can demonstrate the capacities the Draggable Plugin has: https://codepen.io/GreenSock/pen/Pqwxvw Happy Tweening!
  22. Hi, I don't think you need to store the MatchMedia instance in a ref. Will you add to that instance later on in your code? If not there is no need IMHO. Agreed, that looks cumbersome and verbose, but given the fact that you need that to play/reverse based on a state property there isn't a lot of other alternatives TBH. I would try to avoid using state to toggle the instance, but if you actually need that state then use it. Another thing you could try is see if the hamburger component has an onClick prop, so you can call a method that toggles the animation, like this demo: https://stackblitz.com/edit/gsap-react-basic-f48716?file=src%2FApp.js Hopefully this helps. Happy Tweening!
  23. Hi, I think you are overcomplicating this quite a bit. It should be as simple as this: https://codepen.io/GreenSock/pen/zYXWVdw Happy Tweening!
  24. Hi @Jake H and welcome to the GSAP Forums! You can tell ScrollTrigger to listen for scroll events in other elements with the scroller config property, no problemo! From the ScrollTrigger Docs: scroller String | Element - By default, the scroller is the viewport itself, but if you'd like to add a ScrollTrigger to a scrollable <div>, for example, just define that as the scroller. You can use selector text like "#elementID" or the element itself. It would be something like this: onMounted(() => { // Slide "Hello #20" rightward when it's centered. const tl = gsap.timeline({ scrollTrigger: { trigger: ".hello-20", start: "top center", end: "+=100", scroller: ".tall-component", markers: true, }, }); tl.to(".hello-20", { x: 30 }); }); Here is a fork of your demo: https://codesandbox.io/p/devbox/vue-scrolltrigger-test-forked-hddg9j?file=%2Fsrc%2Fcomponents%2FTallComponent.vue%3A20%2C25 Is worth noticing though that the center of your scroller element is waaay below the fold so your animation happens immediately, so I would look into enhancing the styles accordingly to make this work the way you want/need. Hopefully this helps Happy Tweening!
  25. Hi, Nick, you can use useGSAP and pass the prop value as a dependency and use revertOnUpdate: true in order to revert everything when that value changes and run your own conditional logic to run the animation or not. Also I strongly recommend you to not create your GSAP instances outside the scope of useGSAP. Maybe something like this: useGSAP(() => { const tl = gsap.timeline(); if (dark) { // Add instances for truthy } else { // Add instances for falsy } }, { scope: container,// if any dependencies: [dark], revertOnUpdate: true, }); Another option would be to not use revertOnUpdate and use the clear and invalidate methods: const tl = useRef(); useGSAP(() => { if (tl.current) { tl.current && tl.current.clear().invalidate(); } else { const tl = gsap.timeline(); } if (dark) { // Add instances for truthy } else { // Add instances for falsy } }, { dependencies: [dark], }); The code inside the hook will run when the dependency is updated but the instances inside of it won't be reverted. Those would be my approaches in this case. If you keep having issues, please post a minimal demo that we can take a look at. Happy Tweening!
×
×
  • Create New...