js基于canvas实现时钟组件


Posted in Javascript onFebruary 07, 2021

canvas一直是前端开发中不可或缺的一种用来绘制图形的标签元素,比如压缩上传的图片、比如刮刮卡、比如制作海报、图表插件等,很多人在面试的过程中也会被问到有没有接触过canvas图形绘制。

定义

canvas元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成。
canvas标签只是图形容器,您必须使用脚本来绘制图形。

浏览器支持

Internet Explorer 9、Firefox、Opera、Chrome 和 Safari 支持

那么本篇文章就通过一个时钟组件来熟悉使用一下关于canvas的api。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>canvas时钟</title>
<style>
*{margin:0;padding:0;}
body{text-align:center;padding-top:100px;}
</style>
</head>
<body>
<canvas id="clock" width="200px" height="200px"></canvas>
<script>
(function(win){
	function DrawClock(options){
		this.canvas = options.el;
		this.ctx  = this.canvas.getContext('2d');//方法返回一个用于在画布上绘图的环境
		this.width = this.ctx.canvas.width;
		this.height = this.ctx.canvas.height;
		this.r   = this.width / 2;
		this.rem  = this.width / 200;
		this.digits = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];

	  var self  = this;
	  self.init();
	  setInterval(function(){
	  	self.init();
	  }, 1000);
	}

	DrawClock.prototype = {
		init: function(){
			var ctx = this.ctx;
			ctx.clearRect(0, 0, this.width, this.height);  //在给定的矩形内清除指定的像素
			var now = new Date();
			var hours = now.getHours();
			var minutes = now.getMinutes();
			var seconds = now.getSeconds();

			var hour = hours >= 12 ? hours - 12 : hours;
			var minute = minutes + seconds / 60;

			this.drawBackground();
			this.drawHour(hour, minute);
			this.drawMinute(minute);
			this.drawSecond(seconds);
			this.drawDot();
			ctx.restore();
		},
		drawBackground: function(){
			var ctx = this.ctx;
			var self = this;
			ctx.save();
			ctx.translate(this.r, this.r);     //重新映射画布上的 (0,0) 位置
			ctx.beginPath();
			ctx.lineWidth = 8 * this.rem;
			ctx.arc(0, 0, this.r - ctx.lineWidth / 2, 0, 2 * Math.PI, false);  //创建弧/曲线(用于创建圆形或部分圆)
			ctx.stroke();
			ctx.font = 16 * this.rem + "px Arial";//设置或返回文本内容的当前字体属性
			ctx.textAlign = "center";       //设置或返回文本内容的当前对齐方式
			ctx.textBaseline = "middle";      //设置或返回在绘制文本时使用的当前文本基线
			this.digits.forEach(function(number, i){
				var rad = 2 * Math.PI / 12 * i;
				var x = Math.cos(rad) * (self.r - 33 * self.rem);
				var y = Math.sin(rad) * (self.r - 33 * self.rem);
				ctx.fillText(number, x, y);    //在画布上绘制"被填充的"文本
			});

			//分钟的刻度,每分钟转6deg
			for (var i = 0; i < 60; i++){
				ctx.save();            //保存当前环境的状态
				ctx.rotate(6 * i * Math.PI / 180); //旋转当前绘图
				ctx.beginPath();          //起始一条路径,或重置当前路径
				ctx.moveTo(0, -82 * this.rem);   //把路径移动到画布中的指定点,不创建线条
				ctx.lineTo(0, -87 * this.rem);   //添加一个新点,然后在画布中创建从该点到最后指定点的线条
				ctx.closePath();          //创建从当前点回到起始点的路径
				ctx.strokeStyle = '#000';     //设置或返回用于笔触的颜色、渐变或模式
				ctx.lineWidth = 1 * this.rem;   //设置或返回当前的线条宽度
				ctx.stroke();           //绘制已定义的路径
				ctx.restore();           //返回之前保存过的路径状态和属性
			}
			//小时的刻度,每小时转30deg
			for (var i = 0; i < 12; i++){
				ctx.save();
				ctx.rotate(30 * i * Math.PI / 180);
				ctx.beginPath();
				ctx.moveTo(0, -79 * this.rem);
				ctx.lineTo(0, -87 * this.rem);
				ctx.closePath();
				ctx.strokeStyle = '#000';
				ctx.lineWidth = 2 * this.rem;
				ctx.stroke();
				ctx.restore();
			}
		},
		drawHour: function(hour, minute){
			var ctx = this.ctx;
			ctx.save();
			ctx.beginPath();
			var hRad = 2 * Math.PI / 12 * hour;
			var mRad = 2 * Math.PI / 12 / 60 * minute;
			ctx.rotate(hRad + mRad);
			ctx.lineWidth = 6 * this.rem;
			ctx.lineCap = "round";         //设置或返回线条的结束端点样式
			ctx.moveTo(0, 10 * this.rem);
			ctx.lineTo(0, -this.r / 2);
			ctx.stroke();
			ctx.restore();
		},
		drawMinute: function(minute){
			var ctx = this.ctx;
			ctx.save();
			ctx.beginPath();
			var rad = 2 * Math.PI / 60 * minute;
			ctx.rotate(rad);
			ctx.lineWidth = 3 * this.rem;
			ctx.lineCap = "round";
			ctx.moveTo(0, 10 * this.rem);
			ctx.lineTo(0, -this.r + 26 * this.rem);
			ctx.stroke();
			ctx.restore();
		},
		drawSecond: function(second){
			var ctx = this.ctx;
			ctx.save();
			ctx.beginPath();
			ctx.fillStyle = "#c14543";
			var rad = 2 * Math.PI / 60 * second;
			ctx.rotate(rad);
			ctx.moveTo(-3 * this.rem, 20 * this.rem);
			ctx.lineTo(3 * this.rem, 20 * this.rem);
			ctx.lineTo(1, -this.r + 26 * this.rem);
			ctx.lineTo(-1, -this.r + 26 * this.rem);
			ctx.fill();  //填充当前绘图(路径)
			ctx.restore();
		},
		drawDot: function(minute){
			var ctx = this.ctx;
			ctx.beginPath();
			ctx.fillStyle = "#fff";
			ctx.arc(0, 0, 3 * this.rem, 0, 2 * Math.PI, false);
			ctx.fill();
		}
	};

    win.DrawClock = DrawClock;
})(window);

