Jump to content
Search Community

GreenSock last won the day on May 5

GreenSock had the most liked content!

GreenSock

Administrators
  • Posts

    23,164
  • Joined

  • Last visited

  • Days Won

    818

Community Answers

  1. GreenSock's post in scrolltrigger use pin and once, but pin-spacer cause padding space when scroll back was marked as the answer   
    You're making one of the common ScrollTrigger mistakes - nesting ScrollTriggers inside of a timeline. That can't logically work because you can't have the parent timeline AND the scroll position both control the same playhead(s), as they could be going in different directions. So either separate out each tween into its own individual tween that has a ScrollTrigger on it, OR put your tweens into a timeline that has a ScrollTrigger applied to that timeline. 
     
    As for once: true, you could do something like this instead: 
    onLeave: self => { let max = ScrollTrigger.maxScroll(window), // record maximum scroll amount, and the current scroll position scroll = self.scroll(); self.kill(true, true); self.scroll(scroll - (max - ScrollTrigger.maxScroll(window))); // adjust the scroll based on how much was lost when self.kill() was called. }  

    See the Pen jORLdmy?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    (I didn't fix all your nested ScrollTriggers - you'll need to work through those). 
  2. GreenSock's post in ScrollTrigger: i want to fixed the position of element at center of screen while moving along SVG Path was marked as the answer   
    I built a helper function specifically for this: 

    See the Pen vYMJdjB?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Related forums post: 
     
    I hope that helps!
  3. GreenSock's post in ScrollSmoother and getBoundingClientRect was marked as the answer   
    Yeah, that's because you're listening to the window's "scroll" event, but ScrollSmoother gradually applies that. So you're using stale values. Just set up an onUpdate event handler on the ScrollSmoother, and for maximum performance you can leverage a cache boolean to only trigger updates when absolutely necessary: 

    See the Pen RwOZBjp?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Is that what you're looking for? 
  4. GreenSock's post in Problems resizing a scene with a pinned ScrollTrigger + SplitText with absolute position was marked as the answer   
    Are you trying to do something like this?: 

    See the Pen GRPdENx?editors=0010 by GreenSock (@GreenSock) on CodePen
  5. GreenSock's post in Animating to auto height while using grid display with media query breakpoints was marked as the answer   
    When an animation renders for the first time, it records the start/end values internally so that it can very quickly interpolate between them during the animation. You've created a scenario where you actually want to CHANGE those values on resize. invalidate() will do exactly that - it flushes any recorded start/end values so that on the next render of that animation, it'll re-calculate those. 
     
    With that in mind, you can just invalidate the animation and restore its progress: 
    window.addEventListener("resize", () => { let progress = tl.progress(); // remember the progress tl.progress(0).invalidate().progress(progress); // rewind to the beginning, invalidate to flush any recorded start/end values, then restore the progress });
    See the Pen BaEdQBy?editors=0110 by GreenSock (@GreenSock) on CodePen
     
    Is that what you're looking for? 
     
    You could also consider using a gsap.matchMedia(). There are many ways to accomplish something similar 🙂
  6. GreenSock's post in Strange behaviour of a pin element using Scrolltriggers was marked as the answer   
    That sounds like it could simply be a consequence of the fact that most modern browsers handle scrolling on a completely different thread than the main JS thread, thus it renders the content as if it was scrolled (without any ScrollTrigger logic applied) first, and THEN when the JS thread executes, ScrollTrigger does what it must do to pin the element, making it look like it jumps back. 
     
    Two things you can try (assuming that's the problem you're noticing):
     
    1) Try setting ScrollTrigger.normalizeScroll(true) which forces all the scrolling to occur on the main thread. 
     
    2) Use a scroll smoothing library like ScrollSmoother or Lenis which accomplishes a similar thing, unhooking the native scroll and implementing JS-based scrolling instead. 
  7. GreenSock's post in Variable height stacked pinning with combined lateral split sections was marked as the answer   
    You can't have nested pinning, but you could probably use position: sticky like this: 

    See the Pen MWRoQoV?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Is that what you're looking for? 
  8. GreenSock's post in GSAP unable to animate clip-path: inset(... was marked as the answer   
    That's because the browser's getComputedStyle() doesn't return the calc() data properly. So when GSAP gets the starting (from) value, the browser gives it a value with no calc(), and then the end string has calc() in it with multiple numbers. It's the same issue with your other demos (mis-matched data/quantities). There are two solutions: 
     
    1) Use CSS variables:

    See the Pen RwOgRJQ by GreenSock (@GreenSock) on CodePen
     
    2) Use a normal .fromTo() tween so that GSAP understands what you're trying to do and can use the raw starting value instead of a computed one from the browser: 

    See the Pen wvZeWXQ?editors=0110 by GreenSock (@GreenSock) on CodePen
     
  9. GreenSock's post in Mounting and unmounting animations with React was marked as the answer   
    That looks like all React-related logic. 
    You were adding a .from() animation to the timeline that targets usernameFormRef.current...but at the end of the previous tween you're calling setJoined() which triggers a re-render of the component, so that element that you were tweening with the from() tween no longer exists! It was replaced by React with something else or removed altogether.  When you setJoined(), React takes a little time to actually create/render the new state, so you have to wait for React to finish that before you can actually animate what it creates. That's the perfect case for a useGSAP() with a dependencies Array - it'll get triggered as soon as a dependency changes and is rendered.  You created your timeline instance outside of any context, therefore it won't get reverted or cleaned up properly.  You don't really need to set a scope if you're never using any selector text, just so you know. It doesn't hurt anything, of course. It's just that it is only useful for selector text.  Are you trying to do this?:
    https://stackblitz.com/edit/nextjs-7ex2g3?file=app%2Fcomponents%2FControls.tsx
  10. GreenSock's post in Conflict between two pin animations was marked as the answer   
    I didn't have a lot of time to look at this, but it appears to me as though you were creating the ScrollTriggers in the wrong order. You should always create them in the order they appear on the page, -OR- you can set a refreshPriority on them instead so that you can make sure things get refreshed in the proper order. I added a ScrollTrigger.sort() at the end in order to force them to get ordered by their start position: 

    See the Pen XWQRmmb?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Also, this is not a good idea:
    transform: "translateY(100%)" It's much cleaner, faster, and more efficient to do this: 
    yPercent: 100 Does that clear things up? 
  11. GreenSock's post in Horizontal Slider with Draggable was marked as the answer   
    We don't typically provide custom solutions like this in these free forums, but I was curious about this and decided to clean up your demo for you: 

    See the Pen GRLWvGp?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    I assume that was what you're looking for, right? You just had various logic issues and overcomplicated things a bit in my opinion. 🙂
     
    I hope that helps!
  12. GreenSock's post in Split Text coverts style tags was marked as the answer   
    I've never seen someone put <style> tags nested inside of a <div> like that! Hm. Well, here's a method that'll solve it for you - it just temporarily removes the <style> tags and puts them back after the split: 
    function styleSafeSplit(target, vars) { let targets = gsap.utils.toArray(target), styles = targets.map((target, i) => { // remove all the <style> elements let s = gsap.utils.toArray(target.querySelectorAll("style")); s.forEach(el => el.parentNode.removeChild(el)); return s; }), split = SplitText.create(target, vars); styles.forEach((s, i) => s.forEach(style => targets[i].appendChild(style))); // insert the <style> elements again return split; } Use it the same way you would use SplitText.create(...)
    styleSafeSplit("#text", {type:"chars,words"});  

    See the Pen VwNeqNB?editors=1010 by GreenSock (@GreenSock) on CodePen
     
    Does that help? 
  13. GreenSock's post in Using quickTo along with directional rotation was marked as the answer   
    One of the reasons gsap.quickTo() is so fast is because it skips a bunch of conveniences like unit conversions, special features like "_short", relative values, etc. - it's purely for funneling a raw number directly into an existing tween. 
     
    So I would probably do it like this: 

    See the Pen MWRJJay?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    One simple tween that gets killed/replaced on each move. 
  14. GreenSock's post in ScrollTrigger.batch bug with "once" ScrollTrigger's was marked as the answer   
    Great catch, @Cuberto! Sorry about any confusion there. This would only happen if the very first ScrollTrigger (in terms of refreshPriority/order) has once: true. It should be resolved in the next release which you can preview at: 
    https://assets.codepen.io/16327/ScrollTrigger.min.js (you may need to clear your cache)
     
    Better? 
  15. GreenSock's post in How to Animate Radial Gradient Backgrounds was marked as the answer   
    Welcome to GSAP, @BattN
     
    There are many ways you could do that. Here's just one: 

    See the Pen KKYNYgy?editors=0010 by GreenSock (@GreenSock) on CodePen
  16. GreenSock's post in Lenis scroll with Observer Plugin breaks Firefox slow (extremely slow scrolling on firefox) was marked as the answer   
    This sounds like the issue discussed here: 
    https://github.com/darkroomengineering/lenis/issues/311#issuecomment-1986531084
     
    It's not a GSAP/Observer problem - it's a very weird Firefox behavior that Lenis doesn't handle properly but I think they're working on a fix. 
  17. GreenSock's post in How to fix the reverse animation of circle dots using scrolltrigger? was marked as the answer   
    That's a very inefficient way of running that logic. Are you trying to do this?: 

    See the Pen yLraRBd?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    That'll play/reverse the animations when that particular spot on the scroll is hit. But if you want it to be scrubbed instead, you could do that too very easily: 

    See the Pen YzMGJzx?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Lots of options! 
  18. GreenSock's post in Delay between animations was marked as the answer   
    Is this what you're trying to do?: 

    See the Pen wvZGvjp by GreenSock (@GreenSock) on CodePen
     
    I'd strongly recommend reading this article: 
    https://gsap.com/react
     
    You weren't doing proper cleanup in React, and the useGSAP() hook solves that for you. 
  19. GreenSock's post in jpg animation into a canvas was marked as the answer   
    Just to clarify, GSAP is more capable than it has ever been - there was never a time when GSAP just automatically handled <canvas> draw operations for you. It can animate literally any property of any object (not just DOM elements), so you could do it this way: 
     

    See the Pen OJGXKwZ?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Enjoy!
  20. GreenSock's post in Motion path positioning object was marked as the answer   
    We usually don't code a custom solution for you in these forums, but I knew how to do this and figured it'd be fun challenge, so here you go: 
     

    See the Pen PogzKNO?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Is that what you're looking for? 
  21. GreenSock's post in Stagger calculations on a scrolltrigger tween was marked as the answer   
    Yep, that's because the default duration is 0.5 (you didn't set a duration, so it uses the default). Therefore, if each one animates for 0.5 seconds, and you stagger their start times by 0.5 seconds, that means they'd be perfectly sequenced. If you set the duration to 1 second, then you'd need a stagger of 1 to have them perfectly sequenced. See how it works? 
     
    And yes, when you set scrub: true on a ScrollTriggered animation, it just squishes/stretches it to fit perfectly between the start and end scroll positions. 
     
    I hope that clears things up. 
  22. GreenSock's post in Choppy animation in Safari was marked as the answer   
    Yeah, that choppiness has nothing to do with GSAP - welcome to the world of Safari rendering problems. Safari is notorious for really bad rendering problems, sluggishness, and odd behavior. You might want to consider animating PNG images with transparency rather than SVG because you're putting a LOT of pressure on the CPU for fabricating all those pixels. Raster images are much easier for the browser to push around. 
  23. GreenSock's post in Demo lagSmoothing was marked as the answer   
    That's because your fabricated "lag" doesn't exceed the threshold. lagSmoothing(500, 33) basically means "only apply lagSmoothing when a single tick takes MORE than 500ms". And lagSmoothing(1000, 20) would need the tick to take more than 1000ms to kick in lagSmoothing. 
     
    So you can increase the numIterationsyou're passing to your startLag() method. Maybe add a 0 to the end. It also depends on the speed of the device you're running the test on. Some machines will execute that loop faster than others. 
  24. GreenSock's post in Published NPM package with shockingly was marked as the answer   
    @Torben you published a public NPM package that uses members-only plugins? Yikes. 🫣 
     
    What would you expect to happen if a random person installed your package? It shouldn't be able to leverage those plugins of course. So yeah, this would all depend on your having your local .npmrc file set up properly so that it accurately resolves that repository to the npm.greensock.com one and passes along your token. And you're absolutely right about making sure you don't put that in your repository because it'd have your token in there which should never be shared. 
  25. GreenSock's post in Weird delay when reversing animation was marked as the answer   
    You can just use a variable to track the open/closed state: 

    See the Pen bGJpzGP?editors=0010 by GreenSock (@GreenSock) on CodePen
     
    Spam-click as much as you want! 🙂
×
×
  • Create New...