Canvas学习之绘制时钟
2017-09-22 16:25
274 查看
Canvas官方API网址:http://www.w3school.com.cn/tags/html_ref_canvas.asp
效果图:
笔记:
@fillStyle 只能与fill()方法一起使用,
@strokeStyle 与stroke()一起使用;
@fill()方法时用来填充画布的,而stroke()是用来绘制线条的;
@drawHour()这些带有旋转角度(rotate())的情况,画线的时候要以无旋转先画出来,再在此基础上添加旋转角;
@save()和 restore() 一般是成对出现的,restore会去寻找没有被restore过的最近的save状态
可以用window.setInterval(), window.setTimeout(),和window.requestAnimationFrame()来设定定期执行一个指定函数。
@setInterval(function, delay)
当设定好间隔时间后,function会定期执行。
@setTimeout(function, delay)
在设定好的时间之后执行函数
@requestAnimationFrame(callback)
告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。
如果你并不需要与用户互动,你可以使用setInterval()方法,它就可以定期执行指定代码。如果我们需要做一个游戏,我们可以使用键盘或者鼠标事件配合上setTimeout()方法来实现。通过设置事件监听,我们可以捕捉用户的交互,并执行相应的动作。
下面的例子,采用 window.requestAnimationFrame()实现动画效果。这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行60次,也有可能会被降低。
原生代码实现:
在Vue工程中可以采用以下代码实现:
本文时钟绘制根据慕课网canvas教程学习时间,做了部分小修改,以及更多的注释,后自己放在vue工程中做了修改测试,希望对大家理解学习Canvas有所帮助!
效果图:
笔记:
@fillStyle 只能与fill()方法一起使用,
@strokeStyle 与stroke()一起使用;
@fill()方法时用来填充画布的,而stroke()是用来绘制线条的;
@drawHour()这些带有旋转角度(rotate())的情况,画线的时候要以无旋转先画出来,再在此基础上添加旋转角;
@save()和 restore() 一般是成对出现的,restore会去寻找没有被restore过的最近的save状态
可以用window.setInterval(), window.setTimeout(),和window.requestAnimationFrame()来设定定期执行一个指定函数。
@setInterval(function, delay)
当设定好间隔时间后,function会定期执行。
@setTimeout(function, delay)
在设定好的时间之后执行函数
@requestAnimationFrame(callback)
告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。
如果你并不需要与用户互动,你可以使用setInterval()方法,它就可以定期执行指定代码。如果我们需要做一个游戏,我们可以使用键盘或者鼠标事件配合上setTimeout()方法来实现。通过设置事件监听,我们可以捕捉用户的交互,并执行相应的动作。
下面的例子,采用 window.requestAnimationFrame()实现动画效果。这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行60次,也有可能会被降低。
原生代码实现:
<!DOCTYPE HTML> <html> <body> <canvas id="clock1" width="200" height="200" style="border:1px solid #c3c3c3;"> Your browser does not support the canvas element. </canvas> <script type="text/javascript"> let dom = document.getElementById('clock1'); let ctx = dom.getContext('2d'); let width = ctx.canvas.width; let height = ctx.canvas.height; let r = width / 2; let rem=width/200; //比例像素大小 function drawBackground(){ ctx.save(); //保存当前环境的状态,此处保存了最初原点位置 /*画圆圈*/ ctx.translate(r,r); //重设原点,使其在原来基础上在x,y两个方向均偏移r的长度 ctx.beginPath(); //起始一条路径,或重置当前路径 ctx.lineWidth = 10 * rem; ctx.arc(0,0,r-ctx.lineWidth/2,0,2*Math.PI,false); //画圆:.arc(x,y,r,起始角,结束角,顺时针false/逆时针true) ctx.stroke(); // "绘制"已定义的路径 /*刻数字*/ ctx.font = 18* rem+'px Arial'; //设置或返回文本内容的当前字体属性 ctx.textAlign = 'center'; //设置或返回文本内容的当前对齐方式 ctx.textBaseline = 'middle'; //设置或返回在绘制文本时使用的当前文本基线 let hours = [3,4,5,6,7,8,9,10,11,12,1,2]; hours.forEach(function(ele,i){ var rad = 2*Math.PI / 12 *i; let x = Math.cos(rad) * (r-30* rem); let y = Math.sin(rad) * (r-30* rem); ctx.fillText(ele,x,y); //在画布上绘制“被填充的”文本,位置(x,y):.fillText(文本内容,x,y,允许的最大文本宽度,以像素计.可选); }) /*画刻度点*/ for(let i=0;i<60;i++){ let rad = 2*Math.PI / 60 * i; let x = Math.cos(rad) * (r-18* rem); //r-18是为了把点画在圈内18px位置 let y = Math.sin(rad) * (r-18* rem); ctx.beginPath(); if(i % 5 === 0){ ctx.fillStyle = '#000'; ctx.arc(x,y,2* rem,0,2*Math.PI,false) }else{ ctx.fillStyle = '#ccc'; ctx.arc(x,y,2* rem,0,2*Math.PI,false) } ctx.fill(); // "填充"当前绘图 } } function drawHour(hour,minute){ ctx.save(); ctx.beginPath(); let rad = 2 *Math.PI / 12 * hour; var mrad = 2*Math.PI/12/60*minute; ctx.rotate(rad + mrad); //旋转当前绘图,参数为旋转角弧度 ctx.lineWidth = 5* rem; ctx.lineCap = 'round'; //设置或返回线条的结束端点样式 ctx.moveTo(0,10* rem); ctx.lineTo(0,-r/2); ////添加一个新点坐标,然后在画布中创建从该点到最后lineTo指定点的线条 ctx.stroke(); ctx.restore(); } function drawMinute(minute){ ctx.save(); ctx.beginPath(); let rad = 2 *Math.PI / 60 * minute; ctx.rotate(rad); ctx.lineWidth = 3* rem; ctx.lineCap = 'round'; ctx.moveTo(0,15* rem); ctx.lineTo(0,-r/2-10* rem); ctx.stroke(); ctx.restore(); } /*画秒针:秒针不是一条线而是一个尖三角形,先lineTo三角形的三个点然后fill()填充*/ function drawSec(sec) { ctx.save(); // ctx.translate(r,r); ctx.beginPath(); ctx.fillStyle='#c14543'; var rad=2*Math.PI/60*sec;//定义每秒旋转的弧度 ctx.rotate(rad); ctx.moveTo(-2*rem,20*rem); // 把路径移动到画布中的指定点,不创建线条,会作为后面创建线条的起始点 ctx.lineTo(2*rem,20*rem); //添加一个新点,然后在画布中创建从该点到最后lineTo指定点的线条 ctx.lineTo(0,-r+18*rem); ctx.lineTo(-2*rem,20*rem); ctx.fill(); ctx.restore(); } /*画中心固定点*/ function drawDot(){ ctx.beginPath(); ctx.fillStyle = 'green'; ctx.arc(0,0,3* rem,0,2*Math.PI,false); ctx.fill(); } function draw(){ ctx.clearRect(0,0,width,height); //清除矩形画布,后面开始重新画圆 drawBackground(); drawDot(); let now = new Date(); let hour = now.getHours(); let munite = now.getMinutes(); let sec = now.getSeconds(); drawHour(hour,munite); drawMinute(munite); drawSec(sec); ctx.restore(); //返回之前保存过的路径状态和属性,此处返回drawBackground()开始保存到的空画布状态 /*采用 window.requestAnimationFrame()实现动画效果。这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行60次,也有可能会被降低*/ window.requestAnimationFrame(draw); } draw(); window.requestAnimationFrame(draw); /*此处要么一个setInterval,要么两个requestAnimationFrame,都可以短时间刷新*/ // setInterval(draw, 1000); </script> <!-- fillStyle 只能与fill()方法一起使用, strokeStyle 与stroke()一起使用; fill()方法时用来填充画布的,而stroke()是用来绘制线条的; drawHour()这些带有旋转角度(rotate())的情况,画线的时候要以无旋转先画出来,再在此基础上添加旋转角; save()和 restore() 一般是成对出现的,restore会去寻找没有被restore过的最近的save状态--> </body> </html>
在Vue工程中可以采用以下代码实现:
<template> <div class="clock"> <canvas id="clock1" width="200" height="200" style="border:1px solid #c3c3c3;"> Your browser does not support the canvas element. </canvas> </div> </template> <script> export default{ data(){ return{ } }, mounted:function(){ this.dom = document.getElementById('clock1'); this.ctx = this.dom.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.draw(); setInterval(this.draw, 1000); }, methods:{ drawBackground:function(){ this.ctx.save(); //保存当前环境的状态,此处保存了最初原点位置 /*画圆圈*/ this.ctx.translate(this.r,this.r); //重设原点,使其在原来基础上在x,y两个方向均偏移r的长度 this.ctx.beginPath(); //起始一条路径,或重置当前路径 this.ctx.lineWidth = 10 * this.rem; this.ctx.arc(0,0,this.r-this.ctx.lineWidth/2,0,2*Math.PI,false); //画圆:.arc(x,y,r,起始角,结束角,顺时针false/逆时针true) this.ctx.stroke(); // "绘制"已定义的路径 /*刻数字*/ this.ctx.font = 18* this.rem+'px Arial'; //设置或返回文本内容的当前字体属性 this.ctx.textAlign = 'center'; //设置或返回文本内容的当前对齐方式 this.ctx.textBaseline = 'middle'; //设置或返回在绘制文本时使用的当前文本基线 let hours = [3,4,5,6,7,8,9,10,11,12,1,2]; for(let i=0;i<hours.length;i++){ let rad = 2*Math.PI / 12 *i; let x = Math.cos(rad) * (this.r-30* this.rem); let y = Math.sin(rad) * (this.r-30* this.rem); this.ctx.fillText(hours[i],x,y); //在画布上绘制“被填充的”文本,位置(x,y):.fillText(文本内容,x,y,允许的最大文本宽度,以像素计.可选); } /*hours.forEach(function(ele,i){ let rad = 2*Math.PI / 12 *i; let x = Math.cos(rad) * (this.r-30* this.rem); let y = Math.sin(rad) * (this.r-30* this.rem); this.ctx.fillText(ele,x,y); //在画布上绘制“被填充的”文本,位置(x,y):.fillText(文本内容,x,y,允许的最大文本宽度,以像素计.可选); })*/ /*画刻度点*/ for(let i=0;i<60;i++){ let rad = 2*Math.PI / 60 * i; let x = Math.cos(rad) * (this.r-18* this.rem); //r-18是为了把点画在圈内18px位置 let y = Math.sin(rad) * (this.r-18* this.rem); this.ctx.beginPath(); if(i % 5 === 0){ this.ctx.fillStyle = '#000'; this.ctx.arc(x,y,2* this.rem,0,2*Math.PI,false) }else{ this.ctx.fillStyle = '#ccc'; this.ctx.arc(x,y,2* this.rem,0,2*Math.PI,false) } this.ctx.fill(); // "填充"当前绘图 } }, drawHour:function(hour,minute){ this.ctx.save(); this.ctx.beginPath(); let rad = 2 *Math.PI / 12 * hour; var mrad = 2*Math.PI/12/60*minute; this.ctx.rotate(rad + mrad); //旋转当前绘图,参数为旋转角弧度 this.ctx.lineWidth = 5* this.rem; this.ctx.lineCap = 'round'; //设置或返回线条的结束端点样式 this.ctx.moveTo(0,10* this.rem); this.ctx.lineTo(0,-this.r/2); ////添加一个新点坐标,然后在画布中创建从该点到最后lineTo指定点的线条 this.ctx.stroke(); this.ctx.restore(); }, drawMinute:function(minute){ this.ctx.save(); this.ctx.beginPath(); let rad = 2 *Math.PI / 60 * minute; this.ctx.rotate(rad); this.ctx.lineWidth = 3* this.rem; this.ctx.lineCap = 'round'; this.ctx.moveTo(0,15* this.rem); this.ctx.lineTo(0,-this.r/2-10* this.rem); this.ctx.stroke(); this.ctx.restore(); }, /*画秒针:秒针不是一条线而是一个尖三角形,先lineTo三角形的三个点然后fill()填充*/ drawSec:function(sec) { this.ctx.save(); this.ctx.beginPath(); this.ctx.fillStyle='#c14543'; var rad=2*Math.PI/60*sec;//定义每秒旋转的弧度 this.ctx.rotate(rad); this.ctx.moveTo(-2*this.rem,20*this.rem); // 把路径移动到画布中的指定点,不创建线条,会作为后面创建线条的起始点 this.ctx.lineTo(2*this.rem,20*this.rem); //添加一个新点,然后在画布中创建从该点到最后lineTo指定点的线条 this.ctx.lineTo(0,-this.r+18*this.rem); this.ctx.lineTo(-2*this.rem,20*this.rem); this.ctx.fill(); this.ctx.restore(); }, /*画中心固定点*/ drawDot:function(){ this.ctx.beginPath(); this.ctx.fillStyle = 'green'; this.ctx.arc(0,0,3* this.rem,0,2*Math.PI,false); this.ctx.fill(); }, draw:function(){ this.ctx.clearRect(0,0,this.width,this.height); //清除矩形画布,后面开始重新画圆 this.drawBackground(); this.drawDot(); let now = new Date(); let hour = now.getHours(); let munite = now.getMinutes(); let sec = now.getSeconds(); this.drawHour(hour,munite); this.drawMinute(munite); this.drawSec(sec); this.ctx.restore(); //返回之前保存过的路径状态和属性,此处返回drawBackground()开始保存到的空画布状态 } } } </script>
本文时钟绘制根据慕课网canvas教程学习时间,做了部分小修改,以及更多的注释,后自己放在vue工程中做了修改测试,希望对大家理解学习Canvas有所帮助!
相关文章推荐
- Canvas绘制时钟(学习笔记)
- qml学习--------------利用Canvas绘制简单图形
- canvas自适应圆形时钟绘制
- Canvas学习:绘制矩形
- canvas绘制表盘时钟
- android 用canvas 绘制简单圆形时钟
- html5学习canvas实例之时钟
- JavaScript html5 canvas绘制时钟效果(二)
- 分别利用html+js和canvas绘制时钟
- 【canvas学习笔记四】绘制文字
- HTML5 Canvas 绘制时钟
- Canvas学习:绘制圆和圆弧
- [HTML5 Canvas学习]绘制矩形
- html5 canvas学习--绘制线性渐变
- android 用canvas 绘制简单圆形时钟
- android学习4-25 使用canvas绘制几何图形(在View内)
- 使用canvas绘制动画时钟
- html5学习笔记二:利用canvas绘制简单图形
- HTML5学习笔记14-Canvas绘制渐变图形与绘制变形图形
- html5 canvas学习--绘制径向渐变