小任务之Canvas绘制时钟
背景图的绘制(大圆、数字、小圆点)
掌握基础知识:圆的绘制(arc方法),关于圆的弧度的计算,数学中关于sin cos
的用法
圆的弧度为2*math.pi
12个数字分得弧度每个为2*math.pi/12
那么rad=i*2*math.pi/12
x=math.cos(rad)*所需要的长度(也就是半径-差值)
y=math.sin(rad)*所需要的长度(也就是半径-差值)
同理可得60个点的绘制
60个数字分得弧度每个rad=i*2*math.pi/60
x=math.cos(rad)*所需要的长度(也就是半径-差值)
y=math.sin(rad)*所需要的长度(也就是半径-差值)
1 <!doctype html> 2 <html> 3 4 <head> 5 <meta charset="utf-8" /> 6 7 <title>canvas练习</title> 8 9 </head> 10 11 <body> 12 <canvas id="prac" width="500" height="500" style="border:1px solid black"></canvas> 13 <canvas id="clock" width="500" height="500" style="border:1px solid black"></canvas> 14 <script> 15 var prac = document.queryselector("#prac"); 16 var test = prac.getcontext("2d"); 17 test.moveto(20, 25); //起点,但是绘制 18 test.lineto(200, 25); //终点 19 test.stroke(); //绘制路径 20 21 test.beginpath(); 22 test.linewidth = "10"; 23 test.rect(200, 200, 50, 50); 24 test.stroke(); 25 26 test.beginpath(); 27 test.rect(260, 200, 50, 50); 28 test.fill(); 29 30 test.fillstyle = "rgb(200,0,0)"; 31 test.linewidth = "10"; //带填充的,画线粗细无作用 32 test.fillrect(100, 100, 55, 50); //带填充的矩形 33 34 test.strokestyle = "blue"; 35 test.linewidth = "1"; 36 test.strokerect(85, 85, 100, 150); //不带填充的矩形 37 38 test.beginpath(); 39 test.arc(100, 295, 15, 0, 2 * math.pi); //圆心坐标+半径+起始角和结束角; 40 test.stroke(); 41 42 test.beginpath(); 43 test.arc(150, 295, 15, 0, 2 * math.pi); //圆心坐标+半径+起始角和结束角; 44 test.fill(); 45 46 test.font = "20px arial"; 47 test.textalign = "center"; 48 test.filltext("hello world", 400, 200); 49 test.textalign = "center"; 50 test.textbaseline = "hanging"; 51 test.filltext("hello world", 400, 200); 52 53 //以下为时钟部分 54 var clock = document.getelementbyid("clock"); 55 var ctx = clock.getcontext("2d"); 56 var width = clock.width; 57 var height = clock.height; 58 var radius = width / 2; //半径 59 var rem = width / 200; //画面比例 60 61 function drawbg() { 62 ctx.save(); //保存当前环境 63 ctx.translate(width / 2, height / 2);//转换原点为中心 64 ctx.beginpath(); 65 ctx.linewidth = 8 * rem; 66 //以0,0为原点,r为半径,0为起始角,2*math.pi为结束角,顺时针画圆 67 ctx.arc(0, 0, radius - ctx.linewidth / 2, 0, 2 * math.pi, false); 68 ctx.closepath(); 69 ctx.stroke(); 70 71 var hournumber = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]; 72 //画出1-12的数字 73 hournumber.foreach(function (number, i) { 74 var rad = 2 * math.pi / 12 * i; 75 var x = math.cos(rad) * (radius - 35 * rem); 76 var y = math.sin(rad) * (radius - 35 * rem); 77 ctx.font = 20 * rem + "px arial"; //拼接字符串 78 ctx.textalign = "center"; 79 ctx.textbaseline = "middle"; 80 ctx.filltext(number, x, y); 81 }) 82 //画出秒针走动的60个点 83 for (let i = 0; i < 60; i++) { 84 var rad = 2 * math.pi / 60 * i; 85 var x = math.cos(rad) * (radius - 18 * rem); 86 var y = math.sin(rad) * (radius - 18 * rem); 87 ctx.beginpath(); 88 if (i % 5 === 0) { 89 ctx.fillstyle = "#000"; 90 ctx.arc(x, y, 3 * rem, 0, 2 * math.pi); 91 } else { 92 ctx.fillstyle = "#ccc"; 93 ctx.arc(x, y, 3 * rem, 0, 2 * math.pi); 94 } 95 ctx.fill(); 96 } 97 98 99 } 100 //绘制时针 101 function drawhour(hour, minute) { 102 ctx.save(); 103 ctx.beginpath(); 104 var rad = 2 * math.pi / 12 * hour; 105 var mrad = 2 * math.pi / 12 / 60 * minute; //分60等份弧度 106 ctx.rotate(rad + mrad); //时针特殊性+上对应每分钟占的时钟刻度 107 ctx.moveto(0, 10 * rem); 108 ctx.linewidth = 6 * rem; 109 ctx.linecap = "round"; 110 ctx.lineto(0, -radius / 2); 111 ctx.stroke(); 112 ctx.restore(); 113 } 114 //绘制分针 115 function drawminute(minute) { 116 ctx.save(); 117 ctx.beginpath(); 118 var rad = 2 * math.pi / 60 * minute; 119 ctx.rotate(rad); 120 ctx.moveto(0, 10 * rem); 121 ctx.linewidth = 3 * rem; 122 ctx.linecap = "round"; 123 ctx.lineto(0, -radius + 45 * rem); 124 ctx.stroke(); 125 ctx.restore(); 126 } 127 //绘制秒针 128 function drawsecond(second) { 129 ctx.save(); 130 ctx.beginpath(); 131 var rad = 2 * math.pi / 60 * second; 132 ctx.rotate(rad); 133 ctx.moveto(-2 * rem, 20 * rem); 134 ctx.lineto(2 * rem, 20 * rem); 135 ctx.lineto(1 * rem, -radius + 18 * rem); 136 ctx.lineto(-1 * rem, -radius + 18 * rem); 137 ctx.fillstyle = "red"; 138 ctx.fill(); 139 ctx.restore(); 140 } 141 //画时钟上的中心白色原点 142 function drawdot() { 143 ctx.beginpath(); 144 ctx.arc(0, 0, 2 * rem, 0, 2 * math.pi, false); 145 ctx.fillstyle = "white"; 146 ctx.fill(); 147 } 148 149 //绘制整体函数 150 function draw() { 151 ctx.clearrect(0, 0, width, height); //清空画布 152 var now = new date();//获取时间 153 var hour = now.gethours(); 154 var minute = now.getminutes(); 155 var second = now.getseconds(); 156 console.log(hour, minute, second); 157 drawbg(); 158 drawhour(hour, minute); 159 drawminute(minute); 160 drawsecond(second); 161 drawdot(); 162 ctx.restore(); //清除,起始坐标回到0,0 163 } 164 draw();//提前先画一次,避免空白 165 setinterval(draw, 1000); //每秒执行一次 166 </script> 167 </body> 168 169 </html>
注意点:
1.rem=width/200(基准值)
所需要的像素换算=x*rem
2.canvas的字体设置可以用拼接字符串来动态根据rem修改大小:
ctx.font = 20 * rem + "px arial"; //拼接字符串
3.为了使文字填充为该坐标中心, 那么利用文字对齐方式调整至中心位置
ctx.textalign = "center"; ctx.textbaseline = "middle";
4.记得保存和重置,因为清除画布(不清除画布,画面会重叠)需要把坐标移动至左上角原始位置,所以本来我们画背景的时候将画布原点移致画布中心,所以要ctx.restore()
5.moveto和lineto都是不绘制的,最后得stroke(),或者fill()
6.由于时针的特殊性,所以要加上分钟走过的弧度来确定指针指向的位置
var rad = 2 * math.pi / 12 * hour; var mrad = 2 * math.pi / 12 / 60 * minute; //分60等份弧度 ctx.rotate(rad + mrad); //时针特殊性+上对应每分钟占的时钟刻度
7.时分秒针以及中心原点的绘制,其中时针和分针就是绘制一个直线即可,秒针则画一个梯形样式呈现又粗到细的效果,要掌握的基础知识:直线的绘制,旋转角度的控制(rotate以弧度为单位),时钟的动态走动效果,则用setinterval
函数控制每一秒钟执行一次绘制时钟的函数。
上一篇: 判断NaN的真假
下一篇: 神经网络相关之基础概念的讲解