zoukankan      html  css  js  c++  java
  • 原生js之canvas时钟组件

    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以及弧度的计算方法,又重温了一把当年学数学时的许多乐趣,可谓是一举两得。

    时钟效果图如下:

  • 相关阅读:
    SQL Server, Timeout expired.all pooled connections were in use and max pool size was reached
    javascript 事件调用顺序
    Best Practices for Speeding Up Your Web Site
    C语言程序设计 使用VC6绿色版
    破解SQL Prompt 3.9的几步操作
    Master page Path (MasterPage 路径)
    几个小型数据库的比较
    CSS+DIV 完美实现垂直居中的方法
    由Response.Redirect引发的"Thread was being aborted. "异常的处理方法
    Adsutil.vbs 在脚本攻击中的妙用
  • 原文地址:https://www.cnblogs.com/tnnyang/p/8951804.html
Copyright © 2011-2022 走看看