ashthornton / asscroll

Ash's Smooth Scroll 🍑
MIT License
947 stars 27 forks source link

Behavior where scroll position is repeated #56

Closed pr1ntr closed 3 years ago

pr1ntr commented 3 years ago

I am tryin to implement asscroll with ScrollTrigger which works fine, but I get a strange behavior with and without using scrolltrigger. For some reason whenever I scroll (with wheel or moving the scrollbar) the scroll progress gets to its target and then reverts to the prescroll position and does it again. Its like something doesn't catch up with the scroll state and resets it.

My DOM is a bit weird, I have basically an empty container (React) the refs are the the target elements f or scrollTrigger and asscroll. I only have one element that sits a the bottom of this empty container as I want it to scroll in naturally. The rest of the content is in fixed panels that have their own animations based on scroll position.

<ScrollRange ref={asscrollContainerRef}>
  <ScrollInner
    ref={containerRef}
    css={{
      height: '400vh',
    }}
  >
    <BackgroundVideo videoRef={videoRef} />
  </ScrollInner>
</ScrollRange>

The asscroll code waits for an appReady state variable to become true before it initializes

useEffect(() => {
  if (appReady) {
    asscrollRef.current = new ASScroll({
      containerElement: asscrollContainerRef.current,
      disableRaf: true,
    })
    const asscroll = asscrollRef.current

    gsap.ticker.add(asscroll.update)

    ScrollTrigger.defaults({
      scroller: asscroll.containerElement,
    })

    ScrollTrigger.scrollerProxy(asscroll.containerElement, {
      scrollTop(value) {
        return arguments.length ? asscroll.scrollTo(value) : asscroll.currentPos
      },
      getBoundingClientRect() {
        return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight }
      },
    })

    asscroll.on('update', ScrollTrigger.update)

    ScrollTrigger.addEventListener('refresh', asscroll.resize)

    mainTimeline.current = gsap.timeline({
      scrollTrigger: {
        trigger: containerRef.current,
        start: 'top top',
        end: 'bottom bottom',
        // onSnapComplete,
        // snap: {
        //   snapTo,
        // },
        onUpdate,
      },
    })

    asscroll.enable()
  }
  //eslint-disable-next-line
}, [appReady])

this is basically the same implementation as your scrolltrigger example. I attached a video of the behavior

https://user-images.githubusercontent.com/1272089/118296141-79b38d80-b491-11eb-8519-c4c73fdea25d.mp4

So after every scroll it resets to the start position of the scroll and then does the scroll again. I am confident that I am doing something wrong, and its not the library as it works for everyone else ;). Any help would be appreciated.

[edit]

Forgot to add CSS for the DOM elements

const ScrollRange = styled('div', { position: 'fixed' })
const ScrollInner = styled('div', {
  position: 'relative',
  display: 'flex',
  flexDirection: 'column',
  justifyContent: 'flex-end',
})
ashthornton commented 3 years ago

It's hard to say without seeing a live example (maybe you could make a CodeSandbox or similar if this doesn't help), but it looks like there could be 2 ASScroll instances running at the same time, with that sort of behaviour.

Does the code inside the useEffect callback definitely run just once?

ashthornton commented 3 years ago

Closing due to inactivity.

S-n-d commented 3 years ago

@pr1ntr did you find a solution for this? Running into the exact same problem.

watarutmnh commented 3 years ago

I had a similar issue. In my case I could fix it removing style below:

html {
    scroll-behavior: smooth;
}
S-n-d commented 3 years ago

@watarutmnh thank you very much! That is indeed the solution.