不要在事件处理程序中绘制动画(一个简单的草图应用程序)
在 mousemove
期间,每秒钟会有 30 个鼠标事件被淹没。你可能无法以每秒 30 次的速度重绘图形。即使你可以,你也可能在浏览器未准备好绘制时浪费计算能力(浪费= =跨越显示刷新周期)。
因此,将用户输入事件(如 mousemove)与动画绘图分开是有意义的。
-
在事件处理程序中,保存控制图形在画布上的位置的所有事件变量。但实际上并没有画任何东西。
-
在
requestAnimationFrame
循环中,使用保存的信息将所有绘图渲染到画布。
通过不绘制事件处理程序,你不会强制 Canvas 尝试以鼠标事件速度刷新复杂的绘图。
通过在 requestAnimationFrame
中完成所有绘制,你将获得此处描述的所有好处使用’requestanimationFrame’而不是’setInterval’来表示动画循环 。
带注释的代码:
<!doctype html>
<html>
<head>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red; }
</style>
<script>
window.onload=(function(){
function log(){console.log.apply(console,arguments);}
// canvas variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// set canvas styling
ctx.strokeStyle='skyblue';
ctx.lineJoint='round';
ctx.lineCap='round';
ctx.lineWidth=6;
// handle windows scrolling & resizing
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
// vars to save points created during mousemove handling
var points=[];
var lastLength=0;
// start the animation loop
requestAnimationFrame(draw);
canvas.onmousemove=function(e){handleMouseMove(e);}
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// get the mouse position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// save the mouse position in the points[] array
// but don't draw anything
points.push({x:mouseX,y:mouseY});
}
function draw(){
// No additional points? Request another frame an return
var length=points.length;
if(length==lastLength){requestAnimationFrame(draw);return;}
// draw the additional points
var point=points[lastLength];
ctx.beginPath();
ctx.moveTo(point.x,point.y)
for(var i=lastLength;i<length;i++){
point=points[i];
ctx.lineTo(point.x,point.y);
}
ctx.stroke();
// request another animation loop
requestAnimationFrame(draw);
}
}); // end window.onload
</script>
</head>
<body>
<h4>Move mouse over Canvas to sketch</h4>
<canvas id="canvas" width=512 height=512></canvas>
</body>
</html>