首页 > canvas制作的时钟不同地方设置setInterval,不清楚为什么会效果不同。

canvas制作的时钟不同地方设置setInterval,不清楚为什么会效果不同。

现象:

用canvas制作时钟,用不同的方式来调用setInterval,效果不同。(详细代码在后面)

用法一:

setInterval(drawClock,1000);  
//下一秒的时候,之前的时分秒针会消失,出现新的时分秒针(我想要的效果)

function drawClock(){
    drawFace();
    drawNumbers();
    drawTime(); 
   //下一秒的时候,之前的时分秒针会消失,出现新的时分秒针(我想要的效果)
}

用法二:

drawClock();  
//上一秒的时分秒针没有消失(不想要的效果)

function drawClock(){
    drawFace();
    drawNumbers();
    setInterval(drawTime,1000);    
    //上一秒的时分秒针没有消失(不想要的效果
}

问题:

为什么用方法一可以清除掉上一秒的时分秒针?而方法二不可以?

Code Here:

<!DOCTYPE html>
<html>
<head>
<style>
*{margin:0px;padding:0px;}
</style>
</head>
<body>
    <canvas id='myCanvas' width='300' height='300' style='background-color:#333'></canvas>
<script>

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var radius=canvas.width/2;
ctx.translate(radius,radius);  //change to new (0,0) to old (50,50)
radius=radius*0.9;
//setInterval(drawClock,1000);
drawClock();

function drawClock(){
    drawFace();
    drawNumbers();
    drawTime();
    setInterval(drawTime,1000);
}

function drawFace(){
    var gdt;
    //draw the background
    ctx.beginPath();
    ctx.fillStyle = "white";
    ctx.arc(0,0,130,0,2*Math.PI);
    ctx.fill();

    //draw the center point
    ctx.beginPath();
    ctx.fillStyle='rgba(255,0,0,.3)';
    ctx.arc(0,0,radius*0.1,0,2*Math.PI);
    ctx.fill();

    //draw the outline
    ctx.beginPath();
    gdt=ctx.createRadialGradient(0,0,radius*0.95,0,0,radius*1.05);
    gdt.addColorStop(0,'#333');
    gdt.addColorStop(0.5,'white');
    gdt.addColorStop(1,'#333');
    ctx.lineWidth=radius*0.1;
    ctx.strokeStyle=gdt;
    ctx.arc(0,0,radius,0,2*Math.PI);
    ctx.stroke();
}

function drawNumbers(){
    ctx.font = radius*0.15 + "px arial";
    ctx.textBaseline="middle";
    ctx.textAlign="center";
    ctx.fillStyle='rgba(255,0,0,.3)';

    //effect A
    // for(var i=1;i<13;i++){
    //     ctx.rotate(Math.PI/6*i);
    //     ctx.translate(0,-0.85*radius);
       //  ctx.fillText(i.toString(),0,0);
       //  ctx.translate(0,0.85*radius);
       //  ctx.rotate(-Math.PI/6*i);
    // }

    //effect B
    for(var i=1;i<13;i++){
        ctx.beginPath();
        ctx.rotate(Math.PI/6*i);   //center , rotate to 
        ctx.translate(0,-0.85*radius);  //translate
        ctx.rotate(-Math.PI/6*i);    //rotate to straight
        ctx.fillText(i.toString(),0,0);  //fill text
        ctx.rotate(Math.PI/6*i);    //In contrast
        ctx.translate(0,0.85*radius);
        ctx.rotate(-Math.PI/6*i);
    }
}

function drawHands(pos,length,width){
    ctx.beginPath();
    ctx.strokeStyle='rgba(0,255,0,.3)';
    ctx.lineWidth=width;
    ctx.lineCap='round';
    ctx.moveTo(0,0);
    ctx.rotate(pos);
    ctx.lineTo(0,-length);
    ctx.stroke();
    ctx.rotate(-pos);
    ctx.save();
}

function drawTime(){
    var now=new Date();
    var hour=now.getHours();
    var minute=now.getMinutes();
    var second=now.getSeconds();
    //hour
    hour=hour%12;
    hour=(hour*Math.PI/6)+(minute*Math.PI/(6*60))+(second*Math.PI/(360*60));
    drawHands(hour, radius*0.5, radius*0.07);
    //minute
    minute=(minute*Math.PI/30)+(second*Math.PI/(30*60));
    drawHands(minute, radius*0.8, radius*0.07);
    //second
    second=second*Math.PI/30;
    drawHands(second, radius*0.9, radius*0.02);
}

</script>
</body>
</html>

问了其他网友:因为用方法一,会覆盖原来的;方法二没有覆盖。所以看上去是正确的。这个启发了我对canvas覆盖/clear的性能关注。


你的方法1, 是在每隔一秒调用一次 drawFace, drawNumbers, drawTime 这三个函数.
你这三个函数的功能分别是 画表盘, 画数字 和 画时分秒的指针.

而在画表盘的时候, 会清除原来画出来的数字和指针(或者说是覆盖掉了).

所以你的第一种方法, 每次都按这个流程走, 所以你会看到它原来的那个秒针被清掉了.

而你的第2种方法, 而是 先画表盘, 再画数字, 然后每隔一秒去画一次针对.
而你在画指针的时候,并没有清除原来的 时/分/秒 的内容, 所以你会看到它每画一次, 它原来的内容还在那里,
而且你会发现 分/时针的颜色会越来越重.

【热门文章】
【热门文章】