最近在學習canvas,http://corehtml5canvas.com/code-live/,主要的學習方式就是通過上面的一些例子來學習canvas的一些用法。但是我發現,這里的例子,只要canvas的內容有一點點變化(甚至是某個元素位置的變動),都會去清空整個canvas然后整個canvas重繪。例如下面時鍾的例子
http://corehtml5canvas.com/code-live/ch01/example-1.11/example.html。
但是,對於這個時鍾的功能來說,每一秒變化,改變的只是指針,刻度數字和圓圈都不需要改變,就因為指針的變化而去重繪整個canvas是不是耗費了性能呢。如果把指針變化這部分提出來成為一層,然后刻度不變的那一部分作為一層,2層疊加,上面一層背景透明,這樣,能達到同樣的效果,又能減少重繪的部分,相應的性能也能提高。抱着這種想法我試驗了一下。代碼如下:
<html> <head> <title>Clock</title> <style> body { background: #dddddd; } #canvas1 { position: absolute; left: 0px; top: 0px; margin: 20px; background: #ffffff; border: thin solid #aaaaaa; } #canvas2 { position: absolute; left: 0px; top: 0px; margin: 20px; border: thin solid #aaaaaa; } </style> </head> <body> <canvas id="canvas1" width="400" height="400"> Canvas not supported </canvas> <canvas id="canvas2" width="400" height="400"> Canvas not supported </canvas> <script src="MyTestClock.js"></script> </body>
</html>
MyTestClock.js部分代碼:
/** * Created by jackyWHJ on 14-2-26. */ var canvas1 = document.getElementById('canvas1'), context1 = canvas1.getContext('2d'), canvas2 = document.getElementById('canvas2'), context2 = canvas2.getContext('2d'), FONT_HEIGHT = 15, MARGIN = 35, HAND_TRUNCATION = canvas1.width/25, HOUR_HAND_TRUNCATION = canvas1.width/10, NUMERAL_SPACING = 20, RADIUS = canvas1.width/2 - MARGIN, HAND_RADIUS = RADIUS + NUMERAL_SPACING; // Functions..................................................... function drawCircle() { context1.beginPath(); context1.arc(canvas1.width/2, canvas1.height/2, RADIUS, 0, Math.PI*2, true); context1.stroke(); } function drawNumerals() { var numerals = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ], angle = 0, numeralWidth = 0; numerals.forEach(function(numeral) { angle = Math.PI/6 * (numeral-3); numeralWidth = context1.measureText(numeral).width; context1.fillText(numeral, canvas1.width/2 + Math.cos(angle)*(HAND_RADIUS) - numeralWidth/2, canvas1.height/2 + Math.sin(angle)*(HAND_RADIUS) + FONT_HEIGHT/3); }); } function drawCenter() { context1.beginPath(); context1.arc(canvas1.width/2, canvas1.height/2, 5, 0, Math.PI*2, true); context1.fill(); } function drawHand(loc, isHour,color) { var angle = (Math.PI*2) * (loc/60) - Math.PI/2, handRadius = isHour ? RADIUS - HAND_TRUNCATION-HOUR_HAND_TRUNCATION : RADIUS - HAND_TRUNCATION; context2.beginPath(); context2.strokeStyle = color; context2.moveTo(canvas2.width/2, canvas2.height/2); context2.lineTo(canvas2.width/2 + Math.cos(angle)*handRadius, canvas2.height/2 + Math.sin(angle)*handRadius); context2.stroke(); } function drawHands() { context2.clearRect(0,0,canvas2.width,canvas2.height); var date = new Date, hour = date.getHours(); hour = hour > 12 ? hour - 12 : hour; drawHand(hour*5 + (date.getMinutes()/60)*5, true, "#FF0000"); drawHand(date.getMinutes(), false, "#00FF00"); drawHand(date.getSeconds(), false, "#0000FF"); } function drawClock() { drawCircle(); drawCenter(); drawNumerals(); } // Initialization................................................ context1.font = FONT_HEIGHT + 'px Arial'; drawHands(); drawClock(); loop = setInterval(drawHands, 1000);
瀏覽器看了下,原來重繪需要2ms,現在是1ms。。。