首先,canvas语法基础薄弱的小伙伴请点这里,剩下的小伙伴们可以接着往下看了。

一个表,需要画什么出来呢:3条线(时分秒针),1个圆(表盘),以及60条短线/点(刻度)。

嗯,没毛病。

那接下来让我们考虑点细节:一个圆,自然是360°,分成60个刻度,两个刻度之间相隔6°,然后分针和秒针刻度偏移是相同的,时针的刻度偏移应该是它们的5倍(只有12个小时刻度)=30°,然而你见过时分秒针一样长的表么?(我反正没有)所以我们还需要控制它们的长度是不一样的才对。

咳,有了上面的思考作为基础了,开搞。

先定个点画个圆:

            var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(X坐标, Y坐标, 半径, 0, 2 * Math.PI, false);
ctx.strokeStyle = 随便填颜色;
ctx.stroke();
ctx.closePath();

接下来我们要打上时间刻度,可是问题来了:你是可以画出来一个圆,也知道每个刻度6°角,可如何在画出来的圆上找到对应的坐标呢?

don't worry(数学知识过关的小伙伴们表示毫无压力)~我们只需要去算出正余弦就拿到了对应的XY坐标啦(是的,脚本内正余弦算法不是算角度),具体做法如下:

        //计算圆上每个点的坐标
///[a]角度[i]刻度[ox]圆心X坐标[oy]圆心Y坐标[or]圆半径
function angle(a, i, ox, oy, or) {
var hudu = (2 * Math.PI / 360) * a * i;//求出弧度
var x = ox + Math.sin(hudu) * or;//计算出x轴坐标for正弦
var y = oy - Math.cos(hudu) * or;//计算出y轴坐标for余弦
return x + '_' + y;
}

到了这里,我们就可以愉快的画刻度了:

            //打上文字(仅小时)
