zoukankan      html  css  js  c++  java
  • canvas学习:我用canvas画了一个动画时钟!

    好几天没有进行每日一练了,除了工作原因之外,还有因为近期看到同事发的各种刚入职场的学弟学妹们的简历,被上面写的各种掌握的技能所刺激了。虽然可能不是那么尽实,但着实的push自己一把,决定先把canvas啃下来。

    我试水了画了一个时钟,和MDN的例子略有一点不同。I work it by myself!

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body onload="draw()">
    <canvas id="canvas" width="300" height="300"></canvas>
    <script>
        function init(){
            var ctx = document.getElementById('canvas').getContext('2d');
    
            ctx.save();
            ctx.clearRect(0,0,300,300);
            ctx.translate(150,150);
            ctx.lineWidth = 4;
            ctx.strokeStyle = "#a77";
            ctx.beginPath();
            ctx.arc(0,0,100,0,Math.PI*2,true);
            ctx.stroke();
            ctx.rotate(-Math.PI/2);
    
            //minute mark
            ctx.save();
            for(var i = 0;i<60;i++){
                if(i%5 != 0){
                    ctx.beginPath();
                    ctx.moveTo(90,0);
                    ctx.lineTo(94,0);
                    ctx.stroke();
                }
                ctx.rotate(Math.PI/30);
            }
            ctx.restore();
    
            //hour mark
            ctx.save();
            for(var i=1;i<=12;i++){
                ctx.beginPath();
                ctx.moveTo(85,0);
                ctx.lineTo(95,0);
                ctx.stroke();
                ctx.rotate(Math.PI/6);
            }
            ctx.restore();
            window.requestAnimationFrame(clock);
        }
    
        function clock() {
            var ctx = document.getElementById('canvas').getContext('2d');
            var now = new Date();
            var sec = now.getSeconds();
            var min = now.getMinutes();
            var hr = now.getHours();
            hr = hr>=12 ? hr-12 : hr;
    
            ctx.beginPath();
            ctx.arc(0,0,82,0,Math.PI*2,false);
            ctx.clip();
            ctx.clearRect(-90,-90,180,180);
    
            //write hour
            ctx.save();
            ctx.lineWidth = 6;
            ctx.rotate(hr*Math.PI/6 + min*Math.PI/360 + sec*Math.PI/21600);
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.lineTo(50,0);
            ctx.stroke();
            ctx.restore();
    
            //write minute
            ctx.save();
            ctx.lineWidth = 3;
            ctx.rotate(min*Math.PI/30 + sec*Math.PI/1800);
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.lineTo(65,0);
            ctx.stroke();
            ctx.restore();
    
            //write second
            ctx.save();
            ctx.lineWidth = 1;
            ctx.rotate(sec*Math.PI/30);
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.lineTo(80,0);
            ctx.stroke();
            ctx.restore();
    
            window.requestAnimationFrame(clock);
        }
    
        init();
    </script>
    </body>
    </html>
    View Code

    这里给出MDN的例子页:点我点我

    和MDN的例子不同的是,MDN每次都要重绘整个时钟,而我的做法则将时钟表盘和3个指针分离开来,只需重绘指针。

    我觉得这里有两个难点:一个是计算时分针的角度(分针走的同时,时针也会走一些角度)。一个是重绘指针的区域。

    canvasRendingContext2D.rotate(angle)

    这里Math.PI是半圆,半圆有6个小时,所以Math.PI/6是一个小时时针所走的弧度。

    因为分针转完一圈,时针就走完1/12圈,所以计算时针对于minute所走的弧度可以这么计算:Math.PI*2/60*12 =>Math.PI/360

    秒针同理。

    第二,重绘指针。

    若不重绘指针,1分钟之后,你将得到满是360度秒针的时钟。像这样:

    那么如何才能重绘指针部分的区域呢?

    我想到了裁剪。然后在裁剪的区域重绘。

    这样就OK了!(啦啦啦啦啦,手舞足蹈啦啦啦啦~~~)

  • 相关阅读:
    又玩起了“数独”
    WebService应用:音乐站图片上传
    大家都来DIY自己的Blog啦
    CSS导圆角,不过这个代码没有怎么看懂,与一般的HTML是不同
    网站PR值
    CommunityServer2.0何去何从?
    网络最经典命令行
    炎热八月,小心"落雪"
    Topology activation failed. Each partition must have at least one index component from the previous topology in the new topology, in the same host.
    SharePoint 2013服务器场设计的一些链接
  • 原文地址:https://www.cnblogs.com/gong-zhu/p/7132747.html
Copyright © 2011-2022 走看看