Javascript HTML画布延迟
因此,我创建了一个画布,当您将鼠标悬停在画布上方时,会出现一个32x32的绿色框。画布非常大,所以你可以画大量的肖像,问题是画绿色的盒子会使画布和我的整个浏览器变大 我添加的部分使其变得滞后: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(); } 我猜有一个简单的答案可以解决这个
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();