Jump to content
Search Community

Rodrigo last won the day on April 24

Rodrigo had the most liked content!

Rodrigo

Administrators
  • Posts

    6,598
  • Joined

  • Last visited

  • Days Won

    285

Community Answers

  1. Rodrigo's post in Awaiting for timelines to revert() was marked as the answer   
    Hi,
     
    You can use Stackblitz to create a Nuxt demo and the GSAP Trial package in order to use the bonus plugins on Stackblitz:
    https://stackblitz.com/
    https://www.npmjs.com/package/gsap-trial
     
    Here is a simple Nuxt demo:
    https://stackblitz.com/edit/nuxt-starter-vzsxyp?file=app.vue
     
    Hopefully this helps.
    Happy Tweening!
  2. Rodrigo's post in Mixing ScrollTrigger with Lenis in a Nuxt project was marked as the answer   
    Well the only thing I can see is that there is no animation at all here:
    gsap.to(trigger, { scrollTrigger: { trigger: trigger, start: 'top center', y: '-=100px', ease: "power1.inOut", stagger: .2, onEnter: () => { console.log('coucou') } } }) You have a GSAP to() instance but there is no animation whatsoever, just the ScrollTrigger configuration, if you remove that this is what's left:
    gsap.to(trigger, { }) Nothing, nada, nicht. See the problem? You need to add some property for those elements that can be animated to begin with.
     
    Finally you're planning to animate the same element that you're using as a trigger on your ScrollTrigger configuration. Be super careful about that and if possible avoid animating the trigger element because it could lead to unexpected results.
     
    Happy Tweening!
  3. Rodrigo's post in SVG path animation triggerd by scrolling with different sections was marked as the answer   
    Hi,
     
    Not really TBH. What you're trying to achieve is not the simplest thing to do and adding stuff through a CMS only brings more complexity to it since you need a 100% dynamic solution for this.
     
    As I mentioned before the issue resides in the start and end points of each ScrollTrigger, having different sections for the SVG only adds an extra wrinkle to this.
     
    Here are a couple of demos that use different approaches to this:

    See the Pen zYrPrgd by creativeocean (@creativeocean) on CodePen
     

    See the Pen jOryjNX by oliviale (@oliviale) on CodePen
     
    Finally this mostly boils down to your layout more than anything else. I forked your demo and added different indents and ids to each ScrollTrigger instance and you can see in section 2 your SVG is waaaaay too tall, it goes beyond the final spacing element. The mask and path for that section also is the same height but the actual drawing is smaller, that's why that section's draw animation finishes before the end point of the ScrollTrigger instance is reached:

    The light blue rectangle is one of the SVG tags for section 2, but the path finishes quite before that, that's why you're getting those pauses between sections.

    See the Pen QWoYQQQ by GreenSock (@GreenSock) on CodePen
     
    You can see that the end point for scroller 3 is way after the animation already ended
     
    Again this boils down to HTML/CSS/SVG and not a GSAP related issue and is beyond the scope of the help we can provide in these free forums. You have to find a way to make your SVG to dynamically adapt to the dimensions of the content and the screen.
     
    Good luck with your project!
    Happy Tweening!
  4. Rodrigo's post in Invalid scope on dynamically rendered elements with scrolltriggers when switching routes in Next js was marked as the answer   
    Yeah the issue could be that the fact that the boolean on your state is updated that doesn't necessarily means that the elements are rendered yet, especially when you run that ScrollTrigger.refresh() method. Any particular reason for that? I don't really see any reason for having that code in that component. Removing that single line seems to fix the issue.
     
    As far as I can tell there is no real need to have that refresh call there, since when that component is unmounted the useGSAP hook will revert everything inside of it, so there shouldn't be any reason to globally refresh ScrollTrigger, unless there are other ScrollTrigger instances in your parent component, but still 
    if you need it you can add the revertOnUpdate option to the useGSAP hook to revert everything:
    useGSAP( () => { if (feedLoaded) { ScrollTrigger.refresh(); // rest of your code } }, { scope: curatorContainer, revertOnUpdate: true, dependencies: [feedLoaded], } ); Hopefully this helps.
    Happy Tweening!
     
  5. Rodrigo's post in I encountered some issues with ScrollTrigger again. was marked as the answer   
    Hi,
     
    I think the main issue here is the fact that you're using the same element as the scroller (the document element). ScrollTrigger allows you to define a scroller which is the element where ScrollTrigger  will look for the scroll position in order to update any Tween/Timeline you pass to it. 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.
     
    https://gsap.com/docs/v3/Plugins/ScrollTrigger/#config-object
     
    Here are a couple of demos that use a similar approach:

    See the Pen yLRQozy by GreenSock (@GreenSock) on CodePen
     

    See the Pen OJBvBjB by GreenSock (@GreenSock) on CodePen
     
    Hopefully this helps.
    Happy Tweening!
  6. Rodrigo's post in How to animate a storyline with multiple stacked texts? was marked as the answer   
    Hi,
     
    In this case the Observer Plugin might be a better fit actually:
    https://gsap.com/docs/v3/Plugins/Observer/
     

    See the Pen XWzRraJ by GreenSock (@GreenSock) on CodePen
     
    Here is a demo that mixes ScrollTrigger with Observer:

    See the Pen ExEOeJQ by GreenSock (@GreenSock) on CodePen
     
    Hopefully this helps.
    Happy Tweening!
  7. Rodrigo's post in Scroll, zoom and pin into SVG logo was marked as the answer   
    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:

    See the Pen WNWgaqZ by GreenSock (@GreenSock) on CodePen
     
    Hopefully this helps.
    Happy Tweening!
  8. Rodrigo's post in ssr:warn Please gsap.registerPlugin(CustomEase) when using CustomEase with Nuxt 3 was marked as the answer   
    Hi @m__shum and welcome to the GSAP Forums!
     
    Sorry to hear about the issues. I created a new Nuxt3 app here in my local machine and this is working without any issues:
    import gsap from "gsap"; import { CustomEase } from "gsap/CustomEase"; import { onMounted } from "vue"; if (typeof window !== "undefined") { gsap.registerPlugin(CustomEase); } const myEase = CustomEase.create('myEase', 'M0,0 C0.29,0 0.311,0.268 0.35,0.502 0.423,0.951 0.756,0.979 1,1 '); onMounted(() => { gsap.to("h1", { x:200, y: 200, ease: "myEase", duration: 2, }); }); I would recommend you to use the onMounted hook in your setup.
     
    We have this starter template on stackblitz that you can use as a reference:
    https://stackblitz.com/edit/nuxt-starter-aih1uf
     
    Hopefully this helps.
    Happy Tweening!
  9. Rodrigo's post in Can I stagger toggleClass? was marked as the answer   
    Hi,
     
    The stagger config option is not a valid one for the ScrollTrigger config object. 
     
    What I don't really understand of your setup, is why you want to stagger something if you are already using a loop for creating the ScrollTrigger instances.
     
    Maybe you're looking for ScrollTrigger's batch method:
    https://gsap.com/docs/v3/Plugins/ScrollTrigger/static.batch()
     
    Check the demos in that link see if that helps. If you keep having questions please include a minimal demo that illustrates what you're trying to do and where you're encountering problems.
     
    Happy Tweening!
  10. Rodrigo's post in Animate a single element using multiple ScrollTriggers was marked as the answer   
    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:

    See the Pen eYojqEB by GreenSock (@GreenSock) on CodePen
     
    Here is the debug view:
    https://cdpn.io/pen/debug/eYojqEB
     
    Hopefully this helps.
    Happy Tweening!
  11. Rodrigo's post in How to draw a squiggly path alongside the 50% viewport with scrollTrigger? was marked as the answer   
    Hi,
     
    Indeed this is mostly about creating a custom easing that works with your particular path, unfortunately this is mostly a trial and error approach. Good news is that we have the ease visualizer that can help you with this.
     
    Basically what you need is a linear (no easing) or slower ease for the vertical sections, so the drawing is slower in those sections, and faster/steeper easing for the horizontal sections. The reason is that you need the horizontal part to be as fast as possible because the element is still scrolling up/down while the path is being drawn in a horizontal way.
     
    I created a simple custom ease (doesn't resolve your issue though) so you can see in the ease visualizer what I mean:
    "M0,0 C0.025,0.021 0.401,0.312 0.401,0.312 0.401,0.312 0.5,0.5 0.5,0.5 0.5,0.5 0.7,0.7 0.7,0.7 0.7,0.7 0.77,0.876 0.77,0.876 0.77,0.876 0.983,0.989 1,1 " You can copy that string and paste it on our ease visualizer in order to see how that works, the faster parts are intended for horizontal sections and the slower ones for vertical sections:
    https://gsap.com/resources/getting-started/Easing
     
    Hopefully this helps.
    Happy Tweening!
  12. Rodrigo's post in react clip-path scroll animation with Observer, useGSAP was marked as the answer   
    Hi,
     
    I think this is a better approach:

    See the Pen JjVmWKb by GreenSock (@GreenSock) on CodePen
     
    I wasn't able to create a react version of it for technical issues on my end (ISP is super slow and creating a codepen is not as slow as a react demo on stackblitz), but porting this to react shouldn't be a really complicated task. The heart of this is on the doSlide method that takes a specific value (+1 or -1) which updates the index value. Also the difference with your approach is that this uses a fromTo instance for the next slide, regardless of the direction so that takes the clip path of the next image from the bottom to the top which makes looping possible.
     
    Hopefully this helps.
    Happy Tweening!
  13. Rodrigo's post in Stagger effect not applying on grid was marked as the answer   
    Hi,
     
    The first issue in your code is that you're using the quick setter on the parent element, that is the element that contains the grid, and not the grid elements so staggering will have no effect whatsoever.
     
    Then I fail to see the point of a quick setter if you can achieve the same with just a GSAP Tween that gets overwritten if another is created. Something like this:
    useGSAP(() => { let proxy = { translate: 0 }, translateSetter = gsap.quickSetter('.video-container', 'y', 'px'), clamp = gsap.utils.clamp(-1000, 1000); ScrollTrigger.create({ onUpdate: (self) => { translateSetter(clamp(self.getVelocity() / -100)); gsap.to('.video-container', { y: 0, duration: 0.2, stagger: 0.05, overwrite: true, }); }, }); }); Here is a fork of your demo with that approach:
    https://stackblitz.com/edit/react-hnfbhc?file=src%2FApp.js
     
    Hopefully this helps.
    Happy Tweening!
  14. Rodrigo's post in Image Reveal on Hover implemetation, image positioning issue was marked as the answer   
    Hi,
     
    In this thread @akapowl and @nico fonseca go into a lot of detail on how to create that type of effect and provide some good resources as well:
     
    Hopefully this helps.
    Happy Tweening!
  15. Rodrigo's post in Moving bg + ScrollTrigger won't reach end was marked as the answer   
    Hi @1PM and welcome to the GSAP Forums!
     
    I think the problem here are the values you're passing and how they're calculated based on the dimensions they have. I've been looking for a bit at your demo and one of the things I think (emphasis on the I THINK part) is the fact that your SVG has a specific width in pixels based on the screen size and it's parent, but then you have the viewbox in your SVG which creates a whole new coordinates system that doesn't really matches the one outside of it. In that particular case a 100 pixels motion in the DOM is not the same as inside of the SVG. For example I'm looking at this in a 1920x1084 pixels screen so moving something 192 pixels on the X axis is 10% of the screen, right? But your SVG has a viewbox of 9000 units width, 192 units in that frame is only 2.1333% of that, see the problem? On top of that you have to figure a way to move each element (right now you're moving each group of kids individually) a specific amount of units inside the SVG so they become visible in a specific window size (that's why you have different end positions in different screen widths).
     
    I think you should start by completely removing ScrollTrigger from this and focus just on getting the animations to work as expected, nothing more. Once the animations do what you want (I strongly recommend you to have everything in a single GSAP Timeline) you can plug in ScrollTrigger back into this.
     
    Also I'd recommend you to group all the kids playing in one layer and move that, same with the trees and rocks, it would be far easier to move this elements if they reside in a single group rather than move them one by one.
     
    There are a lot of moving parts in this and a lot of things that need to be taking into consideration and that's beyond the scope of what we can do for our users in these free forums. Unfortunately we don't have the time resources to start fiddling with your demo and get it working. Maybe there is a simple way to do this that is eluding me, but SVG is not something I particularly excel at. As I mentioned I'd take it one step at a time and one layer at a time with just a single animation for each layer/group inside a timeline, make sure is responsive and then add ScrollTrigger in order to control everything with the scroll position.
     
    Happy Twening!
  16. Rodrigo's post in Split Screen Pinning was marked as the answer   
    Hi,
     
    I think you are overcomplicating this quite a bit. It should be as simple as this:

    See the Pen zYXWVdw by GreenSock (@GreenSock) on CodePen
     
    Happy Tweening!
  17. Rodrigo's post in Interrupting ScrollTo was marked as the answer   
    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!
  18. Rodrigo's post in ScrollTrigger reposition and resize logo on scroll was marked as the answer   
    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:

    See the Pen bGxOjeP by GreenSock (@GreenSock) on CodePen
     
    Hopefully this helps.
    Happy Tweening!
  19. Rodrigo's post in ScrollTrigger not working in a grid was marked as the answer   
    Hi @seifhadaba and welcome to the GSAP Forums!
     
    In your App.tsx file the main issue is that your layout element has a fixed height of 100vh, so when you uncomment that part there is no scroll available:
    .layout { display: grid; grid-template-columns: 12rem 1fr; height: 100vh; /* THIS */ } Also these styles don't seem to be helping at all:
    .content { grid-column: 2 / span 1; overflow: hidden scroll; scroll-snap-type: y proximity; } You can just set hidden to both, ScrollTrigger works with the window as the default scroller and unless you have no other choice but to use a different one, is always better to keep it that way, it simplifies everything quite a bit. Also your ScrollTrigger already has a snap function in it, any particular reason to have scroll-snap defined in your CSS? This seems to work:
    .layout { display: grid; grid-template-columns: 12rem 1fr; } .content { grid-column: 2 / span 1; overflow: hidden; } In the case of the toggleClass, is doing exactly what you're telling it to do, is adding the ".active" class with the dot in it so your HTML looks like this:
    class="_src_components_ExperiencePage_ExperiencePage_module__container .active" See the dot before active?
    // Wrong toggleClass: ".active", // Right toggleClass: "active", Finally if you log in your getWidth you'll see that is ran after you resize the window so that is also working as expected:
    const getWidth = () => { const margin = Number( window .getComputedStyle(section1.current!) .getPropertyValue("margin-right") .slice(0, -2) // remove "px" ); const width = Number( window .getComputedStyle(section1.current!) .getPropertyValue("width") .slice(0, -2) ) + 2 * margin; console.log("get width", width); return width; }; You also don't need to add the window width to the dependencies on the useGSAP hook:
    useGSAP(() => {}, { scope: container, dependencies: [window.innerWidth] // <- No need for this }); ScrollTrigger will run it's refresh method after the window resize and it has a debounce method that optimizes the whole process.
     
    Here is a fork of your demo:
    https://codesandbox.io/p/sandbox/gsap-scrolltrigger-forked-qjt48r?file=%2Fsrc%2FApp.tsx%3A7%2C5-7%2C29
     
    Hopefully this helps.
    Happy Tweening!
  20. Rodrigo's post in matchMedia() not behaving as expected was marked as the answer   
    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:

    See the Pen KKYRJwo by GreenSock (@GreenSock) on CodePen
     
    Hopefully this helps.
    Happy Tweening!
  21. Rodrigo's post in Gsap Club installation with Nuxt & Netlify was marked as the answer   
    Hi @OversensitiveCat and welcome to the GSAP Forums!
     
    Did you by any chance installed the regular GSAP package before installing the package with the bonus plugins? That's the only reason I can think of why this doesn't work.
     
    What you could try is to delete the lock file (package-lock.json) and push again to the repo and see if that works.
     
    Hopefully this works.
    Happy Tweening!
  22. Rodrigo's post in next js scrolltrigger issues with containeranimation and matchmedia in a horizontal layout was marked as the answer   
    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!
  23. Rodrigo's post in GSAP marquee animation was marked as the answer   
    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:

    See the Pen zYaxEKV by GreenSock (@GreenSock) on CodePen
     

    See the Pen GRwePYw by GreenSock (@GreenSock) on CodePen
     
    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!
  24. Rodrigo's post in GSAP and Threlte (ThreeJs inside Svelte) with Reactive Properties was marked as the answer   
    Hi,
     
    Using Svelte's tick method removes the ref error, but there is definitely something here tied to the way Svelte's THREE wrapper works:
    onMount(async () => { await tick(); const ctx = gsap.context((self) => { console.log(threlteContainer); const box = threlteContainer.ref; gsap.to(box.position, { x: '100', y: '200', scrollTrigger: { trigger: threlteContainer, start: 'bottom bottom', end: 'top 20%', scrub: true, }, }) }, threlteContainer) return () => ctx.revert(); // <- Cleanup! }); Is worth noticing that GSAP Context is complaining that the scope you're passing is not a valid DOM element, be sure to do that. In this case this seems more tied to what threlte is doing behind the scenes.
     
    Even this is throwing some error:
    https://stackblitz.com/edit/vitejs-vite-smjvup?file=src%2FApp.svelte
     
    Honestly I couldn't tell you exactly what the issue is here, but most likely is not related to meither GSAP nor ScrollTrigger. I suggest you to get something simple working with just a regular GSAP Tween and then add ScrollTrigger back into this.
     
    Happy Tweening!
  25. Rodrigo's post in ScrollTrigger not working when scrolling element is not body was marked as the answer   
    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!
×
×
  • Create New...