javascript - canvas绘制的时钟,出现多余的黑色线条是怎么回事??

查看:127
本文介绍了javascript - canvas绘制的时钟,出现多余的黑色线条是怎么回事??的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

该问题已解决:

// 是这边的 this._clockW , this._clockH 出了错误,这两个值时时钟的宽 高
// 而不是 画布的宽度,所以导致清除不完整,未清除部分 与 重绘部分不断重叠
// 导致颜色不断加深 + 出现多余的部分
this._ctx.clearRect(0 , 0 , this._clockW , this._clockH);

那些黑色的东西不知道怎么来的??

// 代码中有下面这么一句
// 清空画板
// 这里应该是已经清空了原有的内容进行重绘,但是出现了一个现象:
// 线条的颜色居然在不断加深!!不知道是不是我的代码出问题了....,可是运行却正常....汗
this._ctx.clearRect(0 , 0 , this._clockW , this._clockH);

以下是完整代码

var Clock = (function(){
  function Clock(ele){
     if (this === window) {
       return new Clock(ele);
     }

     this._con = ele;
     this._run();
  }

  Clock.prototype = {
     _initHTML: function(){
       var cavW = getEleW(this._con , 'content-box');
       var cavH = getEleH(this._con , 'content-box');
       if (cavW !== cavH) {
         throw new RangeError('容器元素的宽高不一致!');
       }
       var cav = document.createElement('canvas');

       cav.width = cavW;
       cav.height = cavH;
       this._con.appendChild(cav);
       this._clock = cav;
     } ,
     _init: function(){
        this._Xa = this._clock.width / 2;
        this._Ya = this._Xa;
        this._ratio = 0.8;
        this._maxW = this._clock.width;
        this._maxH = this._maxW;
        this._clockW = this._maxW * this._ratio;
        this._clockH = this._clockW;
        this._r  = this._clockW / 2;
        this._ctx = this._clock.getContext('2d');
        
        // 标尺长度
        this._hourLineLen = 15;
        this._minuteLineLen = 10;
        this._secondLineLen = this._minuteLineLens;
        
        // 标尺角度
        this._hourLineAngle = 30;
        this._minuteLineAngle = 6;
        this._secondLineAngle = this._minuteLineAngle;
        
        // 标尺数量
        this._hourNum = 12;
        this._minuteNum = 60;
        this._secondNum = this._minuteNum;

        // 时钟|分钟|秒钟 线长
        var ratio = 0.8;
        this._secondLen = this._r * ratio;
        this._minuteLen = this._secondLen * ratio;
        this._hourLen = this._minuteLen * ratio;
        this._draw();
     } ,
     
     _draw: function(){
        // 清空画板===> 这里应该是已经清空了原有的内容进行重绘,但是出现了一个现象:
        // 线条的颜色居然在不断加深!!不知道是不是我的代码出问题了....,可是运行却正常....汗
        this._ctx.clearRect(0 , 0 , this._clockW , this._clockH);
        
        // 绘制基本图形
        this._drawShell();
        this._drawRuler('hour');
        this._drawRuler('minute');
        
        // 绘制指示线
        //this._drawHour();
        //this._drawMinute();
        this._drawCenterOfCircle();

        var d = new Date();
        var h = d.getHours();
        var m = d.getMinutes();
        var s = d.getSeconds();
        this._drawTimeLine(h , this._hourLen);
        this._drawTimeLine(m , this._minuteLen);
        this._drawTimeLine(s , this._secondLen);
     } ,

     _drawShell: function(){
        this._ctx.beginPath();
        this._ctx.arc(this._Xa , this._Ya , this._r ,  0 , getRad(360) , false);
        this._ctx.stroke();
        this._ctx.closePath();
     } ,
         
     _drawRuler: function(type){
       var typeRange = ['hour' , 'minute' , 'second'];
       if (!(contain(type , typeRange))) {
         throw new RangeError('无法绘制的类型:' + type + ',受支持的绘制类型:' + typeRange.join(' '));
       }
       switch (type)
         {
            case 'hour':
                this._drawLine(this._hourNum , this._hourLineLen , this._hourLineAngle);
                break;
            case 'minute':
                this._drawLine(this._minuteNum , this._minuteLineLen , this._minuteLineAngle);
                break;
            case 'second':
                this._drawLine(this._secondNum , this._secondLineLen , this._secondLineAngle);
                break;
         }
       
     } ,

     _drawLine: function(num , baseLen , baseAngle , opt){
         if (opt === undefined) {
           var opt = {
             lineWidth: 1 ,
             lineCap: 'butt' , 
             lineJoin: 'miter' , 
             miterLimit: 10 ,
             strokeColor: 'black'
           }
         }
         var baseRad = getRad(baseAngle);
         var rad = 0;
         var X1 = 0;
         var Y1 = 0;
         var X2 = 0;
         var Y2 = 0;

         for (var i = 0; i < num; ++i)
          { 
             // 与圆相交的点的坐标
             var X1_1 = this._r * Math.sin(rad);
             var Y1_1 = this._r * Math.cos(rad);
             X1 = this._Xa + X1_1;
             Y1 = this._Ya - Y1_1;

             // 线段另一个点的坐标
             var X2_1 = baseLen * Math.sin(rad);
             var Y2_1 = baseLen * Math.cos(rad);
             X2 = X1 - X2_1;
             Y2 = Y1 + Y2_1;
             // console.log(getDeg(rad) , this._Xa , this._Ya , X1 , Y1 , X2 , Y2 , this._clock.width , this._clock.height);
             this._ctx.beginPath();
             this._ctx.moveTo(X1 , Y1);
             this._ctx.lineTo(X2 , Y2);
             for (var key in opt)
              {
                this._ctx[key] = opt[key];
              }
             this._ctx.stroke();
             this._ctx.closePath();
             rad += baseRad;
          }
     } ,

     _drawCenterOfCircle: function(r , fillColor){
       if (r === undefined || r > 10) {
         r = 5;
       } 
       if (fillColor === undefined) {
         fillColor = 'black';
       }
       this._ctx.beginPath();
       this._ctx.arc(this._Xa , this._Ya , r , 0 , getRad(360) , false);
       this._ctx.fill();
       this._ctx.closePath();
     } ,

     _drawTimeLine: function(num , len , opt){
        if (opt === undefined) {
          var opt = {
            lineWidth: 1 , 
            lineCap: 'butt' , 
            lineJoin: 'miter' ,
            miterLimit: 10 , 
            strokeStyle: 'black' ,
            
          };
        }

        var rad = getRad(num * this._secondLineAngle);
        var X1 = this._Xa;
        var Y1 = this._Ya;
        var X2 = X1 + len * Math.sin(rad);
        var Y2 = Y1 - len * Math.cos(rad);
        console.log(X1 , Y1 , X2 , Y2);
        this._ctx.beginPath();
        this._ctx.moveTo(X1 , Y1);
        this._ctx.lineTo(X2 , Y2);
        for (var key in opt)
          {
            this._ctx[key] = opt[key];
          }
        this._ctx.stroke();
        this._ctx.closePath();
     } ,
     
     _timeEvent: function(){
        this._draw();
        this._clock.timer = window.setTimeout(this._timeEvent.bind(this) , 1000);
     } ,
     
     _clearTimeEvent: function(){
        window.clearTimeout(this._clock.timer);
     } ,
     
     _run: function(){
        this._initHTML();
        this._init();
        this._clearTimeEvent();
        this._timeEvent();
     }
  };

  return Clock;
})();

Clock($id('clock'));

解决方案

this._ctx.clearRect(0 , 0 , this._clockW , this._clockH);
问题出在这句,你清除的大小没有达到整个canvas的大小,黑色的就是你没有擦掉的秒针,还有表盘一部分加黑也是这样,那些地方没有被擦到,检查一下canvas的此次和this._clockW是不是一致

这篇关于javascript - canvas绘制的时钟,出现多余的黑色线条是怎么回事??的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