之前用html+css+JavaScript实现了一个简单钟表,但还是有一些问题,主要是一些css属性不同浏览器支持效果不一样,所以尝试用 canvas实现了一个简单的钟表,效果在下方,当然了,采用canvas同样会有一些浏览器不支持。。。 这里只讨论canvas的实现方式。^_^

html部分

html部分很简单,写入canvas标签,其id设置为“canvas”,用css设置成居中显示,代码如下:

 1<!doctype html> 2<html> 3<head> 4<meta charset='utf-8'> 5<style> 6    canvas{display:block;margin:5px auto;} 7</style> 8<title>clock</title> 9</head>10<body>11<canvas id='canvas'>您的浏览器不支持canvas标签</canvas>12<script type='text/javascript' src="外部JavaScript文件路径"></script>13</body>14</html>

备注:需要通过script标签的src属性引入外部JavaScript文件

JavaScript部分

可以通过js获取Canvas对象,设置画布的宽高,不过绘图工作是通过操作CanvasRenderingContext2D对象来操作的,获取此对象的方法:

1var canvas = document.getElementById('canvas');    // Canvas对象2 canvas.width = 450;        // 宽3 canvas.height = 450;    // 高4var context = canvas.getContext('2d'); // 获取绘图上下文环境

获取到绘图上下文context以后即可绘制钟表了,整体思路是这样的:定义一个全局变量记录当前系统时间信息,用setInterval方法重复执行,获取时间信息,并绘制图像,代码如下:

1var currentDateObj; // 记录当前时间信息2 setInterval(function(){
3     update(); // 修改currentDateObj的内容4     draw(); // 根据currentDateObj的内容绘制图像5 }, 500);

本文实现重点在于绘制图像,关于update方法的实现,可以直接查看后边的整体js代码,draw方法中,主要涉及到的一些内容有:线段和圆的绘制、canvas文字渲染、canvas阴影实现、canvas图形变换等内容

canvas绘制线段、圆

绘制线段很简单,只需调用moveTo、lineTo方法设置线段路径,调用stroke方法完成绘制

 1 context.moveTo(20, 70);
 2 context.lineTo(140, 70);
 3 context.lineTo(140, 40);
 4 context.lineTo(180, 80);
 5 context.lineTo(140, 120);
 6 context.lineTo(140, 90);
 7 context.lineTo(20, 90);
 8 context.lineWidth = 2; // 设置线段宽度 9 context.strokeStyle = "#058"; // 设置颜色10 context.stroke();    // 绘制到画布上

运行结果:

绘制圆需要调用arc方法,然后调用stroke完成绘制,arc有5个参数,分别表示圆弧圆心的x坐标、y坐标、圆弧半径、起始角、结束角,最后一个参数是一个布尔值,false表示顺时针,true表示逆时针,下面是一些示例

 1for(var i = 0; i < 2; i++) {
 2for(var j = 0; j < 4; j++){
 3var b = (i == 0) ? false : true;
 4        context.beginPath();
 5         context.lineWidth = 2;
 6         context.strokeStyle = '#058';
 7         context.arc(150 * j + 75, 150 * i + 75, 45, 0, (j + 1) * Math.PI / 2, b);
 8        context.stroke();
 9    }
10 }

运行结果:

通过moveTo、lineTo或者arc方法设置好图形路径以后,调用stroke方法完成图形绘制,如果需要绘制一个区域,需要调用fill方法,如上例中,可以将stroke改成fill代码如下:

1for(var i = 0; i < 2; i++) {
2for(var j = 0; j < 4; j++){
3var b = (i == 0) ? false : true;
4        context.beginPath();
5         context.fillStyle = '#058';
6         context.arc(150 * j + 75, 150 * i + 75, 45, 0, (j + 1) * Math.PI / 2, b);
7        context.fill();
8    }
9 }

运行结果如下:

canvas文字渲染

在canvas画布上写段文字很简单,基本分两步:1.通过设置context的font属性设置文本的样式;2. 调用fillText或strokeText方法渲染文字

