canvas实现挂钟

canvas实现挂钟,实现该效果不难,只是实现过程帮助我们更好的掌握几个知识点。
照例先奉上效果图:
效果图

<div id="block">
<canvas id="bgcan" width="250" height="250"></canvas>
<canvas id="clockcan" width="200" height="200"></canvas>
</div>

div设置整个背景图。
这里采用两个canvas,均是绝对定位。id分别为bgcan , clockcan:
这里在bgcan上绘制挂钟的钟框。也就是外部的圆环。
在clockcan上绘制各时间点及时针、分针、秒针。
首先取得和定义需要的元素和变量:

var bgcan = document.getElementById("bgcan"),
        clockcan = document.getElementById("clockcan"),
        bgcontext = bgcan.getContext("2d"),
        clockcontext = clockcan.getContext("2d"),
        bgX = bgcan.width/2,
        bgY = bgcan.height/2,
        clockX = clockcan.width/2,
        clockY = clockcan.height/2,
        radius = clockcan.width/2-20;

绘制外部的钟框:

var radgrad = bgcontext.createRadialGradient(bgX,bgY,bgcan.width/2-50,bgX,bgY,bgcan.width/2);
    radgrad.addColorStop(0,"#BEBAB7");
    radgrad.addColorStop(1/5,"#ffffff");
    radgrad.addColorStop(2/5,"#BFBBBA");
    radgrad.addColorStop(3/5,"#EEEEEC");
    radgrad.addColorStop(4/5,"#EBEBEB");
    radgrad.addColorStop(1,"#EEEEEC");
    bgcontext.fillStyle = radgrad;
    bgcontext.fillRect(0,0,bgcan.width,bgcan.height);

这里涉及第一个知识点:绘制径向渐变
首先使用createRadialGradient方法创建canvasGradient对象,然后使用addColorStop方法上色。
其中createRadialGradient(x1 , y1 , r1 , x2 , y2 , r2)参数含义:
定义一个以x1,y1为原点,半径为r1的圆,再定义一个以x2,y2为原点,r2为半径的圆。
接下来绘制另一个画布上的内容:
首先初始化样式:


    clockcontext.font = "normal 24px Arial";//设置字体样式
    clockcontext.translate(clockX,clockY);//设置坐标原点在该画布中心

绘制每一个时间点(60个秒点):

for (var i = 0,angle=0; i < 60; i++) {
            clockcontext.save();
            clockcontext.beginPath();
            clockcontext.moveTo((radius+18)*Math.cos(angle),(radius+18)*Math.sin(angle));
            if (i%5==0) {
                clockcontext.lineWidth = 3;
            }
            clockcontext.lineTo((radius+13)*Math.cos(angle),(radius+13)*Math.sin(angle));
            clockcontext.stroke();
            clockcontext.restore();
            angle += Math.PI/30;
        }

这里根据角度来取得每个点对应坐标,遇到分点时(i%5),点的宽度增粗。
绘制每个时刻:

for (var i = 1; i < 13; i++) {
            timeText(i,radius*Math.sin(Math.PI*i/6),-radius*Math.cos(Math.PI*i/6));//调用timeText(时刻,对应横坐标,对应纵坐标)函数绘制
        }
function timeText(num,x,y){
        clockcontext.save();
        x -= (clockcontext.measureText(num).width/2);
        y += 8;
        clockcontext.beginPath();
        clockcontext.translate(x,y);
        clockcontext.fillText(num,0,0);
        clockcontext.restore();
    }

第二个知识点:measureText方法获得指定字符串,返回一个TextMetrics对象,该对象的width属性表示使用当前指定的字体后该字符串总文字的宽度。
第三个知识点:绘制文字有两个方法:
fillText(text , x, y ,[maxWidth]);填充绘制文字,四个参数依次表示表示所绘文字,文字起点对应横坐标,文字起点对应纵坐标,文字最大宽度(可选)。
strokeText(text , x, y ,[maxWidth]);轮廓绘制文字。参数意义相同。

取得当前时间:

var time = new Date(),
    timeH = time.getHours(),
    timeM = time.getMinutes(),
    timeS = time.getSeconds();
if (timeH > 12) {
    timeH -= 12;
}

更新绘制时针、分针、秒针:

//  h、m、s分别为所取得当前时、分、秒数值。
function update(h,m,s){
        //绘制中心的小圆,使得更形象
        clockcontext.save();
        clockcontext.beginPath();
        clockcontext.moveTo(0,0);
        clockcontext.fillStyle = "#222";
        clockcontext.arc(0,0,8,0,Math.PI*2,false);
        clockcontext.fill();
        clockcontext.restore();
        //绘制时针
        clockcontext.save();
        clockcontext.beginPath();
        clockcontext.moveTo(0,0);
        clockcontext.lineWidth = 10;
        clockcontext.lineCap = "round";//设置端点样式
        clockcontext.lineTo((radius-35)*Math.cos(Math.PI*(h-3)/6),(radius-35)*Math.sin(Math.PI*(h-3)/6));
        clockcontext.stroke();
        clockcontext.restore();
        //绘制分针
        clockcontext.save();
        clockcontext.beginPath();
        clockcontext.moveTo(0,0);
        clockcontext.lineWidth = 5;
        clockcontext.lineTo((radius-5)*Math.cos(Math.PI*(m-15)/30),(radius-5)*Math.sin(Math.PI*(m-15)/30));
        clockcontext.stroke();
        clockcontext.restore();
        //绘制秒针
        clockcontext.save();
        clockcontext.beginPath();
        clockcontext.fillStyle = "#222";
        clockcontext.rotate(Math.PI*(s-15)/30);
        clockcontext.moveTo(-40,-2);
        clockcontext.lineTo(-40,2);
        clockcontext.lineTo(-1,2);
        clockcontext.lineTo(0,1);
        clockcontext.lineTo(radius+15,1);
        clockcontext.lineTo(radius+15,-1);
        clockcontext.lineTo(0,-1);
        clockcontext.lineTo(0,-2);
        clockcontext.lineTo(-40,-2);
        clockcontext.fill();
        clockcontext.restore();
    }

注意这里绘制秒针的方式有点不同,看效果图秒针的底部还多出来一节,想要实现这种效果,可以先把坐标空间旋转,使横坐标轴由圆心指向当前秒数所在坐标,随之依次绘制各坐标点,即可实现效果。
编写一个时间更新函数:

function updateTime(){
        var time = new Date(),
            timeH = time.getHours(),
            timeM = time.getMinutes(),
            timeS = time.getSeconds();
        alert(timeH);
        if (timeH > 12) {
            timeH -= 12;
        }
        //每次更新都需要先清理当前画布
        clockcontext.clearRect(-clockcan.width/2,-clockcan.height/2,clockcan.width,clockcan.height);
        drawTime();//绘制各时间点函数(将以上绘制时间点代码和各时刻代码封装成一个函数)
        update(timeH,timeM,timeS);
    }

最后调用setInterval方法每隔一秒执行一次时间更新函数:

setInterval("updateTime()",1000);

完整代码下载地址:canvas实现挂钟

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值