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 相关文章推荐
JavaScript QueryString解析类代码
Jan 17 Javascript
js下获得客户端操作系统的函数代码(1:vista,2:windows7,3:2000,4:xp,5:2003,6:2008)
Oct 31 Javascript
jQuery实现3D文字特效的方法
Mar 10 Javascript
详解webpack进阶之loader篇
Aug 23 Javascript
JavaScript判断变量名是否存在数组中的实例
Dec 28 Javascript
使用淘宝镜像cnpm安装Vue.js的图文教程
May 17 Javascript
vue单文件组件lint error自动fix与styleLint报错自动fix详解
Jan 08 Javascript
小程序获取当前位置加搜索附近热门小区及商区的方法
Apr 08 Javascript
JS设置自定义快捷键并实现图片上下左右移动
Oct 17 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
Jul 20 Javascript
记一次vue跨域的解决
Oct 21 Javascript
Vue实现简单的留言板
Oct 23 Javascript
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
使用sockets:从新闻组中获取文章(二)
2006/10/09 PHP
php include加载文件两种方式效率比较
2010/08/08 PHP
php中用date函数获取当前时间有误的解决办法
2013/08/02 PHP
php的array数组和使用实例简明教程(容易理解)
2014/03/20 PHP
PHP register_shutdown_function()函数的使用示例
2015/06/23 PHP
WordPress后台中实现图片上传功能的实例讲解
2016/01/11 PHP
更优雅的事件触发兼容
2011/10/24 Javascript
JavaScript实现非常简单实用的下拉菜单效果
2015/08/27 Javascript
jquery通过扩展select控件实现支持enter或focus选择的方法
2015/11/19 Javascript
js实现(全选)多选按钮的方法【附实例】
2016/03/30 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
2016/06/06 Javascript
javascript事件捕获机制【深入分析IE和DOM中的事件模型】
2016/12/15 Javascript
JavaScript数组去重的6个方法
2017/01/21 Javascript
微信小程序 swiper组件构建轮播图的实例
2017/09/20 Javascript
js阻止默认右键的下拉菜单方法
2018/01/02 Javascript
js实现图片局部放大效果详解
2019/03/18 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
2020/12/09 Javascript
[02:40]DOTA2殁境神蚀者 英雄基础教程
2013/11/26 DOTA
深入理解Python中变量赋值的问题
2017/01/12 Python
Flask框架踩坑之ajax跨域请求实现
2019/02/22 Python
python实现植物大战僵尸游戏实例代码
2019/06/10 Python
python单线程下实现多个socket并发过程详解
2019/07/27 Python
python实现图书馆抢座(自动预约)功能的示例代码
2020/09/29 Python
python em算法的实现
2020/10/03 Python
使用Python实现NBA球员数据查询小程序功能
2020/11/09 Python
html5 音乐播放器 audio 标签使用概述
2013/07/15 HTML / CSS
Martinelli官方商店:西班牙皮鞋和高跟鞋品牌
2019/07/30 全球购物
介绍一下Ruby中的对象,属性和方法
2012/07/11 面试题
环保专业大学生职业规划设计
2014/01/10 职场文书
实习证明格式范文
2014/10/14 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
教师节主题班会教案
2015/08/17 职场文书
同学会演讲稿
2019/04/02 职场文书
公司致全体员工的感谢信
2019/06/24 职场文书
六年级情感作文之500字
2019/10/23 职场文书
微信小程序APP的生命周期及页面的生命周期
2022/04/19 Javascript