• canvas 钟表


    上周开始利用闲暇时间看html5 canvas技术。觉得非常好玩。就利用 canvas 做了一个简陋的钟表。源码非常简单,但是在制作的过程中,进入的误区却不少,浪费了很多时间。先上源码,然后在说说我走的岔路。

    源码是基于 require.js 去写的,可以去 官网 了解 require.js 的详细资料。

     1 define(function(){
     2     function T_clock(options){
     3         this.container = options.container || document.body;
     4         if(!document.createElement('canvas').getContext){
     5             alert('当前浏览器不支持canvas!');
     6             return;
     7         }
     8         this.init();
     9     };
    10     var cfg = {
    11         bg:'#ffaa77',
    12         bg_rbga:'rgba(255,170,119,1)',
    13         outCircleLen:99,
    14         innerCircleLen:94,
    15         minLen:65,
    16         secLen:75,
    17         hourLen:55,
    18         ctx:undefined
    19     };
    20     T_clock.prototype.init = function(){
    21         var cv = document.createElement('canvas');
    22         this.container.appendChild(cv);
    23         cv.height = 600;
    24         cv.width = 800;
    25         cv.style.backgroundColor = cfg.bg;
    26         if(cv.getContext){
    27             cfg.ctx = cv.getContext('2d');
    28         }
    29         setInterval(function(){
    30             cfg.ctx.clearRect(0,0,800,600);
    31             cfg.ctx.beginPath();
    32             cfg.ctx.lineWidth = 1;
    33             cfg.ctx.arc(100,100,cfg.outCircleLen,0,2*Math.PI,false);
    34             cfg.ctx.moveTo(100 + cfg.innerCircleLen,100);
    35             cfg.ctx.arc(100,100,94,0,2*Math.PI,false);
    36 
    37             cfg.ctx.font = 'bold 14px 宋体';
    38             cfg.ctx.textAlign = 'center';
    39             cfg.ctx.textBaseline = 'middle';
    40             var numR = 76,x,y,arc;
    41             for(var i=1,arc=-Math.PI/3;i<13;i++,arc+= Math.PI/6){
    42                 x = 100 + numR * Math.cos(arc);
    43                 y = 100 + numR * Math.sin(arc);
    44                 cfg.ctx.fillText(i,x,y);
    45             }
    46             for(i=0,arc=-Math.PI/2; i<60; i++,arc+=Math.PI/30){
    47                 x = 100 + 94 * Math.cos(arc);
    48                 y = 100 + 94 * Math.sin(arc);
    49                 cfg.ctx.moveTo(x,y);
    50                 if(i % 5 == 0){
    51                     x = 100 + (94 - 10) * Math.cos(arc);
    52                     y = 100 + (94 - 10) * Math.sin(arc);
    53                 }
    54                 else{
    55                     x = 100 + (94 - 5) * Math.cos(arc);
    56                     y = 100 + (94 - 5) * Math.sin(arc);
    57                 }
    58                 cfg.ctx.lineTo(x,y);
    59             }
    60             cfg.ctx.closePath();
    61             cfg.ctx.stroke();
    62 
    63             var d = new Date();
    64             var sec = d.getSeconds();
    65             var min = d.getMinutes();
    66             var hour = d.getHours();
    67             var sec_angle = - Math.PI * sec / 30 + Math.PI;
    68 
    69             cfg.ctx.beginPath();
    70             cfg.ctx.strokeStyle = '#F00';
    71             cfg.ctx.lineWidth = 1;
    72             cfg.ctx.moveTo(100,100);
    73             cfg.ctx.lineTo(100 + cfg.secLen * Math.sin(sec_angle),100 + cfg.secLen * Math.cos(sec_angle));
    74             cfg.ctx.closePath();
    75             cfg.ctx.stroke();
    76 
    77             cfg.ctx.beginPath();
    78             cfg.ctx.strokeStyle = '#555';
    79             cfg.ctx.lineWidth = 2;
    80             cfg.ctx.moveTo(100,100);
    81             var min_angle = - Math.PI * min / 30 + Math.PI - Math.PI * sec / 1800;
    82             cfg.ctx.lineTo(100 + cfg.minLen * Math.sin(min_angle),100 + cfg.minLen * Math.cos(min_angle));
    83             cfg.ctx.closePath();
    84             cfg.ctx.stroke();
    85 
    86             cfg.ctx.beginPath();
    87             cfg.ctx.strokeStyle = '#000';
    88             cfg.ctx.lineWidth = 2;
    89             cfg.ctx.moveTo(100,100);
    90             var hour_angle = - Math.PI * hour / 6 + Math.PI - Math.PI * min / 360;
    91             cfg.ctx.lineTo(100 + cfg.hourLen * Math.sin(hour_angle),100 + cfg.hourLen * Math.cos(hour_angle));
    92             cfg.ctx.closePath();
    93             cfg.ctx.stroke();
    94         },1000);
    95 };
    96 
    97 return T_clock;
    98 })
    钟表模块
    1     require(['../../js/require/config.js'],function(cfg){
    2         require(['h5/L_canvas'],function(Canvas){
    3             new Canvas({});
    4         });
    5     })
    引用钟表模块

    上效果图;

    误区一:错误的理解 canvas 中的每一个图(画的每一个元素)都是一个单独的对象,可以自己销毁(擦除)自己。其实不是这样的,canvas 的 context 对象只提供了一个 clearRect 方法去清空指定区域的内容。

    误区二:在一个钟表里,只有指针是动的,钟表的圆盘及数字是不动的。于是我就想在做指针动画的时候,不清除钟表的圆盘和数字,只是清除指针重画指针来实现这样的效果。期间我试了很多办法都不行。最典型的就是用了 canvas 的这个属性 globalCompositeOperation, 通过用背景色重画动画的上一个动作,用于擦除上一个动画,效果非常的莫名其妙,推测应该是 Math 对象的一些运算结果都不是精确值导致的。最后我只能在每次心跳时,清空画布重画钟表的圆盘和数字来实现动画效果;

    误区三:每画一个元素,如果样式和下一个原色的样式不一样,都要单独设置元素的样式,并且要嵌在context.beginPah,context.closePath()内部,每调用closePath方法,都要调用Stroke或者fill方法把元素画出来。否则画布不会显示的。参看上传的第一块代码。

  • 相关阅读:
    四则运算单元测试
    四则运算2
    课堂记录
    软件工程第一课,设计简单小学四则运算
    阅读计计计计计计划
    团队开发——冲刺1.a
    博客园之用户体验
    软件项目风险评估计划
    《人月神话》读书笔记 第2篇
    课堂作业——找1
  • 原文地址:https://www.cnblogs.com/zeq-jone/p/3985632.html
Copyright © 2020-2023  润新知