Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript HTML画布延迟_Javascript_Html_Canvas_Html5 Canvas_Lag - Fatal编程技术网

Javascript HTML画布延迟

Javascript HTML画布延迟,javascript,html,canvas,html5-canvas,lag,Javascript,Html,Canvas,Html5 Canvas,Lag,因此,我创建了一个画布,当您将鼠标悬停在画布上方时,会出现一个32x32的绿色框。画布非常大,所以你可以画大量的肖像,问题是画绿色的盒子会使画布和我的整个浏览器变大 我添加的部分使其变得滞后: function makeTileCover(mousex, mousey) { ctx.strokeStyle = "green"; ctx.strokeRect(mousex, mousey, 32, 32); ctx.stroke(); } 我猜有一个简单的答案可以解决这个

因此,我创建了一个画布,当您将鼠标悬停在画布上方时,会出现一个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”);
函数updateCanvas(){
容器=document.getElementById(“容器”);
if(container.width!=window.innerWidth){
container.style.width=window.innerWidth-250;
}
if(container.height!=window.innerHeight){
container.style.height=window.innerHeight;
}
}
//在画布出口上销毁鼠标。
addEventListener('mouseout',function(){
document.body.style.cursor='auto';
});
函数getMousePos(画布,evt){
var rect=canvas.getBoundingClientRect();
返回{
x:evt.clientX-rect.left,
y:evt.clientY-rect.top
};
}
canvas.addEventListener('mousemove',函数(evt){
var mousePos=getMousePos(canvas,evt);
var mousex=数学圆(mousePos.x/32)*32;
var mousey=数学圆(mousePos.y/32)*32;
var cursor=document.createElement('canvas'),
cursorctx=cursor.getContext('2d');
光标宽度=32;
光标高度=32;
makeTileCover(mousex,mousey);
document.body.style.cursor='url('+cursor.toDataURL()+'),auto';
document.getElementById('mousePosLocation').innerHTML=“鼠标位置:”+“+mousex+++”,“+”+mousey+”;
},假);
函数makeTileCover(mousex、mousey){
ctx.strokeStyle=“绿色”;
ctx.strokeRect(mousex,mousey,32,32);
ctx.stroke();
}
画布{
背景色:黑色;
}

你在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>";
}
函数绘图(){
window.requestAnimationFrame(绘制);
var mousex=数学圆(mousePos.x/32)*32;
var mousey=数学圆(mousePos.y/32)*32;
var cursor=document.createElement('canvas'),
cursorctx=cursor.getContext('2d');
光标宽度=32;
光标高度=32;
makeTileCover(mousex,mousey);
document.body.style.cursor='url('+cursor.toDataURL()+'),auto';
document.getElementById('mousePosLocation').innerHTML=“鼠标位置:”+“+mousex+++”,“+”+mousey+”;
}

作为一个额外的好处,好的浏览器也将在浏览器能够管理的框架内尽早出现。这意味着长时间运行的代码将发生在尽可能远离显示的帧的地方(在监视器需要它之前,为这段繁重的代码提供尽可能长的计算时间,这与mousemove事件不同,mousemove事件可能发生在监视器需要它之前的几分之一毫秒)问题是你的画布太大了,chrome无法处理它所需的内存。你真的不希望画布比屏幕上的大。(通常约为1080x1920)。结合@ScottMichaud的答案,我们得到

HTML


JS

var canvas=document.getElementById(“MapEditor”);
var ctx=canvas.getContext(“2d”);
var MousePos={x:0,y:0};
函数updateCanvas(){
容器=document.getElementById(“容器”);
if(container.width!=window.innerWidth){
container.style.width=window.innerWidth-250;
}
if(container.height!=window.innerHeight){
container.style.height=window.innerHeight;
}
}
//在画布出口上销毁鼠标。
addEventListener('mouseout',function(){
document.body.style.cursor='auto';
});
函数更新(){
window.requestAnimationFrame(更新);
var mousex=数学圆(MousePos.x/32)*32;
var mousey=数学圆(MousePos.y/32)*32;
ctx.fillRect(0,0,canvas.width,canvas.height);
makeTileCover(ctx、mousex、mousey);
}
函数getMousePos(画布,evt){
var rect=canvas.getBoundingClientRect();
返回{
x:evt.clientX-rect.left,
y:evt.clientY-rect.top
};
}
canvas.addEventListener('mousemove',函数(evt){
MousePos=getMousePos(canvas,evt);
//var cursor=document.createElement('canvas'),
//cursorctx=cursor.getContext('2d');
//光标宽度=32;
//光标高度=32;
//makeTileCover(mousex,mousey);
//document.body.style.cursor='url('+cursor.toDataURL()+'),auto';
//document.getElementById('mousePosLocation').innerHTML=“鼠标位置:”+“+mousex+++”,“+”+mousey+”;
},假);
函数makeTileCover(ctx、mousex、mousey){
ctx.strokeStyle=“绿色”;
ctx.strokeRect(mousex,mousey,32,32);
ctx.stroke();
}
更新();

我还更改了画布,使每一帧都将画布重新填充为黑色,这样就不会有一堆方块填充视图,而只保留光标所在的方块。

FWIW运行代码片段后,我不得不重新启动。那是一幅巨大的画布。你为什么有这么大的一个?你的代码很好。。。你只需要一个更小的画布…它如此之大的原因是它将成为一个游戏的地图编辑器:(与他们的编辑器大小相同。我的Chrome实例刚刚崩溃,内存不足。绝对没有理由使用你的c
<div id="container">
   <canvas width="1638" height="900" id="MapEditor"></canvas>
</div>
 var canvas = document.getElementById("MapEditor");
  var ctx = canvas.getContext("2d");
  var MousePos = {x:0, y:0};
  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 Update(){
    window.requestAnimationFrame(Update);
    var mousex = Math.round(MousePos.x / 32) * 32;
    var mousey = Math.round(MousePos.y / 32) * 32;
    ctx.fillRect(0,0,canvas.width,canvas.height);
    makeTileCover(ctx, mousex, mousey);
  }
  function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
  }

  canvas.addEventListener('mousemove', function(evt) {
    MousePos = getMousePos(canvas, evt);

    // 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(ctx, mousex, mousey) {
    ctx.strokeStyle = "green";
    ctx.strokeRect(mousex, mousey, 32, 32);
    ctx.stroke();
  }
  Update();