我必须在下一个requestAnimationFrame之前取消iMationFrame吗?

发布于 2025-01-22 16:25:43 字数 2818 浏览 0 评论 0原文

在这里,我在React中有一个简单的计时器应用程序。我是否需要始终调用cancelAnimationFrame在调用Next requestanimationFrame in and> Animate方法中?

我从某个地方读到,如果我在单个回调中调用多个requestAnimationFrame,则需要CANCELANIMATIONFRAME。但是在我的示例中,我在单个回调中调用单个requestAnimationFrame

当一个人说不需要时,我什至感到困惑,而另一个人在本文中说需要: https ://medium.com/@moonformeli/hi-caprice-liu-8803cd542aaa

function App() {
  const [timer, setTimer] = React.useState(0);
  const [isActive, setIsActive] = React.useState(false);
  const [isPaused, setIsPaused] = React.useState(false);
  const increment = React.useRef(null);
  const start = React.useRef(null);

  const handleStart = () => {
    setIsActive(true);
    setIsPaused(true);
    setTimer(timer);
    start.current = Date.now() - timer;
    increment.current = requestAnimationFrame(animate);
  };

  const animate = () => {
    setTimer(Date.now() - start.current);
    cancelAnimationFrame(increment.current);
    increment.current = requestAnimationFrame(animate);
  };

  const handlePause = () => {
    cancelAnimationFrame(increment.current);
    start.current = 0;
    setIsPaused(false);
  };

  const handleResume = () => {
    setIsPaused(true);
    start.current = Date.now() - timer;

    increment.current = requestAnimationFrame(animate);
  };

  const handleReset = () => {
    cancelAnimationFrame(increment.current);
    setIsActive(false);
    setIsPaused(false);
    setTimer(0);
    start.current = 0;
  };

  return (
    <div className="app">
      <div className="stopwatch-card">
        <p>{timer}</p>
        <div className="buttons">
          {!isActive && !isPaused ? (
            <button onClick={handleStart}>Start</button>
          ) : isPaused ? (
            <button onClick={handlePause}>Pause</button>
          ) : (
            <button onClick={handleResume}>Resume</button>
          )}
          <button onClick={handleReset} disabled={!isActive}>
            Reset
          </button>
        </div>
      </div>
    </div>
  );
};
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Here I have a simple timer application in React. Do I need to always call cancelAnimationFrame before calling next requestAnimationFrame in animate method?

I read from somewhere that if I call multiple requestAnimationFrame within single callback, then cancelAnimationFrame is required. But in my example, I am calling single requestAnimationFrame in a single callback.

I got even confused when one said no need while another one said need in this article: https://medium.com/@moonformeli/hi-caprice-liu-8803cd542aaa

function App() {
  const [timer, setTimer] = React.useState(0);
  const [isActive, setIsActive] = React.useState(false);
  const [isPaused, setIsPaused] = React.useState(false);
  const increment = React.useRef(null);
  const start = React.useRef(null);

  const handleStart = () => {
    setIsActive(true);
    setIsPaused(true);
    setTimer(timer);
    start.current = Date.now() - timer;
    increment.current = requestAnimationFrame(animate);
  };

  const animate = () => {
    setTimer(Date.now() - start.current);
    cancelAnimationFrame(increment.current);
    increment.current = requestAnimationFrame(animate);
  };

  const handlePause = () => {
    cancelAnimationFrame(increment.current);
    start.current = 0;
    setIsPaused(false);
  };

  const handleResume = () => {
    setIsPaused(true);
    start.current = Date.now() - timer;

    increment.current = requestAnimationFrame(animate);
  };

  const handleReset = () => {
    cancelAnimationFrame(increment.current);
    setIsActive(false);
    setIsPaused(false);
    setTimer(0);
    start.current = 0;
  };

  return (
    <div className="app">
      <div className="stopwatch-card">
        <p>{timer}</p>
        <div className="buttons">
          {!isActive && !isPaused ? (
            <button onClick={handleStart}>Start</button>
          ) : isPaused ? (
            <button onClick={handlePause}>Pause</button>
          ) : (
            <button onClick={handleResume}>Resume</button>
          )}
          <button onClick={handleReset} disabled={!isActive}>
            Reset
          </button>
        </div>
      </div>
    </div>
  );
};
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

看春风乍起 2025-01-29 16:25:43

不,您不需要在递归功能中取消RAF,因为RAF就像SetteMeut一样,但是它可以与屏幕刷新率完美地执行该功能,因此它仅执行一次:

const animate = ()=>{
    setTimer(Date.now()-start.current)
    increment.current = requestAnimationFrame(animate)
  }

No you don't need to cancel the raf in the recursive function, since a raf is just like a setTimeout, but it executes the function in perfect sync with the screen refresh rate, so it executes only once:

const animate = ()=>{
    setTimer(Date.now()-start.current)
    increment.current = requestAnimationFrame(animate)
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文