不要在事件處理程式中繪製動畫(一個簡單的草圖應用程式)
在 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>