new DrawClock({el: document.getElementById("clock")});
</script>
</body>
</html>

只要心中有丘壑,就能耕出二亩田!canvas时钟用到了canvas中大部分的api,通过学习canvas时钟的代码实现,很能了解canvas的属性和方法,同时,实现时钟效果时,用到了数学中的几何模型正弦sin和余弦cos以及弧度的计算方法,又重温了一把当年学数学时的许多乐趣,可谓是一举两得。

时钟效果图如下:

js基于canvas实现时钟组件

以上就是js基于canvas实现时钟组件的详细内容,更多关于canvas实现时钟组件的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
onpropertypchange
Jul 01 Javascript
AngularJS中的$watch(),$digest()和$apply()区分
Apr 04 Javascript
AngularJS通过ng-route实现基本的路由功能实例详解
Dec 13 Javascript
vue自定义过滤器创建和使用方法详解
Nov 06 Javascript
JS+HTML+CSS实现轮播效果
Nov 28 Javascript
vue组件(全局,局部,动态加载组件)
Sep 02 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
Sep 11 Javascript
js异步上传多张图片插件的使用方法
Oct 22 Javascript
webpack中的模式(mode)使用详解
Feb 20 Javascript
Vue 列表页带参数进详情页的操作(router-link)
Nov 13 Javascript
在vue中动态修改css其中一个属性值操作
Dec 07 Vue.js
Vue2.0搭建脚手架
Mar 13 Vue.js
nestjs中异常过滤器Exceptionfilter的具体使用
Feb 07 #Javascript
js实现类选择器和name属性选择器的示例步骤
Feb 07 #Javascript
vue如何使用rem适配
Feb 06 #Vue.js
如何管理Vue中的缓存页面
Feb 06 #Vue.js
JS中锚点链接点击平滑滚动并自由调整到顶部位置
Feb 06 #Javascript
一起深入理解js中的事件对象
Feb 06 #Javascript
手动实现vue2.0的双向数据绑定原理详解
Feb 06 #Vue.js
You might like
安装PHP可能遇到的问题“无法载入mysql扩展” 的解决方法
2007/04/16 PHP
php下将XML转换为数组
2010/01/01 PHP
PHP文件上传判断file是否己选择上传文件的方法
2014/11/10 PHP
thinkphp3.2.3版本的数据库增删改查实现代码
2016/09/22 PHP
win10 apache配置虚拟主机后localhost无法使用的解决方法
2018/01/27 PHP
thinkphp整合系列之极验滑动验证码geetest功能
2019/06/18 PHP
Yii2.0框架behaviors方法使用实例分析
2019/09/30 PHP
TP3.2.3框架使用CKeditor编辑器在页面中上传图片的方法分析
2019/12/31 PHP
jquery的键盘事件修改代码
2011/02/24 Javascript
jquery解析JSON数据示例代码
2014/03/17 Javascript
JS 打印界面的CSS居中代码适用所有浏览器
2014/03/19 Javascript
JQuery EasyUI 数字格式化处理示例
2014/05/05 Javascript
javascript浏览器兼容教程之事件处理
2014/06/09 Javascript
JavaScript实现的内存数据库LokiJS介绍和入门实例
2014/11/17 Javascript
JS获取html元素的标记名实现方法
2016/10/08 Javascript
微信小程序之拖拽排序(代码分享)
2017/01/21 Javascript
vuejs实现ready函数加载完之后执行某个函数的方法
2018/08/31 Javascript
浅谈VUE-CLI脚手架热更新太慢的原因和解决方法
2018/09/28 Javascript
浅谈Vue.js 中的 v-on 事件指令的使用
2018/11/25 Javascript
Layui Form 自定义验证的实例代码
2019/09/14 Javascript
[59:08]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第一局
2016/02/27 DOTA
python数据结构之链表详解
2017/09/12 Python
python paramiko利用sftp上传目录到远程的实例
2019/01/03 Python
Pycharm 设置默认头的图文教程
2019/01/17 Python
Schutz鞋官方网站:Schutz Shoes
2017/12/13 全球购物
哄娃神器4moms商店:美国婴童用品品牌
2019/03/07 全球购物
英国手工制作的现代与经典的沙发和床:Love Your Home
2020/09/26 全球购物
客服服务心得体会
2013/12/30 职场文书
我有一个梦想演讲稿
2014/05/05 职场文书
优秀少先队工作者事迹材料
2014/05/13 职场文书
商场促销活动总结
2014/07/10 职场文书
2015年化工厂工作总结
2015/05/04 职场文书
CSS3实现三角形不断放大效果
2021/04/13 HTML / CSS
MYSQL(电话号码,身份证)数据脱敏的实现
2021/05/28 MySQL
HTML CSS 一个标签实现带动画的抖音LOGO
2022/04/26 HTML / CSS
一文了解Java动态代理的原理及实现
2022/07/07 Java/Android