1 context.font = "bold 40px Arial";
2 context.fillStyle = '#058';
3 context.fillText("Canvas制作简单钟表", 50, 50);
4 context.strokeStyle = '#058';
5 context.strokeText("Canvas制作简单钟表", 50, 150);

运行结果如下:

可以设置textAlign和textBaseline属性分别设置文本水平和垂直方向的对齐方式

canvas阴影效果

canvas设置阴影主要涉及到的属性有:shadowColor设置阴影颜色,shadowOffsetX和shadowOffsetY分别设置阴影在x和y方向上的偏移量,shadowBlur设置阴影的模糊程度

1 context.shadowColor = "#444";    // 阴影颜色2 context.shadowOffsetX = 10;    // 阴影在x方向偏移量 负数为反方向3 context.shadowOffsetY = 10; // 阴影在y方向偏移量 负数为反方向4 context.shadowBlur = 10;    // 阴影模糊程度5 context.fillStyle = "#058";
6 context.fillRect(100, 50, 300, 100);

运行结果如下:

canvas图形变换

canvas中最基本的图形变换涉及到的方法是:位移 translate(x, y),旋转 rotate(deg),缩放 scale(sx, sy),我们知道默认的坐标原点(0, 0)在canvas的左上角,但是对于我们的钟表来说,如果能将坐标原点移动到表盘的圆心位置,处理起来将很方便,rotate将图像旋转制定的角度,旋 转中心点即坐标原点,scale将图像按制定的比例在x和y方向上进行缩放。需要注意的是,cavnas是基于状态的,如果通过调用 translate(100, 100)方法,将坐标原点移动到(100, 100)的位置以后,如果再次调用,那么坐标原点将在当前基础上累加,所以在实际调用时,需要掉用save方法保存当前状态,完成绘制以后调用 restore方法还原

本例中多次应用translate方法,设置表盘圆心为坐标原点,用rotate方法旋转图像,如刻度的绘制,只是绘制水平方向的一条线段,通过旋转不同角度来达到效果

clearRect方法

clearRect方法用于清空一个矩形空间站的图像,语法为:context.clearRect(x, y, width, height); 第一个参数x 表示要清除的矩形左上角的x坐标,第二个参数y 表示要清除的矩形左上角的y坐标,width参数表示要清除的矩形的宽度,height参数表示要清除的矩形的高度。

在本例中,draw方法的第一步就是调用此方法,清空整个canvas画布的内容,然后才根据currentDateObj中的内容绘制图像。

JavaScript部分的完整代码

