首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >渲染画布速度超过每秒60次?

渲染画布速度超过每秒60次?
EN

Stack Overflow用户
提问于 2018-06-08 05:46:26
回答 1查看 0关注 0票数 0

我的JS代码:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var mouse = {x:0,y:0}

const times = [];
let fps;

function refreshLoop() {
  window.requestAnimationFrame(() => {
    const now = performance.now();
    while (times.length > 0 && times[0] <= now - 1000) {
      times.shift();
    }
    times.push(now);
    fps = times.length;
    refreshLoop();
  });
}

refreshLoop();

function draw() {
  ctx.fillStyle = "black"
  ctx.fillRect(0, 0, c.width, c.height);
  ctx.strokeStyle = "white"
  ctx.beginPath();
  var e = window.event;
  ctx.arc(mouse.x, mouse.y, 40, 0, 2*Math.PI);
  ctx.stroke();
  ctx.font = "30px Comic Sans MS";
  ctx.fillStyle = "red";
  ctx.textAlign = "center";
  ctx.fillText(fps, c.width/2, c.height/2); 
}

setInterval(draw, 0);

document.addEventListener('mousemove', function(event){
  mouse = { x: event.clientX, y: event.clientY }
})

我的HTML只是画布声明。

据我的理解,setinterval(x,0)应该尽可能快地运行,但它永远不会超过60fps。我试图达到240 + fps以减少输入延迟。

EN

回答 1

Stack Overflow用户

发布于 2018-06-08 15:39:08

首先,不要使用setInterval(fn, lessThan10)。很有可能fn需要超过这段时间才能执行,并且最终可能会堆叠很多fn无间隔的呼叫,这可能会导致*与众所周知的while(true) 浏览器crasher®相同

实际上,你正在同时运行两个不同的循环,这些循环不会以相同的时间间隔进行调用。

  • 你在requestAnimationFrame循环中检查fps,该循环将设置为与浏览器的绘制速率相同的频率(通常为60 * fps *)。
  • 你在绘制setInterval(fn, 0) 你的两个循环没有链接,因此,你在第一个测量的是你draw调用的速度。

如果你这样做有点像

setInterval(checkRate, 16.6);
setInterval(thefuncIWantToMeasure, 0);

显然,你的checkRate测量不会thefuncIWantToMeasure正确

所以只是为了表明一个setTimeout(fn, 0)循环将以更高的速率触发:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var mouse = {
  x: 0,
  y: 0
}

const times = [];
let fps;
draw();

function draw() {
  const now = performance.now();
  while (times.length > 0 && times[0] <= now - 1000) {
    times.shift();
  }
  times.push(now);
  fps = times.length;

  ctx.fillStyle = "black"
  ctx.fillRect(0, 0, c.width, c.height);
  ctx.strokeStyle = "white"
  ctx.beginPath();
  ctx.arc(mouse.x, mouse.y, 40, 0, 2 * Math.PI);
  ctx.stroke();
  ctx.font = "30px Comic Sans MS";
  ctx.fillStyle = "red";
  ctx.textAlign = "center";
  ctx.fillText(fps, c.width / 2, c.height / 2);
  setTimeout(draw, 0);
}
<canvas id="myCanvas"></canvas>

现在,即使嵌套setTimeout循环好于setInterval,你正在做的是一个视觉动画。

绘制这个视觉动画比浏览器的绘制速度更快是没有意义的,因为你在这个画布上绘制的内容不会被绘制到屏幕上。

正如前面所说,这正是requestAnimationFrame循环发射的速度。因此,对所有的视觉动画使用这种方法(至少如果它必须被画到屏幕上,在一些罕见的情况下,如果需要,还有其他方法可以将你链接到注释中)。

现在要解决你的实际问题,不是以更高的速度呈现,而是以这样的速度处理用户的输入,那么解决方案就是拆分代码。

  • 保持绘图部分绑定到requestAniamtionFrame循环,不需要变得更快。
  • 更新你的对象的值,该值应该根据用户的输入同步响应用户的手势。但是,请注意,某些用户的手势实际上以非常高的速度触发(例如,WheelEvent或窗口的调整大小事件)。通常,你不需要获取此类事件的所有值,因此你可能希望将它们绑定到RAF限制器中。
  • 如果你需要使用移动的对象执行碰撞检测,那么执行数学运算将更新用户手势内的移动对象,但不要在屏幕上绘制它。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档