Skip to content

Instantly share code, notes, and snippets.

@sladg
Created July 27, 2022 14:03
Show Gist options
  • Save sladg/2dbfee87129ab2d9712cd2e0d8d0a49c to your computer and use it in GitHub Desktop.
Save sladg/2dbfee87129ab2d9712cd2e0d8d0a49c to your computer and use it in GitHub Desktop.
Simple util function for handling scrolls in react-virtual
import { MutableRefObject, useCallback, useRef } from 'react'
interface UseScrollToProps {
parentRef: MutableRefObject<HTMLDivElement>
}
// https://gist.github.com/gre/1650294
const easeInOutQuint = t => {
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t
}
export const useScrollTo = ({ parentRef }: UseScrollToProps) => {
const scrollingRef = useRef<number>()
const scrollToFn = useCallback((offset, defaultScrollTo) => {
const duration = 300
const start = parentRef.current.scrollTop
const startTime = (scrollingRef.current = Date.now())
const run = () => {
if (scrollingRef.current !== startTime) return
const now = Date.now()
const elapsed = now - startTime
const progress = easeInOutQuint(Math.min(elapsed / duration, 1))
const interpolated = start + (offset - start) * progress
if (elapsed < duration) {
defaultScrollTo(interpolated)
requestAnimationFrame(run)
} else {
defaultScrollTo(interpolated)
}
}
requestAnimationFrame(run)
}, [])
return { scrollToFn }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment