首先,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画五角星,canvas制作钟表、Konva写钟表

    制作一个画画板,有清屏有橡皮擦有画笔可以换颜色 style样式 <head> <meta charset="UTF-8"> <title>画画板 ...

  2. 基于canvas实现钟表

    原理说明 1.通过arc方法实现钟表外环: 2.通过line实现钟表时针,分针,秒针和刻度标志的绘制,基于save和restore方法旋转画布绘制不同角度的指针: 3.通过font方法实现在画布上绘制 ...

  3. -_-#【Canvas】导出在<canvas>元素上绘制的图像

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. Canvas 中drawImage 绘制不出图片

    在使用Canvas的drawImage绘制图片时,却发现绘制不出图片,原因是图片是异步加载,图片加载完再绘制. //html <img src="1.png" /> & ...

  5. canvas教程(二) 绘制直线

    经过 canvas 教程(一) 简介 我们知道了 canvas 的一些基本情况 而本次是给大家带来直线的绘制 canvas 中,基本图形有两种,一种是直线,还有一种是曲线 但是无论是直线还是曲线,我们 ...

  6. canvas教程(三) 绘制曲线

    经过 canvas 教程(二) 绘制直线 我们知道了 canvas 的直线是怎么绘制的 而本次是给大家带来曲线相关的绘制 绘制圆形 在 canvas 中我们可以使用 arc 方法画一个圆 contex ...

  7. Android中使用Canvas和Paint绘制一个安卓机器人

    场景 在Android中画笔使用Paint类,画布使用Canvas类来表示. 绘图的基本步骤 首先编写一个继承自View的自定义View类,然后重写其onDraw方法,最后把自定义的view添加到ac ...

  8. Canvas基础——钟表绘制

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

  9. Canvas 旋转风车绘制

    写在前面:   亲爱的朋友们大家好,鄙人自学前端,第一次写博客,写的不好的地方,烦请同学们谅解,如果本文对你有一丁点帮助,还请劳驾您给我点个赞,您的认可将是我坚持下去的强大动力!谢谢! 在进行教学之前 ...

随机推荐

  1. 简洁 Abstract Factory模式(3.1)

    镇楼 在某些书中使用了二维图说明抽象工厂模式.非常好,可是yqj2065不喜欢他们的产品族/产品等级,改成品牌/产品类型. 抽象工厂模式(abstract factory pattern)较工厂方法模 ...

  2. Could not find class &#39;****&#39;, referenced from method #####

    找不到类,多半也是和第三方的jar包有关. 将找不到的类.在下图中的地方勾选出来.假设jar太多.有的类有冲突的话,须要明白其先后顺序. 请外一篇和第三方jar有关的异常的文章. Conversion ...

  3. 自己动手,丰衣足食!一大波各式各样的ImageView来袭!

    工作略忙,一直想自己打造一个开源控件却苦于没有时间,可是这种事情如果不动手就会一直拖下去,于是最近抽时间做了个简单的自定义形状的ImageView控件. 时间紧迫,目前仅支持正六边形.圆形.菱形.椭圆 ...

  4. Spring MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解(四)

    这一章大象将详细分析web层代码,以及使用Spring MVC的注解及其用法和其它相关知识来实现控制器功能.     之前在使用Struts2实现MVC的注解时,是借助struts2-conventi ...

  5. VS的一部分快捷键

    快捷键                                         功能CTRL + SHIFT + B                        生成解决方案CTRL + F ...

  6. html 笔记

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  7. C语言实现电话本 动态开辟 信息存储于文件

    下面是我用C写的一个电话本小项目,实现的功能有:添加 删除 修改 查找 排序 清空 显示,功能还是比较全的,内存也是动态开辟的.能存储于本地,能从本地读出并显示 头文件部分代码,contact.h: ...

  8. 获取当前时间日期并格式化--JS

    工作当中,总是遇到很多觉得不错的JS脚本.现在觉得还是找个地方记录下来,以后可以随时查看. /** *获取当前时间日期并格式化 */ function getNowDate(){ var mydate ...

  9. zzzzw_在线考试系统②管理员篇章

    今天实现了管理的功能,谈谈遇到的问题!我先上图 图一   管理员的数据库 在action中访问Servlet API的非IoC方式之一:使用apache.struts2.ServletActionCo ...

  10. Java联网技术之一TCP

    最近突然对java网络编程编程这一块非常感兴趣,于是找了很多资料,一点点的尝试,下面是自己的一点小见解,不喜勿喷,欢迎指正. 首先说说客户端和服务器端吧, 如果是网页的话,客户端通过网页的链接对服务器 ...