Geo*_*nts 4 javascript canvas vsync low-latency
我的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 }
})
Run Code Online (Sandbox Code Playgroud)
我的 HTML 只是画布声明。
据我了解,setinterval(x, 0) 应该尽可能快地运行,但它永远不会超过 60fps。我试图达到 240+ fps 以减少输入延迟。
首先,永远不要使用setInterval(fn, lessThan10). 很有可能fn需要比这个时间更多的时间来执行,并且您最终可能会毫无间隔地堆叠大量调用,这可能会导致*与众所周知的浏览器崩溃程序\xc2\xaefn相同的结果。 while(true)
*好吧,在正确的实现中,这不应该发生,但你知道......
\n\n现在,针对你的问题...
\n\n你的代码有很大缺陷。
\n\n您实际上正在同时运行两个不同的循环,它们不会以相同的时间间隔被调用。
\n\nsetInterval(fn, 0)\n您的两个循环没有链接,因此,您在第一个循环中测量的并不是您的循环的速率draw。有点像如果你这样做了
\n\nsetInterval(checkRate, 16.6);\nsetInterval(thefuncIWantToMeasure, 0);\nRun Code Online (Sandbox Code Playgroud)\n\n显然,你的checkRate测量不thefuncIWantToMeasure正确
所以只是为了表明setTimeout(fn, 0)循环将以更高的速率触发:
setInterval(checkRate, 16.6);\nsetInterval(thefuncIWantToMeasure, 0);\nRun Code Online (Sandbox Code Playgroud)\r\nvar c = document.getElementById("myCanvas");\r\nvar ctx = c.getContext("2d");\r\n\r\nvar mouse = {\r\n x: 0,\r\n y: 0\r\n}\r\n\r\nconst times = [];\r\nlet fps;\r\ndraw();\r\n\r\nfunction draw() {\r\n const now = performance.now();\r\n while (times.length > 0 && times[0] <= now - 1000) {\r\n times.shift();\r\n }\r\n times.push(now);\r\n fps = times.length;\r\n\r\n ctx.fillStyle = "black"\r\n ctx.fillRect(0, 0, c.width, c.height);\r\n ctx.strokeStyle = "white"\r\n ctx.beginPath();\r\n ctx.arc(mouse.x, mouse.y, 40, 0, 2 * Math.PI);\r\n ctx.stroke();\r\n ctx.font = "30px Comic Sans MS";\r\n ctx.fillStyle = "red";\r\n ctx.textAlign = "center";\r\n ctx.fillText(fps, c.width / 2, c.height / 2);\r\n setTimeout(draw, 0);\r\n}Run Code Online (Sandbox Code Playgroud)\r\n现在,即使嵌套setTimeout循环比 更好setInterval,您所做的只是视觉动画。
以比浏览器的绘制速度更快的速度绘制此视觉动画是没有意义的,因为您在此画布上绘制的内容不会绘制到屏幕上。
\n\n正如前面所说,这正是requestAnimationFrame循环触发的速率。因此,请将此方法用于所有视觉动画(至少如果必须将其绘制到屏幕上,对于某些罕见的情况,如果需要,我可以在评论中将您链接到其他方法)。
现在要解决您的实际问题,即不是以更高的速率渲染,而是以这样的速率处理用户的输入,那么解决方案就是拆分您的代码。
\n\n| 归档时间: |
|
| 查看次数: |
2270 次 |
| 最近记录: |