我在画布上绘制了一些对象(例如Rectangle)。它也有背景图片。
但是当我使用鼠标事件绘制矩形时,屏幕会闪烁很多。 当我改变对象的位置以便一次又一次地重新绘制画布时,如何停止鼠标移动/鼠标按下时的闪烁。 我们可以将它渲染一段时间或任何其他解决方案吗?
我听说java和C#中有一些函数为“Redraw = false”,但我的代码是用JavaScript编写的。
http://jsfiddle.net/G6tLn/7/`function myMove(e){ if(isDrag){ getMouse(E);
mySel.x = mx - offsetx;
mySel.y = my - offsety;
// something is changing position so we better invalidate the canvas!
invalidate();
} else if (isResizeDrag) {
// time ro resize!
var oldx = mySel.x;
var oldy = mySel.y;
// 0 1 2
// 3 4
// 5 6 7
switch (expectResize) {
case 0:
mySel.x = mx;
mySel.y = my;
mySel.w += oldx - mx;
mySel.h += oldy - my;
break;
case 1:
mySel.y = my;
mySel.h += oldy - my;
break;
case 2:
mySel.y = my;
mySel.w = mx - oldx;
mySel.h += oldy - my;
break;
case 3:
mySel.x = mx;
mySel.w += oldx - mx;
break;
case 4:
mySel.w = mx - oldx;
break;
case 5:
mySel.x = mx;
mySel.w += oldx - mx;
mySel.h = my - oldy;
break;
case 6:
mySel.h = my - oldy;
break;
case 7:
mySel.w = mx - oldx;
mySel.h = my - oldy;
break;
}
invalidate();
}
getMouse(e);
// if there's a selection see if we grabbed one of the selection handles
if (mySel !== null && !isResizeDrag) {
for (var i = 0; i < 8; i++) {
// 0 1 2
// 3 4
// 5 6 7
var cur = selectionHandles[i];
// we dont need to use the ghost context because
// selection handles will always be rectangles
if (mx >= cur.x && mx <= cur.x + mySelBoxSize &&
my >= cur.y && my <= cur.y + mySelBoxSize) {
// we found one!
expectResize = i;
invalidate();
switch (i) {
case 0:
this.style.cursor = 'nw-resize';
break;
case 1:
this.style.cursor = 'n-resize';
break;
case 2:
this.style.cursor = 'ne-resize';
break;
case 3:
this.style.cursor = 'w-resize';
break;
case 4:
this.style.cursor = 'e-resize';
break;
case 5:
this.style.cursor = 'sw-resize';
break;
case 6:
this.style.cursor = 's-resize';
break;
case 7:
this.style.cursor = 'se-resize';
break;
}
return;
}
}
// not over a selection box, return to normal
isResizeDrag = false;
expectResize = -1;
this.style.cursor = 'auto';
}
}
`
答案 0 :(得分:1)
500多行...这对诊断来说很重要!
快速浏览该代码后的一些想法:
创建矩形或调整其大小时,使用覆盖在结果画布顶部的单独编辑画布。这样重新绘制的唯一东西就是你正在处理的矩形 - 而不是每个以前的矩形。完成创建/调整大小后,将覆盖画布绘制到显示画布。
使用requestAnimationFrame 代替setInterval进行定时重绘。 R.A.F将其重绘与显示的刷新周期同步,以获得更好的性能。
不要使用单独的缩放器。管理单独的缩放器需要大量的计算时间。而是做o / s做什么,让用户拖动调整形状的边框。
答案 1 :(得分:1)
您可以考虑设置断点并仔细查看代码中实际发生的情况。
闪烁意味着清除画布清除和重绘不会同步发生。可能有很多原因导致这种情况发生。
一种方法是清除画布或将其调整为事件处理程序的一部分,留下空白画布直到drawloop发生并重绘所有内容。
如果某些内容与某个事件同步更新非常重要,例如鼠标移动或滚动,请将您的画布重绘为事件处理程序的一部分。
window.addEventListener("mousemove", function(event){
doSomething();
redrawOnce();
},false);
但要注意不要意外地启动多个循环。确保您的绘图功能不会调用自身。就像在这个例子中一样:
function redrawOnce(){
//That's not how to redraw once
requestAnimationFrame(redrawOnce);
}
而是将你的画面与画面分开
function loop(){
requestAnimationFrame(loop);
redrawOnce();
}
由于重绘整个画布以更新其中一小部分的更改是颓废的,因此您可能还会考虑仅重新绘制事件更改的部分(如果这是您正在执行的操作的选项)。