准备工作基本做完了,下面是本例中完整的JavaScript代码:

  1 (function(){
  2var config = {
  3        canvas : {
  4             width : 420, // 设置canvas的宽  5             height : 420, // 设置canvas的高      6        },
  7        clock : {
  8             radius : 200, // 设置表盘半径  9             borderWidth : 10, // 表盘边框宽度 10            origin : {
 11                 radius : 8, // 中心点 半径 12                 color : '#333' // 中心点 颜色 13            },
 14            hand : {
 15                 hour : {width : 5, length : 80}, // 时针宽度和长度 16                 minute : {width : 2, length : 110}, // 分针的宽度和长度 17                 second : {length : 160} // 秒针长度 18            }
 19        }
 20    };
 21 22var canvas = document.getElementById('canvas');
 23     canvas.width = config.canvas.width;
 24     canvas.height = config.canvas.height;
 25var context = canvas.getContext('2d');
 26 27var currentDateObj;    // 保存当前时间 28 29     setInterval(function(){
 30        update();
 31        draw();
 32     }, 500);
 33 34function update(){
 35         currentDateObj = getDateObj();
 36 37function getDateObj() {
 38var week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
 39var d = new Date();
 40var year = d.getFullYear();
 41var month = d.getMonth() + 1;
 42var date = d.getDate();
 43var day = d.getDay();
 44var hour = d.getHours();
 45var minute = d.getMinutes();
 46var second = d.getSeconds();
 47             month = (month < 9) ? '0' + month : '' + month;
 48             date = (date < 9) ? '0' + date : '' + date;
 49             hour = (hour < 9) ? '0' + hour : '' + hour;
 50             minute = (minute < 9) ? '0' + minute : '' + minute;
 51             second = (second < 9) ? '0' + second : '' + second;
 52var time = [hour, minute, second];
 53var str = year + '-' + month + '-' + date + ' ' + week[day];
 54return {
 55                dateStr: str,
 56                dateTime: time
 57            }
 58        }
 59    }
 60 61function draw() {
 62         context.clearRect(0, 0, canvas.width, canvas.height);
 63 64        drawBorder();
 65        drawScale();
 66        drawNumbers();
 67        drawTime();
 68        drawHand();
 69        drawOrigin();
 70 71/**
 72         * 绘制表盘边框
 73*/ 74function drawBorder() {
 75            context.save();
 76            context.beginPath();
 77             context.arc(canvas.width / 2, canvas.height / 2, config.clock.radius, 0, 2 * Math.PI, false);
 78             context.arc(canvas.width / 2, canvas.height / 2, config.clock.radius - config.clock.borderWidth, 0, 2 * Math.PI, true);
 79             context.fillStyle = "#333";
 80             context.shadowColor = "#444";
 81             context.shadowBlur = 10;
 82            context.closePath();
 83            context.fill();
 84            context.restore();
 85        }
 86 87/**
 88         * 绘制中心圆点
 89*/ 90function drawOrigin() {
 91            context.save();
 92            context.beginPath();
 93             context.arc(canvas.width / 2, canvas.height / 2, config.clock.origin.radius, 0, 2 * Math.PI, false);
 94             context.fillStyle = config.clock.origin.color;
 95             context.shadowColor = "#444";
 96             context.shadowBlur = 3;
 97            context.closePath();
 98            context.fill();
 99            context.restore();
100        }
101102/**
103         * 绘制表盘刻度
104*/105function drawScale() {
106for(var i = 0; i < 60; i++) {
107var obj = {
108                     sx : config.clock.radius - 15 - config.clock.borderWidth,
109                     sy : 0,
110                     ex : config.clock.radius - config.clock.borderWidth - 5,
111                     ey : 0,
112                     color : "#333",
113                     width : 1
114                };
115                context.save();
116                 context.translate(canvas.width / 2, canvas.height / 2);
117                 context.rotate(i * 6 * Math.PI / 180);
118                context.beginPath();
119if(i % 5 == 0) {
120                     obj.width = 3;
121                     obj.color = "#000";
122                }
123if(i % 15 == 0) {
124                     obj.sx = config.clock.radius - 20 - config.clock.borderWidth;
125                }
126                context.moveTo(obj.sx, obj.sy);
127                context.lineTo(obj.ex, obj.ey);
128                 context.strokeStyle = obj.color;
129                 context.lineWidth = obj.width;
130                context.closePath();
131                context.stroke();
132                context.restore();
133            }
134        }
135136/**
137         * 获取1-12数字
138*/139function drawNumbers() {
140var radius = config.clock.radius - config.clock.borderWidth - 40;
141for(var i = 0; i < 12; i++) {
142                context.save();
143                context.beginPath();
144                 context.translate(canvas.width / 2, canvas.height / 2);
145                 context.font = "normal 28px Arial";
146if((i + 1) % 3 == 0) {
147                     context.font = "normal 36px Arial";
148                }
149                 context.textAlign = 'center';
150                 context.textBaseline = 'middle';
151                 context.fillText(i + 1, -radius * Math.cos((-i * 30 - 120) * Math.PI  / 180), radius * Math.sin((-i * 30 - 120) * Math.PI / 180));
152                context.closePath();
153                context.restore();
154            }
155        }
156157/**
158         * 绘制下方的文字
159*/160function drawTime() {
161            context.save();
162             context.translate(canvas.width / 2, canvas.height / 2);
163            drawDateStr();
164            drawTimeBox();
165            drawTime();
166            context.restore();
167168/**
169             * 绘制 年月日星期信息
170*/171function drawDateStr() {
172                context.beginPath();
173                 context.font = "bold 14px Arial";
174                 context.textAlign = 'center';
175                 context.textBaseline = 'middle';
176                 context.shadowColor = '#ccc';
177                 context.shadowBlur = 2;
178                context.closePath();
179                 context.fillText(currentDateObj.dateStr, 0, 40);
180            }
181182/**
183             * 绘制显示时分秒的背景盒子
184*/185function drawTimeBox() {
186                context.beginPath();
187                 context.fillStyle = "#555";
188                 context.shadowColor = "#444";
189                 context.shadowBlur = 3;
190                context.closePath();
191                 context.fillRect(-47, 60, 30, 30);
192                 context.fillRect(-15, 60, 30, 30);
193                 context.fillRect(17, 60, 30, 30);
194            }
195196/**
197             * 绘制时分秒数字
198*/199function drawTime() {
200                context.beginPath();
201                 context.font = "normal 14px Arial";
202                 context.textAlign = 'center';
203                 context.textBaseline = 'middle';
204                 context.fillStyle = "#fff";
205                context.closePath();
206                 context.fillText(currentDateObj.dateTime[0], -32, 75);
207                 context.fillText(currentDateObj.dateTime[1], 0, 75);
208                 context.fillText(currentDateObj.dateTime[2], 32, 75);
209            }
210211        }
212213/**
214         * 绘制时分秒针
215*/216function drawHand() {
217218var _hour = currentDateObj.dateTime[0] % 12;
219var _minute = currentDateObj.dateTime[1];
220var _second = currentDateObj.dateTime[2];
221            drawHourHand();
222            drawMinuteHand();
223            drawSecondHand();
224225// 时针226function drawHourHand() {
227                context.save();
228                 context.translate(canvas.width / 2, canvas.height / 2);
229                 context.rotate(((_hour + _minute / 60) - 3) * 30 * Math.PI / 180);
230                context.beginPath();
231                 context.moveTo(-12, 0);
232                 context.lineTo(config.clock.hand.hour.length, 0);
233                 context.lineWidth = config.clock.hand.hour.width;
234                 context.strokeStyle = config.clock.origin.color;
235                 context.lineCap = "round";
236                 context.shadowColor = "#999";
237                 context.shadowBlur = 5;
238                 context.shadowOffsetX = 5;
239                 context.shadowOffsetY = 5;
240                context.stroke();
241                context.stroke();
242                context.closePath();
243                context.restore();
244            }
245246// 分针247function drawMinuteHand() {
248                context.save();
249                 context.translate(canvas.width / 2, canvas.height / 2);
250                 context.rotate((_minute - 15) * 6 * Math.PI / 180);
251                context.beginPath();
252                 context.moveTo(-18, 0);
253                 context.lineTo(config.clock.hand.minute.length, 0);
254                 context.lineWidth = config.clock.hand.minute.width;
255                 context.strokeStyle = config.clock.origin.color;
256                 context.lineCap = "round";
257                 context.shadowColor = "#999";
258                 context.shadowBlur = 5;
259                 context.shadowOffsetX = 5;
260                 context.shadowOffsetY = 5;
261                context.stroke();
262                context.closePath();
263                context.restore();
264            }
265266// 秒针267function drawSecondHand() {
268                context.save();
269                 context.translate(canvas.width / 2, canvas.height / 2);
270                 context.rotate((_second - 15) * 6 * Math.PI / 180);
271                context.beginPath();
272                 context.moveTo(-35, 1.5);
273                 context.lineTo(0, 1.5);
274                 context.lineTo(config.clock.hand.second.length, 0.5);
275                 context.lineTo(config.clock.hand.second.length, -0.5);
276                 context.lineTo(0, -1.5);
277                 context.lineTo(-35, -1.5);
278                context.closePath();
279                 context.fillStyle = "#f60";
280                 context.shadowColor = "#999";
281                 context.shadowBlur = 5;
282                 context.shadowOffsetX = 5;
283                 context.shadowOffsetY = 5;
284                context.fill();
285                context.restore();
286            }
287        }
288    }
289 }());