for (var i = 0; i < 12; i++) {
var textXY = angle(30, i + 1, ox, oy, or - 10);//小时刻度坐标
ctx.fillText(i + 1, textXY.split('_')[0], textXY.split('_')[1]);
ctx.textAlign = 'center';//水平居中
ctx.textBaseline = 'middle';//垂直居中
} //打上分秒钟刻度
for (var i = 0; i < 60; i++) {
var oXY = angle(6, i + 1, ox, oy, or);//分、秒刻度坐标
ctx.beginPath();
ctx.arc(oXY.split('_')[0], oXY.split('_')[1], (i + 1) % 5 == 0 ? 2 : 1, 0, 2 * Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();
ctx.closePath();
}         

为了逼真,我还加入了秒针影响分针,分针影响秒针的计算。(见最后代码)

然后就是考虑三根针不一样长的问题,这个问题试过很多遍,最后我发现最简单的解决办法就是多画3个圆,因为偏移的角度计算方式是一样的。

最后的结果是这样的:

因为不支持上传html文件,所以我就把所有代码贴在这里了:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>小马的canvas练手作品-时钟</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="myCanvas" width="1000" height="1000">您的浏览器不支持此标签</canvas>
<script type="text/javascript"> setInterval('drawClock(150, 150, 100, 50, 70, 90,"pink","black","red","green")', 1000); //画钟表
//[ox]圆心X坐标[oy]圆心Y坐标[or]钟表半径[hr]时针半径[mr]分针半径[sr]秒针半径[oc]钟表外环颜色[hc]时针颜色[mc]分针颜色[sc]秒针颜色
function drawClock(ox, oy, or, hr, mr, sr, oc, hc, mc, sc) { //时钟底盘
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(ox - or, oy - or, or * 2, or * 2);//清空上一次绘制
ctx.beginPath();
ctx.arc(ox, oy, or, 0, 2 * Math.PI, false);
ctx.strokeStyle = oc;
ctx.stroke();
ctx.closePath(); //获取当前时间
var NowTime = new Date();
var h = NowTime.getHours();
var m = NowTime.getMinutes();
var s = NowTime.getSeconds();
var y = NowTime.getFullYear();
var mo = NowTime.getMonth() + 1;
var d = NowTime.getDate();
ctx.fillText(mo + '月' + d + '日', ox, oy - or / 2, 50);//显示月日 //打上时间刻度
for (var i = 0; i < 12; i++) {
var textXY = angle(30, i + 1, ox, oy, or - 10);//小时刻度坐标
ctx.fillText(i + 1, textXY.split('_')[0], textXY.split('_')[1]);
ctx.textAlign = 'center';//水平居中
ctx.textBaseline = 'middle';//垂直居中
} //打上分钟刻度
for (var i = 0; i < 60; i++) {
var oXY = angle(6, i + 1, ox, oy, or);//分、秒刻度坐标
ctx.beginPath();
ctx.arc(oXY.split('_')[0], oXY.split('_')[1], (i + 1) % 5 == 0 ? 2 : 1, 0, 2 * Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();
ctx.closePath();
} h = h + m / 60;//分钟影响时针偏移 var hoursXY = angle(30, h > 12 ? h - 12 : h, ox, oy, hr);//时针终点XY坐标
drawLine(ctx, hc, ox, oy, hoursXY.split('_')[0], hoursXY.split('_')[1]); m = m + s / 60;//秒钟影响分针偏移 var minuteXY = angle(6, m, ox, oy, mr);//分针终点XY坐标
drawLine(ctx, mc, ox, oy, minuteXY.split('_')[0], minuteXY.split('_')[1]); var secondXY = angle(6, s, ox, oy, sr);//秒针终点XY坐标
drawLine(ctx, sc, ox, oy, secondXY.split('_')[0], secondXY.split('_')[1]); } //计算圆上每个点的坐标
///[a]角度[i]刻度[ox]圆心X坐标[oy]圆心Y坐标[or]圆半径
function angle(a, i, ox, oy, or) {
var hudu = (2 * Math.PI / 360) * a * i;//求出弧度
var x = ox + Math.sin(hudu) * or;//计算出x轴坐标for正弦
var y = oy - Math.cos(hudu) * or;//计算出y轴坐标for余弦
return x + '_' + y;
} //画线方法
///[ob]绘画对象[ox]圆心X坐标[oy]圆心Y坐标[px]目标X坐标[py]目标Y坐标
function drawLine(ob, color, ox, oy, px, py) {
ob.beginPath();
ob.strokeStyle = color;
ob.moveTo(ox, oy);
ob.lineTo(px, py);
ob.stroke();
ob.closePath();
}
</script>
</body>
</html>

希望对大家有帮助~~

Canvas基础——钟表绘制的更多相关文章

  1. 基础canvas应用-钟表绘制

    首先,canvas语法基础薄弱的小伙伴请点这里,剩下的小伙伴们可以接着往下看了. 一个表,需要画什么出来呢:3条线(时分秒针),1个圆(表盘),以及60条短线/点(刻度). 嗯,没毛病. 那接下来让我 ...

  2. canvas基础绘制-绚丽时钟

    效果图: 与canvas基础绘制-绚丽倒计时的代码差异: // var endTime = new Date();//const声明变量,不可修改,必须声明时赋值: // endTime.setTim ...

  3. canvas基础绘制-绚丽倒计时

    效果图: html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  4. HTML5移动开发学习笔记之Canvas基础

    1.第一个Canvas程序 看的是HTML5移动开发即学即用这本书,首先学习Canvas基础,废话不多说,直接看第一个例子. 效果图为: 代码如下: <!DOCTYPE html> < ...

  5. canvas基础之旅

    canvas 主要使用2D rendering context  API 实现其功能和特效. canvas 一般浏览器都支持,但在ie9之前的是不支持的.(解决办法:添加IxplorerCanvas ...

  6. canvas 基础知识整理(二)

    html部分: <canvas id="myCanvas" width="800" height="800" ></can ...

  7. canvas 基础知识整理(一)

    canvas这个 HTML 元素是为了客户端矢量图形而设计的.它自己没有行为,但却把一个绘图 API 展现给客户端 JavaScript 以使脚本能够把想绘制的东西都绘制到一块画布上. html的基本 ...

  8. 《HTML5 CANVAS基础教程》读书笔记

    一.HTML5简介 1.HTML5新特性 1)结构元素:section,header,hgroup,footer,nav,article,aside, 2)内容元素:figure,figcaption ...

  9. canvas 基础知识

    canvas 基础 低版本的ie不支持html5,需要引入excanvas.js来让ie支持canvas. 检测支持canvas <canvas id="canvas" wi ...

随机推荐

  1. 【EasyNetQ】- 发送接收

    发布/订阅和请求/响应模式是位置透明的,因为您不需要指定消息的使用者所在的位置,而发送/接收模式专门用于通过命名队列进行通信.它也不会假设可以通过队列发送的消息类型.这意味着您可以通过同一队列发送不同 ...

  2. Docker实战系列一:初识Docker for Windows

    windows下安装Docker官网教程Install Docker for Windows Docker配置官网教程Get started with Docker for Windows

  3. Linux 常用命令记录(学习笔记)

    不同机器间文件传输(转自:http://www.zhimengzhe.com/mac/323324.html) scp是什么? scp是secure copy的简写,用于在Linux下进行远程拷贝文件 ...

  4. JSP语法,运行机理等

    JSP是几年前就接触了,但是用归用,很多实际的意义含义等还是不太明白,借此机会,梳理一下. 1.JSP运行原理:当浏览器web应用服务器请求一个JSP页面时,Web应用服务器将其转换成一个Servle ...

  5. [CF912B]New Year's Eve

    题意:在1~n中选不超过m个数,求其异或最大值 题解:经过找规律发现如果m为1,输出n,不然输出最小的不超过n的2^k-1 C++ Code: #include<cstdio> using ...

  6. 雪碧图background-position的rem用法

    background的雪碧图配合rem就正常写即可,要加上background-size,大小为sprites的原图尺寸,宽高为一帧的尺寸.例如: .player{ width: 2.32rem; / ...

  7. HZOI String STL的正确用法

                                                                      String          3s 512 MB描述硬盘中里面有n ...

  8. HDU - 1880 魔咒词典~哈希入门

    哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. 给你一部魔咒词 ...

  9. Robot POJ - 1376

    The Robot Moving Institute is using a robot in their local store to transport different items. Of co ...

  10. SQL优化单表案例

    数据准备: -- 创建数据库 mysql> create database db_index_case; Query OK, row affected (0.00 sec) -- 查看数据库 m ...