Pure Javascript rAF (requestAnimationFrame) - 如何以最高可用帧率更新屏幕?

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

我正在学习JavaScript,有8年的Python经验,作为练习,我做了一个曼德尔布罗特渲染器,生成分形并使用 putImageData 来从左到右更新画布,每次更新一个单像素列。

我发现,采用这种方法,浏览器中的可见图像只有在全屏计算完成后才会更新(而不是像我所希望的那样看到它从左到右逐渐出现)。我理解这是预期的行为,所以我决定通过使用以下方法来添加 "扫描线 "动画 requestAnimationFrame. (就像这里看到的那样。Christian Stigen Larsen渲染器)

我的期望是,较轻的计算应该渲染得更快(因为下一帧很快就可以使用),而较高迭代的计算应该渲染得更慢。我在我的实现中发现,扫描线的速度一直很慢。

我已经将这个问题与我的曼德尔布罗特计算隔离开来,因为这种行为也发生在下面的最小情况下。我在Chrome 83浏览器上运行,看到画布以恒定的速度(大约每秒30个像素)从左到右缓慢填充。

是我的 rAF 实现不正确,还是我的期望值有问题?我链接到的渲染器使用的是 setTimeout() 来制作动画,但我读到这是目前广泛不鼓励的做法。

我应该如何以最高的可用帧率(目前我并不担心限制帧率)实现画布的从左到右扫描更新?

EDIT: 为了清楚起见,下面的代码是在RAF的每一帧请求中画一个薄薄的矩形,并取下 恰恰 绘制整个画布所需的时间与100次迭代的Mandelbrot渲染所需的时间相同。

这说明它的慢并不是由于帧之间的计算量造成的。

const canvas = document.querySelector('.myCanvas');
const width =  window.innerWidth;
const height = window.innerHeight;
const ctx = canvas.getContext('2d');

function anim(timestamp, i) {
  if (i < width) {
    ctx.fillRect(i, 0, 1, height);
    window.requestAnimationFrame(function(timestamp) {
      anim(timestamp, i + 1);
    })
  }
}

ctx.fillStyle = 'rgb(0,0,0)';
window.requestAnimationFrame(function(timestamp) {
  anim(timestamp, 0);
});
<!DOCTYPE html>
<html lang="en">

<head>
  <canvas class="myCanvas">
        <p>Add suitable fallback here.</p>
    </canvas>
  <script src="slow%20rAF.js"></script>
  <style>
    body {
      margin: 0;
      overflow: hidden;
    }
  </style>
  <meta charset="UTF-8">
  <title>Mandelbrot</title>
</head>

<body>




</body>


</html>
javascript requestanimationframe
1个回答
2
投票

没有 "更快的 "requestAnimationFrame。

一般来说,答案是将计算和渲染分开。理想情况下,计算发生在主线程之外,渲染则在主线程上处理。即使没有线程,你也应该能够找到一种方法在 RAF 之外进行计算,并让 RAF 渲染像素。

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