Jump to content
Search Community

merlin

Premium
  • Posts

    37
  • Joined

  • Last visited

Posts posted by merlin

  1. 1 minute ago, Cassie said:

     

    Mmm. No there's not any layout/sorting behaviour. Not adding ScrollSmoother on touch devices will just remove smooth scrolling. It shouldn't affect your ScrollTriggers at all.

     

    Sanity check - @GreenSock?

    We use multiple scrollTriggers in different components.
    For instance:

      useLayoutEffect(() => {
        if (!ref.current) return;
        const tl = gsap
          .timeline({
            scrollTrigger: {
              trigger: containerRef.current,
              scrub: true,
              start: '-=15%',
              end: `+=40%`,
            },
          })
          .to(ref.current.position, {
            y: -11,
            ease: 'power4.inOut',
          });
    
        return () => {
          tl.kill();
        };
      }, [ref.current, containerRef]);

    When I disable (early return) ScrollSmoother it seems to overlap all the elements with a scrollTrigger binded to them.

    But, maybe we need to look at the issue as to why the scrollTriggers end up shocky. If we find something for that, this won't need to be fixed! Since I think the overlapping will be a more complex issue to reproduce?

    • Like 1
  2. 2 hours ago, GreenSock said:

    @merlin any chance you could provide a much simpler reduced test case like in CodePen that isn't dependent on any frameworks? Just some simple colored <div> elements is fine. I couldn't seem to replicate it in a simpler fashion and I wonder if it's somehow related to a ThreeJS rendering cycle issue or a React thing or what(?) I very well may be missing something obvious.

    Hi Jack!

    Hope you're well :)

     

    This was the most reduced CSB that I could do with react-three-fiber, just to give a good impression and stay closer to what we're building for our client.

    This is a more reduced version: https://codesandbox.io/s/circling-birds-forked-bvnq23?file=/src/App.js

     

    I'm adding a video of the unexpected behaviour.

    You can see that while scrolling with touch, the pinned container seems to glitch a little up or down (shown as whitespace).

  3. 14 hours ago, Cassie said:

    Ok, So the solution I provided should be good for your use case

    https://3q4st8.csb.app/
     

    if (!ScrollTrigger.isTouch) {
      const smoothScroll = ScrollSmoother.create({
       smooth: 1
      })
    }


    We'll look into it though, thanks for the demos!

     

    Hey Cassie!

    Thanks so much for all the help :)
    I added this to check behaviour on mobile, but then all scrolltrigger instances (about 6) are overlapping each other (even when having `preventOverlaps` enabled.

     

    So it seems like ScrollSmoother also added some type of sorting/layout behaviour?

    • Like 1
  4. 8 minutes ago, Cassie said:

    I'm a little confused now. The issue is on chrome on desktop now? Not on mobile? Can you break this down again for me - just let me know exactly what the issue is and how to recreate? (sorry)

    Also if mobile is the issue and you're not using ScrollSmoother for normalize scroll, or effects or smoothing, maybe only create it on non touch devices?

    if (!ScrollTrigger.isTouch) {
      const smoothScroll = ScrollSmoother.create({
       smooth: 1
      })
    }


    🦜 also I like those birds. 🦩
     

    Ah sorry! I see that's confusing.
    The issue arrises when you view the website in Chrome with devtools and emulate mobile (touch) like the video.
    And also when you just go there on mobile (Chrome, possibly other browsers as well).

    To recreate (DevTools mobile emulator):
    - Open https://zosxos.csb.app/
    - Open DevTools, Toggle Device Toolbar (CMD+SHIFT+M), pick iPhone 12 or other device
    - Refresh page
    - Scroll with "mouse-drag" which is actually a faked touch (like video)

    To recreate (Mobile):
    - Open https://zosxos.csb.app/
    - Scroll

     

    • Like 1
  5. Thanks Cassie!

    It seems like this fixes the shaky scroll:

     

      useLayoutEffect(() => {
        ScrollTrigger.normalizeScroll(true);
    
        const smoothScroll = ScrollSmoother.create({
          smooth: 1, // how long (in seconds) it takes to "catch up" to the native scroll position
          // This causes buttons to scroll to top =======================================================================
          // smoothTouch: 0, // much shorter smoothing time on touch devices (default is NO smoothing on touch devices)
          ignoreMobileResize: true,
          // normalizeScroll: true,
          onUpdate: x => {
            useScrollValue.setState({ scrollValue: x.scrollTop() });
          },
        });
    
        if (window.location.hash) {
          smoothScroll.scrollTo(window.location.hash, true);
        }
    
        return () => {
          smoothScroll.kill();
        };
      }, []);

     

    • Like 3
  6. Hi there!

     

    I tried combining ScrollSmoother with scrub/pin timelines.

    Apparently when using a touch-device (or devtools device emulator) it gets extremely shaky when "touch" to scroll.

     

    I was wondering if there's anything wrong with the code or that it's a bug?

     

    This CSB is a really small example of what i'm doing in a project, where the problem is arising as well.

     

    Steps to reproduce:

    - Open devtools -> mobile view -> iphone 12

    - Use mouse to drag on screen (long drag, flicks work!)

     

     

    https://codesandbox.io/s/scrollsmoother-gsap-test-forked-ipydx4

    • Like 1
  7. Hiya!

    @SteveS @Cassie

    We've sort of found the issue.

    It seems that removing `smoothTouch` fixed the issue.

    We're not sure why or how it became an issue. We'll do some further investigating to see why/how that happened.

    In the meantime, if anyone from GSAP official team wants a copy of the repository, just ask! We're working on a client project so can't just open that up to anyone :)

     

    Best,

    Level30Wizards

    • Like 1
  8. Hi @SteveS !

    Thanks for checking it out.

     

    To clarifyL

    1. You load the page
    2. click a button and it scrolls correctly doesn't scroll as expected (it's just a regular <button> no events)
    3. you resize the page to mobile
    4. click any button and it scrolls to the top of the page

    I tried adding it outside of function scope, which sometimes broke.

    The setState is by `zustand` which is de-coupled from React state so that doesn't affect React's Event Loop

     

    So the buttons should never actually scroll the page, we use anchors with hash links for that

    EDIT: Changing the `<Box>` elements to regular `<div>` doesn't fix it either

  9. I found that one!
    We don't unfortunately. We use Next.js.

    We're also using the 3.10.4 version of ScrollSmoother.

     

    I've just tried putting it outside of the function scope but this doesn't work:

     

    ScrollSmoother.create({
      smooth: 1, // how long (in seconds) it takes to "catch up" to the native scroll position
      smoothTouch: 0.1, // much shorter smoothing time on touch devices (default is NO smoothing on touch devices)
      onUpdate: x => {
        useScrollValue.setState({ scrollValue: x.scrollTop() });
      },
    });
    
    export function BaseLayout({ children, settings }: BaseLayoutProps) {
      useLayoutEffect(() => {
        const smoothScroll = ScrollSmoother.get();
    
        if (window.location.hash) {
          smoothScroll.scrollTo(window.location.hash, true);
        }
    
        return () => {
          smoothScroll.kill();
        };
      }, []);
    
      return (
        <Flex flexDirection="column">
          <Header settings={settings} />
    
          <Box id="smooth-wrapper" as="main" flex="1 0 auto" display="block">
            <Box
              id="smooth-content"
              background="radial-gradient(74.69% 74.69% at 50% 74.69%, rgba(0, 103, 171, 0.2) 0%, rgba(36, 54, 66, 0.2) 100%), #243642"
              sx={{
                contain: 'layout',
              }}>
              {children}
              <Footer settings={settings} />
            </Box>
          </Box>
        </Flex>
      );
    }

     

  10. Hi all,

     

    We encountered an issue with ScrollSmoother where when we change our browser to mobile size (375px) using DevTools in Chrome, every <button type="button"> we click scrolls back to top.

     

    I tried to create a CodeSandbox, but since ScrollSmoother is a paid plugin I kinda failed to do that.

     

    This is our wrapper (`Box` is a `<div>` and `Flex` is a `<div>` with `display: flex` :

    export function BaseLayout({ children, settings }: BaseLayoutProps) {
      useLayoutEffect(() => {
        const smoothScroll = ScrollSmoother.create({
          smooth: 1, // how long (in seconds) it takes to "catch up" to the native scroll position
          smoothTouch: 0.1, // much shorter smoothing time on touch devices (default is NO smoothing on touch devices)
          onUpdate: x => {
            useScrollValue.setState({ scrollValue: x.scrollTop() });
          },
        });
    
        if (window.location.hash) {
          smoothScroll.scrollTo(window.location.hash, true);
        }
    
        return () => {
          smoothScroll.kill();
        };
      });
    
      return (
        <Flex flexDirection="column">
          <Header settings={settings} />
    
          <Box id="smooth-wrapper" as="main" flex="1 0 auto" display="block">
            <Box
              id="smooth-content"
              background="radial-gradient(74.69% 74.69% at 50% 74.69%, rgba(0, 103, 171, 0.2) 0%, rgba(36, 54, 66, 0.2) 100%), #243642"
              sx={{
                contain: 'layout',
              }}>
              {children}
              <Footer settings={settings} />
            </Box>
          </Box>
        </Flex>
      );
    }

     

  11. Hi there,

     

    I'm trying to add a scrolltrigger instance after another has ended.

    Just wondering if that's possible, or if I should resort to tracking progress in onUpdate.

    See `tl2` start and `tl` end.

     

    Next to that, I have another timeline that should travel the same distance, but finish just a bit earlier `carpetTl`. Is this best practice or can I do that more neatly?

     

    Thanks!

     

    const TIMELINE_LENGTH = 300;
    const container = containerRef.current;
    const scrollProgress = { value: 0 };
    
    const tl = gsap
    .timeline({
      scrollTrigger: {
        trigger: container,
        pin: true,
        scrub: true,
        end: `+=${TIMELINE_LENGTH}%`,
      },
    })
    .to(
      scrollProgress,
      {
        value: 1,
        onUpdate: () => {
          camera.position.copy(catmull.getPoint(scrollProgress.value));
          camera.lookAt(catmullLookat.getPoint(scrollProgress.value));
        },
      },
      0,
    );
    
    const tl2 = gsap
    .timeline({
      scrollTrigger: {
        trigger: container,
        pin: true,
        scrub: true,
        start: `+=${TIMELINE_LENGTH}%`,
        end: `+=${TIMELINE_LENGTH * 2}%`,
      },
    })
    .to(scrollProgress, {
      onEnter: () => {
        setTransitionCard(true);
      },
      onLeave: () => {
        setTransitionCard(false);
      },
    });
    
    const carpetTl = gsap
    .timeline({
      scrollTrigger: {
        trigger: container,
        pin: true,
        scrub: true,
        end: `+=${TIMELINE_LENGTH * 0.7}%`,
      },
    })
    .fromTo(
      redCarpetRef.current.position,
      {
        z: 1130,
      },
      {
        z: 350,
      },
      0,
    )
    .fromTo(
      redCarpetRollRef.current.position,
      {
        y: 4,
      },
      {
        y: 0,
      },
      0,
    )
    .fromTo(
      redCarpetRollRef.current.scale,
      {
        z: 1,
      },
      {
        z: 0,
      },
      0,
    );

     

  12. Using GSAP V3.0.1

    Anyone know why an error like this may occur?
    We’re importing eases like this:
    import { Power1 } from 'gsap/all'
    which is the v2 way.
    We’ve tried with power1.in aswell, same error.
    The ‘undefined’ comes from Linear which I think makes sense because you can’t ease a linear?

    WhatsApp Image 2019-11-21 at 08.39.50.jpeg

  13. I’m trying to animate an SVG path which I use as a clip-path into another path with MorphSVG but it seems to be that my first path won’t dissolve completely in the other?

     

    Inside of the SVG called `#clippert` there are two paths, #morph-to and #clippert-path which I am trying to morph in a loop (where they yoyo as well)

     

    I've tried it like this:

    const tl = new TimelineMax()
    tl
    	.to("#clippert-path", 1, {
    		morphSVG: {
    			shape:"#morphTo",
    		},
    		repeat:-1,
    		yoyo:true,
    	})	

     

    But that doesn't seem to do it for the full path?

    See the Pen MMbXOQ by meesrutten (@meesrutten) on CodePen

×
×
  • Create New...