canvas制作钟表相关推荐

  1. linux 电子表小程序,微信小程序Taro开发(3):canvas制作钟表

    制作钟表分成两部分,一部分是表盘,一部分是时针.分针.秒针的走动,首先,先绘制表盘: // 绘制表盘 getDialClock = () => { const width = this.stat ...

  2. canvas制作钟表小案例

    实现原理:canvas绘制圆的知识以及Date对象 window.onload=function (){var myCanvas=document.querySelector('#myCanvas') ...

  3. canvas制作简单钟表

    之前用html+css+JavaScript实现了一个简单钟表,但还是有一些问题,主要是一些css属性不同浏览器支持效果不一样,所以尝试用 canvas实现了一个简单的钟表,效果在下方,当然了,采用c ...

  4. 如何用python做表_如何使用Python中的Tkinter制作钟表?

    这就不得不说,python真的是一个非常神奇的编程语言,小编在浏览一些知识资料时候,根据内容,整合了解后,发现居然可以制作钟表,立刻来了兴趣,于是根据内容编写了以下代码,大家如果感兴趣的话,也可以来看 ...

  5. html根据字段制作曲线图,canvas制作简单的HTML图表,折线或者矩形统计(原创)

    插件描述:canvas制作简单的HTML图表,折线或者矩形统计 使用canvas制作简单的HTML图表,折线或者矩形统计. 使用canvas制作简单的HTML图表,折线或者矩形统计,简单而实用.图形由 ...

  6. [译]怎样用HTML5 Canvas制作一个简单的游戏

    这是我翻译自LostDecadeGames主页的一篇文章,原文地址:How To Make A Simple HTML5 Canvas Game. 下面是正文: 自从我制作了一些HTML5游戏(例如C ...

  7. html制作动态坐标轴,HTML5 canvas制作动态随机星图

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 本篇将会介绍如何用canvas制作动态随机移动的星图啦啦啦 小白在远离小白道路上的第一步就是搭个博客 前言 这次的博文不 ...

  8. Canvas制作的下雨动画

    简介 在codepen上看到一个Canvas做的下雨效果动画,感觉蛮有意思的.就研究了下,这里来分享下,实现技巧.效果可以见下面的链接. 霓虹雨: http://codepen.io/natewile ...

  9. [html] 使用canvas制作一个印章

    [html] 使用canvas制作一个印章 <!DOCTYPE html> <html lang="en"> <head><meta ch ...

最新文章

  1. CentOS6怎么样设置ADSL上网
  2. HTML样式以及使用
  3. THE DRAGON PRINCE BOOK 3
  4. matlab bp结果,Matlab如何处理BP网络每次运行结果不一样这个问题
  5. Python:赋值语句和布尔值
  6. 数据结构:点之间的最短距离--Floyd算法
  7. 搭建: canal部署与实例运行
  8. ubuntu安装python下载包_Ubuntu安装Python的包管理工具Pip
  9. c语言必考面试题,c语言面试最必考的十道试题,求职必看!!!
  10. UVA 847 - A Multiplication Game(游戏)
  11. 利用Python操作Excel实现自动化办公
  12. 带你十分钟了解BFC(渡一教育笔记)
  13. CSS绝对底部布局 Sticky footer
  14. LayaAir 快捷键设置与资源命名规则
  15. Android Gradle配置资源前缀
  16. 批量反编译class
  17. 计算机工程与应用论文模板,计算机工程与应用论文模板
  18. 余额支付使用短信验证码进行二次确认
  19. Wireshark的下载安装及简单使用教程
  20. Python 修改图像中的像素值

热门文章

  1. 趣谈唯一邀请码生成方法
  2. UIUC计算机科学系博士,PhD捷报|计算机博士全美TOP5!清华首批UIUC CS PhD全奖!恭喜Nuts清华学员!...
  3. 流量复制导流工具研究
  4. linux查看磁盘空间大小
  5. HTML做网页登录界面
  6. WP版网易云,解决启动慢问题
  7. verilog的一些技巧,就靠他拿offer了!
  8. Nexus3忘记admin密码时的解决办法
  9. Stimulsoft Dashboards.WEB 23.1.8 完美Patch
  10. AI开发之——Leonardo—Finetuned Models及利用模型制图(5)