2個canvas疊加運用(時鍾例子)


最近在學習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。。。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM