canvas制作钟表
之前用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制作钟表相关推荐
- linux 电子表小程序,微信小程序Taro开发(3):canvas制作钟表
制作钟表分成两部分,一部分是表盘,一部分是时针.分针.秒针的走动,首先,先绘制表盘: // 绘制表盘 getDialClock = () => { const width = this.stat ...
- canvas制作钟表小案例
实现原理:canvas绘制圆的知识以及Date对象 window.onload=function (){var myCanvas=document.querySelector('#myCanvas') ...
- canvas制作简单钟表
之前用html+css+JavaScript实现了一个简单钟表,但还是有一些问题,主要是一些css属性不同浏览器支持效果不一样,所以尝试用 canvas实现了一个简单的钟表,效果在下方,当然了,采用c ...
- 如何用python做表_如何使用Python中的Tkinter制作钟表?
这就不得不说,python真的是一个非常神奇的编程语言,小编在浏览一些知识资料时候,根据内容,整合了解后,发现居然可以制作钟表,立刻来了兴趣,于是根据内容编写了以下代码,大家如果感兴趣的话,也可以来看 ...
- html根据字段制作曲线图,canvas制作简单的HTML图表,折线或者矩形统计(原创)
插件描述:canvas制作简单的HTML图表,折线或者矩形统计 使用canvas制作简单的HTML图表,折线或者矩形统计. 使用canvas制作简单的HTML图表,折线或者矩形统计,简单而实用.图形由 ...
- [译]怎样用HTML5 Canvas制作一个简单的游戏
这是我翻译自LostDecadeGames主页的一篇文章,原文地址:How To Make A Simple HTML5 Canvas Game. 下面是正文: 自从我制作了一些HTML5游戏(例如C ...
- html制作动态坐标轴,HTML5 canvas制作动态随机星图
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 本篇将会介绍如何用canvas制作动态随机移动的星图啦啦啦 小白在远离小白道路上的第一步就是搭个博客 前言 这次的博文不 ...
- Canvas制作的下雨动画
简介 在codepen上看到一个Canvas做的下雨效果动画,感觉蛮有意思的.就研究了下,这里来分享下,实现技巧.效果可以见下面的链接. 霓虹雨: http://codepen.io/natewile ...
- [html] 使用canvas制作一个印章
[html] 使用canvas制作一个印章 <!DOCTYPE html> <html lang="en"> <head><meta ch ...
最新文章
- CentOS6怎么样设置ADSL上网
- HTML样式以及使用
- THE DRAGON PRINCE BOOK 3
- matlab bp结果,Matlab如何处理BP网络每次运行结果不一样这个问题
- Python:赋值语句和布尔值
- 数据结构:点之间的最短距离--Floyd算法
- 搭建: canal部署与实例运行
- ubuntu安装python下载包_Ubuntu安装Python的包管理工具Pip
- c语言必考面试题,c语言面试最必考的十道试题,求职必看!!!
- UVA 847 - A Multiplication Game(游戏)
- 利用Python操作Excel实现自动化办公
- 带你十分钟了解BFC(渡一教育笔记)
- CSS绝对底部布局 Sticky footer
- LayaAir 快捷键设置与资源命名规则
- Android Gradle配置资源前缀
- 批量反编译class
- 计算机工程与应用论文模板,计算机工程与应用论文模板
- 余额支付使用短信验证码进行二次确认
- Wireshark的下载安装及简单使用教程
- Python 修改图像中的像素值
热门文章
- 趣谈唯一邀请码生成方法
- UIUC计算机科学系博士,PhD捷报|计算机博士全美TOP5!清华首批UIUC CS PhD全奖!恭喜Nuts清华学员!...
- 流量复制导流工具研究
- linux查看磁盘空间大小
- HTML做网页登录界面
- WP版网易云,解决启动慢问题
- verilog的一些技巧,就靠他拿offer了!
- Nexus3忘记admin密码时的解决办法
- Stimulsoft Dashboards.WEB 23.1.8 完美Patch
- AI开发之——Leonardo—Finetuned Models及利用模型制图(5)