Jump to content
GreenSock

RJWadley

BusinessGreen
  • Posts

    8
  • Joined

  • Last visited

1 Follower

About RJWadley

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

RJWadley's Achievements

  1. Thanks for the reply, Rodrigo. Refreshing ScrollTrigger after the smoother is initialized does not fix the issue. This would be the preferred solution for me if it worked. Relying on some React state to recreate everything if the smoother changes seems like it would work until the underlying issue is fixed, although I don't anticipate that being very nice to performance. Something else I found that works is adding a reverse and a play to the enter trigger, although this will still break if the page isn't at the top when everything's initialized. onEnter: () => { console.log("onEnter TRIGGERED"); timeline.reverse(); timeline.play(); },
  2. If you initialize ScrollSmoother after you create a tween or timeline with a ScrollTrigger, the tween doesn't work correctly. It will either get stuck at the beginning or snap to the end. Plus, if the page is not at the top when initialized, onEnter and onLeave are sometimes fired instantly. In React, effects in components higher in the tree are run later, and since ScrollSmoother is usually in one of the highest components it will always be initialized last, which causes this issue.
  3. If a smoother hasn't been initialized, `ScrollSmoother.get()` will return undefined. This should be reflected in the typing of the get function. The return type is currently `ScrollSmoother`, but it should be `ScrollSmoother | undefined`
  4. It seems like fromTo tweens aren't always reverting in the way I would expect. If I use a from or a to tween, the inline styles set by gsap are removed. However, with a fromTo tween, the element is reset to the beginning of the tween and the inline styles are not reset. For example, in the codepen provided I would expect the box to return to the top left when reverted, but it just returns to the beginning of the tween. Am I missing something or is this a bug?
  5. ScrollSmoother works really well in a desktop environment, but I've run into some issues trying to adapt pinning code to also work well on mobile. I haven't seen anybody on the forum talk about this yet, so I thought I'd share my experience and a solution I've found. On desktop, ScrollSmoother is transforming the entire page, so the default pinType of "transform" works best. On mobile, ScrollSmoother turns off and the page scrolls normally, so the default pinType causes sync jitter. A pinType of "fixed" would work really well here, but that will only work if we haven't initialized ScrollSmoother at all (since ScrollSmoother leaves a transform behind even when disabled). Here's an example that works great on desktop, but jitters on mobile: https://codepen.io/RJWadley/pen/JjpaaYR One potential solution here (and the one that most sane people probably choose) is to enable normalizeScroll. That moves scrolling to the JS thread, which fixes the sync jitter. But it's not always a perfect solution (and in all fairness, there is no "perfect" solution, especially with fruit-based devices). Anyway, decided I just wasn't satisfied with it. Another solution is to always use a fixed pin with pinReparent enabled, but that's not ideal for performance and can break styles, so I'd rather keep that as a last resort. In my mind, a better solution is to just not enable scrollSmoother at all on mobile devices, then choosing pinTypes based off of that. In hindsight it's a very obvious solution, but it took me quite a while to figure it out. A simple util like const usingSmoothScroll = !matchMedia("(hover: none)").matches; can help us determine the device type. And we can use the same util to determine which pin type to use as well: pinType: usingSmoothScroll ? "transform" : "fixed" From there, only create a ScrollSmoother instance if usingSmoothScroll is true: const usingSmoothScroll = !matchMedia("(hover: none)").matches; if (usingSmoothScroll) ScrollSmoother.create({ smooth: 1, smoothTouch: 0.1 //we don't want scrollsmoother to entirely ditch the smooth, that would break our pins }); Here's the same example as above, but employing this technique: https://codepen.io/RJWadley/pen/MWVEzVg We get the buttery goodness of ScrollSmoother on desktop devices, and the firm beauty of fixed pins on mobile. All around a pretty good solution. Keep in mind that if the media query in the util ever changes (like if a 2-in-1 enters tablet mode), nothing will update. And if ScrollSmoother ever picks up the ability to hotswap between smooth and smoothTouch (right now it just picks one and never changes), this would probably need significant changes. I think an overall cleaner solution would a new pinType (maybe "smoother" or "smoother-auto") that uses fixed if smoother is off and transform if smoother is on. In order for that to work, ScrollSmoother would also need to remove any transforms from smooth-content when it disables. But that's entirely up to the gsap devs.
  6. As of now the fix hasn't been deployed. It'll be in the next version of GSAP, most likely either 3.10.5 or 3.11.0 If you can, it's easiest to just wait for the update. If that's not an option, I'd say either use the beta files or Damian's solution. As a temporary measure either should be fine.
  7. I was easily able to reproduce the issue with React 17, although I wasn't able to recreate it using only React. And although I wasn't able to determine any causes, I was able to find a solution. I'll drop it here in case anybody encounters the same issue. I discovered that the issue only occurs if I explicitly create a smooth-wrapper and smooth-content like so: () => { SmoothScroller.create() //this doesn't work return ( <div id="smooth-wrapper"> <div id="smooth-content">{children}</div> </div> // ); //if I remove the explicitly created wrappers, this would work fine //but we would lose control of fixed elements (since they'd no longer be outside the wrapper) return children; } To fix the issue, I moved the ScrollSmoother.create() into gatsby-browser while leaving the smooth-wrapper and smooth-content in place. This fixes the jumping while retaining control of fixed elements, however the scroller won't always be up-to-date with the wrapper and therefore sometimes just won't scroll. This can be resolved pretty easily by adding a useEffect that refreshes the scroller anytime the scroll component updates. That leaves the final solution as follows: //in gatsby-browser SmoothScroller.create() //in Scroll component () => { useEffect(() => { SmoothScroller.get().refresh() }) return ( <div id="smooth-wrapper"> <div id="smooth-content">{children}</div> </div> // ); }
  8. So I'm using Gatsby with ScrollSmoother, and the first time you click the page, it instantly scrolls to the top (without any easing). This only happens on the very first click after loading the page. Does anybody have any insight into why this might be happening? I've created a minimal demo of the issue at: https://codesandbox.io/s/beautiful-wind-yn4yyt?file=/src/components/Scroll.tsx To reproduce: Reload the page Scroll down a bit Click anywhere (any mouse button)
×