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了!(啦啦啦啦啦,手舞足蹈啦啦啦啦~~~)

  • 相关阅读:
    9.Java通过axis调用WebService
    8.AXIS1基础
    7.Web Service 调用天气代码
    Exception in thread "main" java.lang.NoClassDefFoundError: org.jaxen.NamespaceContext
    webservices 服务器未能识别 HTTP 头 SOAPAction 的值:.
    几种流行Webservice框架性能对比
    6. 使用Axis开发WebService程序
    5. webservice通信调用天气预报接口实例
    4.菜鸟教你一步一步开发 web service 之 axis 客户端创建
    3.菜鸟教你一步一步开发 web service 之 axis 服务端创建
  • 原文地址:https://www.cnblogs.com/gong-zhu/p/7132747.html
Copyright © 2011-2022 走看看