HTML Canvas Lag

时间:2015-04-26 23:00:33

标签: javascript html canvas html5-canvas lag

因此,我创建了一个画布,当您将鼠标悬停在其上方时,会出现一个绿色的32x32框。画布非常大,所以你可以绘制大量的肖像,问题是绘制绿色框使画布和我的整个浏览器滞后。

我添加的那部分让它变得迟钝:

function makeTileCover(mousex, mousey) {
    ctx.strokeStyle = "green";
    ctx.strokeRect(mousex, mousey, 32, 32);
    ctx.stroke();
}

我猜测有一些简单的答案可以解决这个问题,看起来它可能画了太多次,因为正方形变得越来越暗,你盘旋的越多,尽管我都是无论如何都不确定这会解决它。



var canvas = document.getElementById("MapEditor");
var ctx = canvas.getContext("2d");

function updateCanvas() {
  container = document.getElementById("container");
  if (container.width != window.innerWidth) {
    container.style.width = window.innerWidth - 250;
  }
  if (container.height != window.innerHeight) {
    container.style.height = window.innerHeight;
  }
}

//Destroy mouse on canvas exit.
canvas.addEventListener('mouseout', function() {
  document.body.style.cursor = 'auto';
});

function getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
  };
}

canvas.addEventListener('mousemove', function(evt) {
  var mousePos = getMousePos(canvas, evt);
  var mousex = Math.round(mousePos.x / 32) * 32;
  var mousey = Math.round(mousePos.y / 32) * 32;
  var cursor = document.createElement('canvas'),
    cursorctx = cursor.getContext('2d');

  cursor.width = 32;
  cursor.height = 32;

  makeTileCover(mousex, mousey);

  document.body.style.cursor = 'url(' + cursor.toDataURL() + '), auto';
  document.getElementById('mousePosLocation').innerHTML = "Mouse location:" + "<b id='mousex'>" + mousex + "</b>" + "," + "<b id='mousey'>" + mousey + "</b>";
}, false);

function makeTileCover(mousex, mousey) {
  ctx.strokeStyle = "green";
  ctx.strokeRect(mousex, mousey, 32, 32);
  ctx.stroke();
}
&#13;
canvas {
  background-color: black;
}
&#13;
<div id="container">
  <canvas width="16384" height="16384" id="MapEditor"></canvas>
</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

你在MouseMove上做得太多,每帧可能会发射很多次,并且可以在帧的任何时间发生。

在输入事件上,您希望尽可能小。

我认为你能够做到这一点:

 canvas.addEventListener('mousemove', function(evt) {
   //I'm attaching it to Window for now. Ideally, you'd use a private namespace.
   window.mousePos = getMousePos(canvas, evt);
 }, false);

只需设置一个变量然后继续。

其他所有内容都应与requestAnimationFrame()触发的回调相关联。这样,鼠标位置将随着每次鼠标移动而更新,但是每个帧只会进行一次绘制,占用最近的鼠标位置。

function draw() {
  window.requestAnimationFrame(draw);

  var mousex = Math.round(mousePos.x / 32) * 32;
  var mousey = Math.round(mousePos.y / 32) * 32;
  var cursor = document.createElement('canvas'),
    cursorctx = cursor.getContext('2d');

  cursor.width = 32;
  cursor.height = 32;

  makeTileCover(mousex, mousey);

  document.body.style.cursor = 'url(' + cursor.toDataURL() + '), auto';
  document.getElementById('mousePosLocation').innerHTML = "Mouse location:" + "<b id='mousex'>" + mousex + "</b>" + "," + "<b id='mousey'>" + mousey + "</b>";
}

作为一个额外的好处,好的浏览器也将在浏览器可以管理的框架的早期发生。这意味着你的长时间运行的代码将尽可能远离正在呈现的帧发生(在监视器需要之前,这个重代码可能需要最长的时间来计算,不像mousemove事件可能发生在之前的几分之一毫秒监视器需要它。)