怎么用canvas画秒针_使用canvas绘制一个时钟

本文介绍了如何使用HTML5 Canvas绘制一个动态时钟,包括利用beginPath()和closePath()管理路径,save()和restore()保存和恢复状态以避免样式影响,以及运用arc()等方法绘制指针并实现旋转动画。示例代码详细展示了时、分、秒针的绘制过程,以及如何通过定时器更新时间。
摘要由CSDN通过智能技术生成

周末学习canvas的一些基础功能,顺带写了一个基础的时钟。现在加工一下,做的更好看一点,先放上效果图:

谈一些自己的理解:

(1)、要绘制一个新的样式(不想被其他样式影响,或者影响到其他样式),那么一定记得先用beginPath(),beginPath()可以新建一个子路径,接下来的绘制,都是针对该子路径进行的。如果不适用该方法,那么默认和之前路径为同一路径设置,在接下来的绘制中,前面设置的路径会被重复绘制(打个比方,如果不用beginPath(),上面我绘制了一个长方形,边框宽度为1,下面我又绘制了一个长方形,边框宽度为5,那么上面的长方形会被重新绘制,且边框宽度也变为5)。相对的还有一个closePath()方法,如果前面设置的路径是开放的,该方法会自动用直线连接终点和起点。

(2)、因为时、分、秒针都是通过循环并且旋转来做出移动效果,所以需要在每次旋转前,通过save()方法保存下当前状态,并在旋转后restore()恢复到之前状态,否则每次旋转都会在上一次旋转的基础上进行。

(3)、仔细看的话可以发现秒针的尾端是一个弧线,canvas里有很多曲线的绘制方法,且大多与切线(切点)有关,具体可以搜索下,网上有很多详解文章了。

(4)、lineTo()、arc()、arcTo()这些都仅仅是绘制路径,最后要通过fill()或者stroke()来完成绘制。

下面给出完整代码,补上了注释:

不支持canvas

var myClock = document.getElementById('my_clock');

var ctx = myClock.getContext('2d');

var clockImg = new Image();

clockImg.src = 'clock.png';

ctx.translate(600, 400);

var startTime = new Date().getTime(),

count = 0;

function clock() {

ctx.clearRect(-600, -400, 1200, 900);

// 裁剪钟面图,只留下圆的钟面

ctx.beginPath();

ctx.arc(0, 0, 250, 0, 2 * Math.PI);

ctx.clip();

// 钟面图有点歪,需要差不多顺时针旋转1/3度

ctx.save()

ctx.rotate(1 / 3 * 2 * Math.PI / 60);

ctx.drawImage(clockImg, - 250, -250, 500, 500);

ctx.restore();

// 这里注释的部分的是绘制的一个简单的钟面,如果不用图片可以打开下面的注释

// ctx.beginPath();

// ctx.arc(0, 0, 200, 0, 2 * Math.PI, false);

// ctx.moveTo(195, 0);

// ctx.arc(0, 0, 195, 0, 2 * Math.PI, false);

// ctx.stroke();

// ctx.closePath();

// ctx.font = '16px Arial';

// ctx.textAlign = 'center';

// ctx.textBaseline = 'middle';

// ctx.fillText('12', 0, -180);

// ctx.fillText('3', 180, 0);

// ctx.fillText('6', 0, 180);

// ctx.fillText('9', -180, 0);

var nowTime = new Date(),

sec = nowTime.getSeconds(),

min = nowTime.getMinutes() + sec / 60,

hour12 = nowTime.getHours() >= 12 ? nowTime.getHours() - 12 : nowTime.getHours(),

hour = hour12 + min / 60;

// 实时时间转换成角度,一圈是360度,也就是2PI,一圈有60小格,一小格就是(2 * Math.PI / 60)

var angle = 2 * Math.PI / 60,

secHandAngle = sec * angle,

minHandAngle = min * angle,

hourHandAngle = hour * 5 * angle;

// 秒针

ctx.save();

ctx.beginPath();

ctx.rotate(secHandAngle)

ctx.moveTo(-2, 10);

ctx.lineTo(0, -240);

ctx.lineTo(2, 10);

ctx.moveTo(-2, 10);

ctx.arcTo(0, -240, 2, 10, 2);

ctx.stroke();

ctx.restore();

// 分针

ctx.save();

ctx.beginPath();

ctx.rotate(minHandAngle)

ctx.moveTo(0, 0);

ctx.lineTo(0, -170);

ctx.lineWidth = 2;

ctx.stroke();

ctx.restore();

// 时针

ctx.save();

ctx.beginPath();

ctx.rotate(hourHandAngle)

ctx.moveTo(-5, 0);

ctx.lineTo(0, -120);

ctx.lineTo(5, 0);

ctx.strokeStyle = '#fff'

ctx.fillStyle = 'rgba(0, 0, 0, .3)';

ctx.lineWidth = 1;

ctx.stroke();

ctx.fill();

ctx.restore();

// 减少setTimeout误差

count++;

var diff = new Date().getTime() - (startTime + count * 1000);

var nextStart = (1000 - diff) < 0 ? 0 : 1000 - diff;

setTimeout(clock, nextStart);

}

// 占用线程

// setInterval(function(){

// var j = 0;

// while (j++ < 100000000);

// }, 0);

// setInterval(function(){

// var j = 0;

// while (j++ < 100000000);

// }, 0);

// setInterval(function(){

// var j = 0;

// while (j++ < 100000000);

// }, 0);

setTimeout(clock, 1000);

// setInterval(clock, 1000)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值