基于滚动的滞后动画

问题描述 投票:0回答:1

我想实现慢速滚动。我决定创建一个比其内容大 10 倍的容器。然后,根据滚动事件,通过 JavaScript 移动内容。

这个例子是在 React 中,但是很简单。我用 JavaScript 标签标记了这个问题,因为我遇到的问题与 JavaScript 本身有关,而不是与 React/TypeScript/etc 相关。

'use client'

import { useEffect, useRef, useState } from 'react'

const targetHeight = 100 // container's height
const rootHeight = 10000 // 10x times larger container

export default function FooBar() {
  const ref = useRef<HTMLDivElement | null>(null)

  useEffect(() => {
    function onScroll() {
      const scrollTop =
        document.documentElement.scrollTop || document.body.scrollTop
      const scrollHeight =
        document.documentElement.scrollHeight || document.body.scrollHeight
      const clientHeight =
        document.documentElement.clientHeight || window.innerHeight
      const scrollProgress = scrollTop / (scrollHeight - clientHeight) // from 0 to 1
      const result = Math.floor((rootHeight - targetHeight) * scrollProgress)
      setTop(result)
    }

    window.addEventListener('scroll', onScroll, { passive: true })
    return () => {
      window.removeEventListener('scroll', onScroll)
    }
  }, [])

  const [top, setTop] = useState(0)

  return (
    <div
      ref={ref}
      style={{
        height: rootHeight,
      }}
    >
      <div
        style={{
          willChange: 'transform',
          transform: `translate3d(0, ${top}px, 0)`,
          transition: 'width 0s',
        }}
      >
        <div style={{ width: 100, height: 100, background: 'white' }} />
      </div>
    </div>
  )
}

一切并不复杂。但是,当用鼠标滚动时,动画会跳动。请参阅以下复制品: https://stackblitz.com/edit/stackblitz-starters-fqrzww?file=app%2Fpage.tsx

尝试滚动示例。我希望白色矩形能够顺利移动。然而,它太跳跃了。

我真的不知道这种行为的原因是什么。计算出的值不是“跳跃的”,它们是连续的。

javascript
1个回答
0
投票

将计算函数放在useEffect之外,然后重试

© www.soinside.com 2019 - 2024. All rights reserved.