Jump to content
GreenSock

Rodrigo last won the day on September 23

Rodrigo had the most liked content!

Rodrigo

Administrators
  • Posts

    5,037
  • Joined

  • Last visited

  • Days Won

    246

Community Answers

  1. Rodrigo's post in Update y value with ScrollTrigger after content changes was marked as the answer   
    Hi @Fabian W and welcome to the GreenSock forums!
     
    First thanks for being a Club GreenSock member and supporting GSAP! 🥳
     
    What you are looking for is the invalidateOnRefresh configuration option in the ScrollTrigger configuration object:
     
    Boolean - If true, the animation associated with the ScrollTrigger will have its invalidate() method called whenever a refresh() occurs (typically on resize). This flushes out any internally-recorded starting values.
    https://greensock.com/docs/v3/GSAP/Tween/invalidate()
     
    This seems to work the way you intend:
    let t1 = gsap.to(c1, { scrollTrigger: { scrub: true, start: () => 0, end: () => 'max', markers: true, invalidateOnRefresh: true,// <- HERE }, y: () => document.body.clientHeight - c1.clientHeight, ease: 'none', overwrite: 'auto' }); let t2 = gsap.to(c2, { scrollTrigger: { scrub: true, start: () => 0, end: () => 'max', markers: true, invalidateOnRefresh: true,// <- HERE }, y: () => document.body.clientHeight - c2.clientHeight, ease: 'none', overwrite: 'auto' }); Hopefully this helps. If you have more questions let us know.
     
    Happy Tweening!
  2. Rodrigo's post in Pin jumps on bottom of the endpoint was marked as the answer   
    Hi,
     
    The issue is that you are pinning an element with display flex. Here you can see what the ScrollTrigger Docs:
     
    pinSpacing
    Boolean | String - By default, padding will be added to the bottom (or right for horizontal: true) to push other elements down so that when the pinned element gets unpinned, the following content catches up perfectly. Otherwise, things may scroll UNDER the pinned element. You can tell ScrollTrigger not to add any padding by setting pinSpacing: false. If you'd rather it use margin instead of padding, you can set pinSpacing: "margin". Note: pinSpacing works in most cases, but it really depends on the way you set up your DOM and CSS. For example, if you pin something in a parent that has display: flex or position: absolute, the extra padding won't push other elements down/right so you may need to manually space things out. pinSpacing is just a convenience that works in most situations. Important: if the container is display: flex, pinSpacing is set to false by default because that's typically what is desired since padding works differently in that context.
     
    If you want to pin something don't use display flex on the element you want to pin and be careful about using pinSpacing: false in your ScrollTrigger configuration.
     
    Hopefully this works the way you intend:
    https://codesandbox.io/p/sandbox/small-tdd-cbgi5l?file=%2Fpages%2Findex.tsx&selection=[{"endColumn"%3A25%2C"endLineNumber"%3A19%2C"startColumn"%3A25%2C"startLineNumber"%3A19}]
     
    Let us know if you have more questions.
     
    Happy Tweening!
  3. Rodrigo's post in How to force different speed on separate tweens was marked as the answer   
    Hi,
     
    I see that you took this example as a base for this:

    See the Pen QWjjYEw by GreenSock (@GreenSock) on CodePen
     
    Any particular reason for using images instead of backgrounds? I 'd stick with backgrounds if I was you, but if you want to use images you should tinker a bit with the styles and use percentage values for your animations.
     
    Here is a small proof of concept:

    See the Pen NWzLyXp by GreenSock (@GreenSock) on CodePen
     
    Let us know if you have more questions.
     
    Happy Tweening!
  4. Rodrigo's post in Looped "Scrolling" Section Transitions with snap scrolling - scrollTrigger was marked as the answer   
    Hi,
     
    I think this demo could be a good starting point as well:

    See the Pen NWxNEwY by GreenSock (@GreenSock) on CodePen
     
    Happy Tweening!
  5. Rodrigo's post in Gsap project with multiple wipes and Lottie animations was marked as the answer   
    Hi @Gigi1303 and welcome to the GreenSock forums!
     
    Indeed there is something in your HTML/CSS setup that is causing the Lottie container to jump out of position, most likely due to the fact that you are using position absolute and the scrub time, so the animation is still catching up while the end point has been passed and ScrollTrigger's pin has been released. I recommend you to move everything into a container without a display flex property and pin that container while animating the lottie file. Here is an example of that part of your codepen, as you can see there is no jump in it:

    See the Pen RwJBOMv by GreenSock (@GreenSock) on CodePen
     
    For the final section I'd add the card of the final section in the same section in order to trigger that animation when that section is at the top of the viewport and it can be pinned. Here is a working example of the entire setup:

    See the Pen dyKjByM by GreenSock (@GreenSock) on CodePen
     
    Hopefully this helps you get starter. Let us know if you have more questions.
     
    Happy Tweening!
  6. Rodrigo's post in Click event delays animation after few clicks. was marked as the answer   
    Hi,
     
    I think you are over complicating your approach IMHO. This is far simpler and seems to work as you expect:

    See the Pen ExREpKX by GreenSock (@GreenSock) on CodePen
     
    Hopefully is what you're looking for. Let us know if you have more questions.
     
    Happy Tweening!
  7. Rodrigo's post in Help me figure out the adaptive slider was marked as the answer   
    Hi,
     
    Unfortunately without a minimal demo is a bit hard to find out what the issue could be.
     
    Although I can suggest you a few things.
     
    When working with Vue always try to use the lifecycle methods(hooks) with GSAP Context in order to have a simple way to cleanup your GSAP instances when the component gets unmounted:
    <script setup> import { onMounted, onUnmounted, ref } from "vue"; import gsap from "gsap"; const main = ref(); const tl = ref(); const ctx = ref(); const toggleTimeline = () => { tl.value.reversed(!tl.value.reversed()); }; onMounted(() => { ctx.value = gsap.context((self) => { const boxes = self.selector(".box"); tl.value = gsap.timeline(); }, main.value) // <- Scope! }); onUnmounted(() => { ctx.value.revert(); // <- Easy Cleanup! }); </script> Here you can read more about GSAP Context:
    https://greensock.com/docs/v3/GSAP/Context
     
    In the case of responsive animations use GSAP Match Media in order to better organize and execute your responsive animations:
    https://greensock.com/docs/v3/GSAP/gsap.matchMedia()
     
    Is worth noticing that, as you can see in the code examples, you don't need context when using MatchMedia. The Match Media wrapper takes care of everything Context does so no need to have both, just use Match Media.
     
    Finally, regardless of the framework you are using, you can always create a Codepen example (simpler than codesandbox) in order to illustrate the issues you are having, at the end when animating we always are talking about DOM elements and Javascript so it makes no difference the setup for that, just the fact that we look at a live editable example that shows the issue you are having.
     
    Let us know if you have more questions.
     
    Happy Tweening!
  8. Rodrigo's post in Sync Two timelines was marked as the answer   
    Hi,
     
    This is not exactly a super simple result and unfortunately we don't have time to create custom solutions for our users.
     
    I was able to whip this simple example based on your codepen (thanks for the reduced codepen, we really love those around here 💚)

    See the Pen vYraJjP by GreenSock (@GreenSock) on CodePen
     
    Hopefully this is enough to get you started. Let us know if you have more questions.
     
    Happy Tweening!
  9. Rodrigo's post in I want morph the svg from one to another but the there is more then one path in svg? was marked as the answer   
    Hi @Chandraprakash Darji and welcome to the GreenSock forums!
     
    The Morph SVG Plugin can't work with <g> tags, what it does is go through the target path's d attribute and the target string you pass to it and animate the morphing of that path.
     
    Here is an example of animating different paths into different shapes, as you can see is not that easy as you have to go through each path and start creating the animation of each one in a timeline instance:

    See the Pen WQjRXE by GreenSock (@GreenSock) on CodePen
     
    In your case you'll have to go through every path until you can morph that particular path from the illustration into the part of the mobile element you want. If you have extra paths that are not matched in the mobile, you could fade-out and scale-down those.
     
    Unfortunately your codepen has over 7000 lines and a lot of SVG paths and we don't have the time resources to provide working custom solutions for something as complex as this. You are free to post in the Jobs & Freelance section or contact us directly for a consulting job.
     
    If you have any other GSAP related question, feel free to post in this thread or create a new one and remember to include a minimal demo.
     
    Good luck with your project!
     
    Happy Tweening!
  10. Rodrigo's post in Pinned slide show bound to scroll position? was marked as the answer   
    Hi @Thisjustin and welcome to the GreenSock forums!
     
    I think it's easier with a loop for the slides and just a single timeline for each slide using ScrollTrigger's scrub configuration as well.
     
    Here  is a live example:

    See the Pen GRGdexP by GreenSock (@GreenSock) on CodePen
     
    Also, since you are starting with GSAP I strongly recommend you to watch this video by @Cassie in order to get a better grasp of how to create a good working flow when using GSAP and ScrollTrigger on your projects:
    Let us know if you have more questions.
     
    Happy Tweening!
  11. Rodrigo's post in Reveal each section title with GSAP was marked as the answer   
    Hi,
     
    Maybe just use the event callbacks to create a GSAP instance for each element and don't use scrub at all. Something like this:

    See the Pen qBKYQyx by GreenSock (@GreenSock) on CodePen
     
    Let us know if you have more questions.
     
    Happy Tweening!
  12. Rodrigo's post in Perspective (3D?) text animation on scroll was marked as the answer   
    Hi,
     
    You just need to add a perspective value to the text container, in this case the H1 tag:

    See the Pen gOKgpxz by GreenSock (@GreenSock) on CodePen
     
    As for linking the Bonus Plugins, for obvious reasons those are not exposed. You don't want to have the files that you have paid for, being accessible to anyone who inspects your code and sees the links there. If you have no option create a single file with the entire code obfuscated and no comments (so no one can see what's in there). Perhaps @GreenSock can offer a better solution for this.
     
    Happy Tweening!
  13. Rodrigo's post in GSAP ScrollTrigger Pinning Question was marked as the answer   
    Hi,
     
    You can solve it with a different style for the first heading, using the Toggle Actions config properly and triggering the first header animation at the same time with the second header.
     
    Toggle Actions (from the Docs):
    String - Determines how the linked animation is controlled at the 4 distinct toggle places - onEnter, onLeave, onEnterBack, and onLeaveBack, in that order. The default is play none none none. So toggleActions: "play pause resume reset" will play the animation when entering, pause it when leaving, resume it when entering again backwards, and reset (rewind back to the beginning) when scrolling all the way back past the beginning. You can use any of the following keywords for each action: "play", "pause", "resume", "reset", "restart", "complete", "reverse", and "none".
     
    Here is a live example (thanks for the simple codepen! 🙌)

    See the Pen oNyqppN by GreenSock (@GreenSock) on CodePen
     
    Finally your original example was using very old versions of GSAP and ScrollTrigger (3.5.x), always use the latest versions.
     
    Happy Tweening!
  14. Rodrigo's post in Nesting an animation trigger inside scrolltrigger element was marked as the answer   
    Hi,
     
    You didn't set up the scroller property in the ScrollTrigger configuration, so basically that instance is waiting for the window to scroll up/down which never happens. This seems to fix it:
    function setupOneOffs() { let panel1 = gsap.timeline({ // yes, we can add it to an entire timeline! scrollTrigger: { trigger: ".content1", pin: false, scroller: ".container2", // <- Add the scroller element here start: "top top", end: "+=50", snap: { snapTo: "labels", }, }, }); // add animations and labels to the timeline panel1.addLabel("start") .from(".test1", {x: -500, scale: .3, rotation:45}) .addLabel("color") .from(".test1", {backgroundColor: "#28a92b"}) .addLabel("spin") .to(".test1", {rotation: 360, x: 0}) .addLabel("end"); }; Happy Tweening!
  15. Rodrigo's post in Disable ScrollSmoother in mobile was marked as the answer   
    Hi,
     
    The issue is that you create the animations and when you go through the breakpoint those are never properly reverted. I'd recommend you to use Match Media for all your different scenarios in order to have a better control.
     
    This seems to work:
    const mm = gsap.matchMedia(); let smoother; const createFadeTweens = () => { const fadescroll = gsap.utils.toArray(".js-fade-scroll-1"); fadescroll.forEach((elem) => { /* Timeline & ScrollTrigger Instances Here */ }); const fadeImage = gsap.utils.toArray(".js-fade-scroll-2"); fadeImage.forEach((image) => { /* Timeline & ScrollTrigger Instances Here */ }); }; mm.add("(min-width: 800px)", () => { let skewSetter = gsap.quickTo(".js-skew", "skewY"), // fast clamp = gsap.utils.clamp(-20, 20); // don't let the skew go beyond 20 degrees. smoother = ScrollSmoother.create({ wrapper: "#smooth-wrapper", content: "#smooth-content", smooth: 2, normalizeScroll: true, ignoreMobileResize: true, effects: true, onUpdate: (self) => skewSetter(clamp(self.getVelocity() / -150)), onStop: () => skewSetter(0) }); createFadeTweens(); return () => smoother.kill(); }); mm.add("(max-width: 799px)", () => { createFadeTweens(); }); Here  is a live example:

    See the Pen WNydVEJ by GreenSock (@GreenSock) on CodePen
     
    Happy Tweening!
  16. Rodrigo's post in How To Control Horizontal Scroll Section As a Tabs Element ? was marked as the answer   
    Hi,
     
    This is mostly a React problem and not GSAP related. You have to tell React that the current tab set has changed in the dependencies array of the effect hook and also always revert your context:
    useEffect(() => { //horizontal scrolling stuff const panels = panel.current.length; const ctx = gsap.to(panel.current, { xPercent: -100 * (panels - 1), ease: "none", scrollTrigger: { trigger: panelsContainer.current, pin: true, scrub: 1, snap: { snapTo: 1 / (panels - 1), ease: "linear" }, end: () => "+=" + panelsContainer.current.offsetWidth } }); return () => ctx.revert(); // cleanup Important! }, [currentTab]); // Update your animation when the tab has been updated Finally regarding this, please be as nice as possible with Moderators and other users that are trying to help in the forums since Mitchel (@mvaneijgen) is a voluntary here in the forums, so he takes time of his own work and daily activities to help users in the forums. Don't look into it as a warning or anything like that, just a friendly suggestion of the tone and general attitude in the forums towards other users. We understand that sometimes there is frustration and deadlines looming, but it is also very important to maintain respect and consideration when asking for help with your projects.
     
    Happy Tweening!
  17. Rodrigo's post in GSAP Marque with Events was marked as the answer   
    Hi,
     
    Actually I don't think you need the onComplete callbacks in your mouse enter/leave event handlers, just tween the timeScale to 0 and 1 and that should be it. Also instead of creating the animation paused, set it's timescale to 0. This seems to work as you expect:

    See the Pen poKWJXa by GreenSock (@GreenSock) on CodePen
     
    Also you should take a look at the Horizontal Endless Loop helper function:
    https://greensock.com/docs/v3/HelperFunctions#loop
     
    Let us know if you have more questions.
     
    Happy Tweening!
  18. Rodrigo's post in position element on corner of parent container was marked as the answer   
    Hi,
     
    I think this is the perfect situation for using the Flip Plugin:

    See the Pen yLEobVz by GreenSock (@GreenSock) on CodePen
     
    https://greensock.com/docs/v3/Plugins/Flip
     
    Happy Tweening!
  19. Rodrigo's post in Hover animation need to rotate slightly with mouse move was marked as the answer   
    Hi @Pathirana and welcome to the GreenSock forums!
     
    What you can do is check the mouse position in the X axis and create a GSAP animation for each image that rotates the image from a starting angle to an end angle. Then you can control that animation's progress using the mouse position value.
     
    Here is a simple example illustrating that:

    See the Pen jOKLNLG by GreenSock (@GreenSock) on CodePen
     
    Hopefully this is enough to get you started. Let us know if you have more questions.
     
    Happy Tweening!
  20. Rodrigo's post in Move bubbles x and y with respect to which direction the mouse hits them with was marked as the answer   
    Hi,
     
    The problem is that all your bubbles are created at the top/left corner of the tank, so the coordinates {x: 0, y: 0} will take a bubble to the top left corner and any value in that vicinity will move the bubble closer to the top/left corner.
     
    What you need is to use relative values instead of absolute ones:
    const moveBubble = (idx, xMove, yMove) => { console.log(xMove, yMove, idx); gsap.to(`.bubble-${idx}`, { x: "+=" + xMove, y: "+=" + yMove, duration: 3 }); }; That seems to work in the way you need. Let us know if you have more questions.
     
    Happy Tweening!
  21. Rodrigo's post in Multiple ScrollTrigger animations in React was marked as the answer   
    Hi,
     
    This seems to be doing what you want:
    https://codesandbox.io/s/team-eleven-forked-iwxm7k
     
    Hopefully is enough to get you started.
     
    Happy Tweening!
  22. Rodrigo's post in How to get staggers to end simultaneously was marked as the answer   
    Hi @Elusien and welcome to the GreenSock forums!
     
    As far as I can tell, the Staggers API doesn't include such tooling because we're talking about the duration of the animation with an equal stagger time. For that I can think of two alternatives.
     
    Create a timeline and loop through the elements and change the duration of each animation on each loop:
    const boxes = gsap.utils.toArray(".box"); const duration = boxes.length; const tl = gsap.timeline({ paused: true }); boxes.forEach((box, index) => { tl.to(box, { y: 200, rotation: 360, ease: "none", backgroundColor: "#ff00ff", duration: duration - index, }, index ? "<=+1" : 0); }); Create a single GSAP instance and use a function based value for the duration running basically the same code:
    const boxes = gsap.utils.toArray(".box"); const duration = boxes.length; const tl = gsap.to(boxes, { stagger: 1, y: 200, rotation: 360, backgroundColor: "#ff00ff", ease: "none", duration: (index) => duration - index, }); Here is a live example with both approaches (just comment one and uncomment the other) and as you can see the result is the same:

    See the Pen dyKRXgZ by GreenSock (@GreenSock) on CodePen
     
    Hopefully this is what you're looking for. Let us know if you have more questions.
     
    Happy Tweening!
  23. Rodrigo's post in Horizontal Histroy was marked as the answer   
    Hi,
     
    The problem is that some of your animations are starting at the same time, that's why all your markers are in the same position:

     
    You have the same class for different images in different sections, so  ScrollTrigger is doing exactly what is supposed to do, your HTML setup needs to be reviewed and the selectors you use in your GSAP instances as well.
     
    Finally is always a good idea to create your ScrollTrigger instances in the way they happen on the screen, right now it seems to me that they are backwards.
     
    Let us know if you have more questions.
     
    Happy Tweening!
  24. Rodrigo's post in 3D carousel codepen not working with latest GSAP version was marked as the answer   
    Hi,
     
    This is a fork of the codepen using ScrollTrigger and the latest version of GSAP (3.11.3):

    See the Pen eYKWzwv by GreenSock (@GreenSock) on CodePen
     
    Hopefully is enough to get you started. Let us know if you have more questions.
     
    Happy Tweening!
  25. Rodrigo's post in Is this possible with GSAP was marked as the answer   
    Hi @MarcFN and welcome to the GreenSock forums!
     
    If you inspect that site you'll see that each letter is wrapped in a <span> tag, so basically they are switching each span between opacity 0 and 1 as you scroll up and down.
     
    Something like that could be easily done with SplitText and ScrollTrigger:

    See the Pen mdKWBmm by GreenSock (@GreenSock) on CodePen
     
    Is worth pointing that the SplitText Plugin is a Club GreenSock perk, but you can try it for free and experiment with it on Codepen without any issues.
     
    Let us know if you have more questions.
     
    Happy Tweening!
×