html5入门:教你用canvas写一个时钟
今天的时间比较充裕,心血来潮,为大家分享一个html5的小例子,希望对刚学html5或者是没学html5正准备学的“童鞋们”展示一个小案例,希望对你们的学习有帮助!高手嘛!请跳过吧!
好了,闲话少数,先看看一下我们的案例效果图吧!
哦哦,我的时间暴露了!效果很粗糙,没有美化,有兴趣的朋友可以写的好看一点!
好了, 这是用什么写的呢,这大家都知道,肯定是html5 的canvas标签和js共同完成的啦,利用canvas的绘图的属性画一个一个的形状,现在就跟我一起画吧!
分析:时钟包括 表盘,小时刻度,分钟刻度,时针,分针,秒针
首先当然是html5声明,声明很简单,就一行:
<!doctype html>
doctype可与的大写,也可以是小写,也可以是大小写,这都无所谓,看你自己的习惯(不区分大小写);头部我就不写了,我会将源码附到下面,为节约时间,我就开始讲正文,头部也没什么好将的
<canvas width="500" height="500" style="background:yellow; margin:50px auto; display:block; " id="clock">
您的浏览器当前版本不支持canvas表签
</canvas>
在body里面写一个canvas标签,设置宽高为500,500(ps:设置宽高时建议按照上面的写法给,不是说在样式表里面不能给,在样式表里面给宽高,在绘图时图形的位置会出错),背景颜色设为黄色;
开始绘图了:
<script>
//获取画布DOM 还不可以操作
var canvas = document.getElementById('canvas');
//设置绘图环境
var cxt = canvas.getContext('2d');
</script>
先获取canvas DOM, 设置绘图环境,目前还只有2d;
(为节省版面,js部分拆分的部分不加script标记了)
画表盘:
//表盘(蓝色)
cxt.beginPath(); //画笔开始
cxt.lineWidth = 5; //设置画笔的线宽
cxt.strokeStyle="blue"; //设置画笔的颜色
cxt.arc(250,250,200,0,360,false); //绘制圆形,坐标250,250 半径200,整圆(0-360度),false表示顺时针
cxt.stroke(); //绘图
cxt.closePath(); //结束画布
写有注释,看得懂不,解释一下,画形状一般都需要写一个开始画笔和结束画布,你自己写一下,看看效果你就知道了,这是画的空心圆,效果是这样的:
然后我们开始画刻度,刻度有小时刻度和分针刻度,先画小时刻度吧:
//时针刻度
for(var i=0; i<12; i++){
cxt.save(); //设置旋转环境
//设置时针的样式
cxt.lineWidth=7;
cxt.strokeStyle="#000"; cxt.translate(250,250);//设置异次元空间的原点 cxt.rotate(30*Math.PI/180);//设置旋转角度
cxt.beginPath(); //画笔开始
cxt.moveTo(0,-170); //画线, 从坐标0,-170开始
cxt.lineTo(0,-190); //到坐标0,-190结束
cxt.stroke(); //绘图
cxt.closePath();
cxt.restore(); //将旋转之后的元素放回原画布
}
因为小时刻度是要在表盘上旋转分布的,所以我们要设一个中心原点,以原点为中心,表针可以旋转指向某个时刻,当然,刻度不只有一个,所以我们用for循环的方式,画出12条线段,旋转角度说明一下,弧度 = 角度*Math.PI/180,要是你有兴趣,可以查一下这是怎么来的(数学里有),一周有12个刻度,一个刻度就是30°;
效果如图:
画分刻度,原理跟时刻的是一样的,只是角度不一样:
//分针刻度
for(var i=0; i<60;i++){
cxt.save();
cxt.lineWidth=5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-180);
cxt.lineTo(0,-190);
cxt.stroke();
cxt.closePath();
cxt.restore();
}
注释就不写了,跟上面的是一样的
效果如图:
现在开始画指针了,先画时针吧:
//时针
cxt.save(); //设置旋转环境
//时针样式
cxt.lineWidth = 7;
cxt.strokeStyle="#000";
cxt.translate(250,250); //设置异次元空间原点
cxt.rotate(30*Math.PI/180); //设置旋转角度
cxt.beginPath(); //画笔开始
cxt.moveTo(0,-140); //画线, 从坐标0,-140开始
cxt.lineTo(0,10); //到坐标0,10结束
cxt.stroke(); //绘图
cxt.closePath(); //结束画布
cxt.restore(); //将旋转之后的元素放回原画布
时针现在实际上就是画一个直线,因为要旋转,所以是在异次元空间设置原点
效果如图:
那分针和秒针就一样一样的了,稍微给点变化,比如给长一点,指针细一点
//分针
cxt.save();
//分针样式
cxt.lineWidth = 5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-160);
cxt.lineTo(0,15);
cxt.stroke();
cxt.closePath();
cxt.restore();
对照时针看注释,这里就不写注释了
效果如图:
现在写分针:
//秒针
cxt.save();
cxt.lineWidth = 3;
cxt.strokeStyle="#f00";
cxt.translate(250,250);
cxt.rotate(60*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-185);
cxt.lineTo(0,20);
cxt.stroke();
cxt.closePath();
效果如图:
到此为止,这个时钟的图就画出来了,就这样就结束了吗?这么丑,美化一下嘛!好吧,我们把分针稍微点缀一下!
//画出时针,分针,秒针交叉点
cxt.beginPath();
cxt.strokeStyle="#f00";
cxt.arc(0,0,5,0,360,false);
cxt.fillStyle="#fff"; //填充颜色
cxt.fill(); //填充
cxt.stroke();
cxt.closePath(); //秒针装饰
cxt.beginPath();
cxt.strokeStyle="#f00";
cxt.arc(0,-160,5,0,360,false);
cxt.fill(); //填充
cxt.stroke();
cxt.closePath();
cxt.restore();
说明一下:上一段是画的3个指针交叉的地方,给点装饰,见图上,这样显得针是围绕一个点转的,fill()是填充的意思,相当于是画一个实心圆,我们填充的是白色,外面的描边是红色,你可以这么理解,一个空心圆里面填充了一个白色,懂了吧;
下面的是分针指针尖山的一个小装饰,跟前面的是一样的,只是位置不一样,但是这样是不是更加“高端大气上档次”了;
效果如图:
到这里就结束了吗?好像不走耶,好吧,我们让他动起来,动起来首先要知道时间,那我们就获取一下本地的时间:
//获取时间
var now = new Date(); //定义时间
var sec = now.getSeconds(); //获取秒
var minute = now.getMinutes(); //获取分钟
var hour = now.getHours(); //获取小时
//小时必须获取浮点类型,产生偏移(小时+分钟比)
hour = hour + minute/60;
//将24小时转换为12小时
hour=hour>12?hour-12:hour;
为什么要写最后2行呢?解释一下,最后一行是因为本地时间是24小时制,而我们的时钟是12小时,所以我们要转换一下,变成12小时;倒数第二行是,如果不加这行,时针只要没有满一个小时,指针一直指针整数刻度上的,而实际的钟表不是这样的,时针在不是整点的时候会有一点偏移,所以我们加的偏移量就是分针走的比例(大家有兴趣可以试一下不加会是什么效果);
要动起来我们需要用到setInterval()函数,那我们将我们写的代码用一个函数包起来,这样就简洁了,但是不包含开始的2句,我们用drawClock()吧
function drawClock(){
//获取时间
var now = new Date(); //定义时间
var sec = now.getSeconds(); //获取秒
var minute = now.getMinutes(); //获取分钟
var hour = now.getHours(); //获取小时
//小时必须获取浮点类型,产生偏移(小时+分钟比)
hour = hour + minute/60;
//将24小时转换为12小时
hour=hour>12?hour-12:hour; //表盘(蓝色)
cxt.beginPath(); //画笔开始
cxt.lineWidth = 5; //设置画笔的线宽
cxt.strokeStyle="blue"; //设置画笔的颜色
cxt.arc(250,250,200,0,360,false); //绘制圆形,坐标250,250 半径200,整圆(0-360度),false表示顺时针
cxt.stroke(); //绘图
cxt.closePath(); //结束画布
//刻度
//时针刻度
for(var i=0; i<12; i++){
cxt.save();
//设置时针的样式
cxt.lineWidth=7;
cxt.strokeStyle="#000";
//设置异次元空间原点
cxt.translate(250,250);
//设置旋转角度
cxt.rotate(i*30*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-170); //画线, 从坐标0,-170开始
cxt.lineTo(0,-190); //到坐标0,-190结束
cxt.stroke();
cxt.closePath();
cxt.restore();
}
//分针刻度
for(var i=0; i<60;i++){
cxt.save();
cxt.lineWidth=5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(i*6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-180);
cxt.lineTo(0,-190);
cxt.stroke();
cxt.closePath();
cxt.restore();
} //时针
cxt.save();
//时针样式
cxt.lineWidth = 7;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(/*hour**/30*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-140);
cxt.lineTo(0,10);
cxt.stroke();
cxt.closePath();
cxt.restore(); //分针
cxt.save();
//分针样式
cxt.lineWidth = 5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(/*minute**/6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-160);
cxt.lineTo(0,15);
cxt.stroke();
cxt.closePath();
cxt.restore(); //秒针
cxt.save();
cxt.lineWidth = 3;
cxt.strokeStyle="#f00";
cxt.translate(250,250);
cxt.rotate(/*sec**/60*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-185);
cxt.lineTo(0,20);
cxt.stroke();
cxt.closePath(); //画出时针,分针,秒针交叉点
cxt.beginPath();
cxt.strokeStyle="#f00";
cxt.arc(0,0,5,0,360,false);
cxt.fillStyle="#fff"; //填充颜色
cxt.fill(); //填充
cxt.stroke();
cxt.closePath(); //秒针装饰
cxt.beginPath();
cxt.strokeStyle="#f00";
cxt.arc(0,-160,5,0,360,false);
cxt.fill();
cxt.stroke();
cxt.closePath();
cxt.restore();
}
//使用setinterval();让时钟动起来 setInterval(drawClock,1000);
ok,动起来,好,刷新,咦,没有动耶,为什么呢,原来我们的指针都只是定义了一个角度,肯定懂不起来啦,好,我们将我们获取的时间嫁到指针上
//时针
cxt.save();
//时针样式
cxt.lineWidth = 7;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(/*hour**/30*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-140);
cxt.lineTo(0,10);
cxt.stroke();
cxt.closePath(); cxt.restore(); //分针
cxt.save();
//分针样式
cxt.lineWidth = 5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(minute*6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-160);
cxt.lineTo(0,15);
cxt.stroke();
cxt.closePath(); cxt.restore(); //秒针
cxt.save();
cxt.lineWidth = 3;
cxt.strokeStyle="#f00";
cxt.translate(250,250);
cxt.rotate(sec*60*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-185);
cxt.lineTo(0,20);
cxt.stroke();
cxt.closePath();
看各指针旋转角度的变化,不错,被你找到了,那现在应该可以转了吧,看图
如图所示:
哎呀,妈妈呀,这是什么怪物,怎么会这样呢?你的是这样吗?是这样就对了,原因是每一次指针旋转都是画上去的,走一步画一步,就出现了像扇子一样的东西,所以我们要在画图之前清空画布,就是画之前清掉前面画的
cxt.clearRect(0,0,500,500); //清除画布
这个是什么意思呢,实际上是2个坐标,0,0 和 500,500 对应整个画布;
那这样应该就万事大吉了吧,刷新,啧啧,总觉得哪里不对劲,对,好像出来的时候慢了点,要等一会才出来,你的是这样吗,是这样啊,是这样 就对了,因为我们在他动之前让他把表画出来,所以执行setInterval()函数时需要1秒之后才开始画,这就是为什么要等大概1秒针才出现的原因,解决方法,在setInterval()前执行drawClock()函数;
drawClock();
setInterval(drawClock,1000);
到这里,所有的问题就都解决了,你的时钟动了没,现在几点了!
现在我把整个代码附在下面,供大家参考学习:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>canvas时钟</title>
</head>
<body>
<canvas width="500" height="500" style="background:yellow; margin:50px auto; display:block; " id="clock">
您的浏览器当前版本不支持canvas表签
</canvas>
<script>
var clock = document.getElementById("clock");
var cxt = clock.getContext('2d'); function drawClock(){
cxt.clearRect(0,0,500,500); //清除画布
//获取时间
var now = new Date(); //定义时间
var sec = now.getSeconds(); //获取秒
var minute = now.getMinutes(); //获取分钟
var hour = now.getHours(); //获取小时
//小时必须获取浮点类型,产生偏移(小时+分钟比)
hour = hour + minute/60;
//将24小时转换为12小时
hour=hour>12?hour-12:hour; //表盘(蓝色)
cxt.beginPath(); //画笔开始
cxt.lineWidth = 5; //设置画笔的线宽
cxt.strokeStyle="blue"; //设置画笔的颜色
cxt.arc(250,250,200,0,360,false); //绘制圆形,坐标250,250 半径200,整圆(0-360度),false表示顺时针
cxt.stroke(); //绘图
cxt.closePath(); //结束画布
//刻度
//时针刻度
for(var i=0; i<12; i++){
cxt.save();
//设置时针的样式
cxt.lineWidth=7;
cxt.strokeStyle="#000";
//设置异次元空间原点
cxt.translate(250,250);
//设置旋转角度
cxt.rotate(i*30*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-170); //画线, 从坐标0,-170开始
cxt.lineTo(0,-190); //到坐标0,-190结束
cxt.stroke();
cxt.closePath();
cxt.restore();
}
//分针刻度
for(var i=0; i<60;i++){
cxt.save();
cxt.lineWidth=5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(i*6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-180);
cxt.lineTo(0,-190);
cxt.stroke();
cxt.closePath();
cxt.restore();
} //时针
cxt.save();
//时针样式
cxt.lineWidth = 7;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(hour*30*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-140);
cxt.lineTo(0,10);
cxt.stroke();
cxt.closePath(); cxt.restore(); //分针
cxt.save();
//分针样式
cxt.lineWidth = 5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(minute*6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-160);
cxt.lineTo(0,15);
cxt.stroke();
cxt.closePath(); cxt.restore(); //秒针
cxt.save();
cxt.lineWidth = 3;
cxt.strokeStyle="#f00";
cxt.translate(250,250);
cxt.rotate(sec*6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-185);
cxt.lineTo(0,20);
cxt.stroke();
cxt.closePath(); //画出时针,分针,秒针交叉点
cxt.beginPath();
cxt.strokeStyle="#f00";
cxt.arc(0,0,5,0,360,false);
cxt.fillStyle="#fff"; //填充颜色
cxt.fill(); //填充
cxt.stroke();
cxt.closePath(); //秒针装饰
cxt.beginPath();
cxt.strokeStyle="#f00";
cxt.arc(0,-160,5,0,360,false);
cxt.fill();
cxt.stroke();
cxt.closePath();
cxt.restore();
}
//使用setinterval();让时钟动起来
drawClock();
setInterval(drawClock,1000);
</script>
</body>
</html>
希望对大家的学习有帮助!
html5入门:教你用canvas写一个时钟的更多相关文章
- 玩转html5(四)----使用canvas画一个时钟(可以动的哦!)
先给个效果图,我画的比较丑,大家可以自己美化一下, 直接上代码: <!DOCTYPE html> <meta charset="utf-8"> <ht ...
- 手把手教你从零写一个简单的 VUE
本系列是一个教程,下面贴下目录~1.手把手教你从零写一个简单的 VUE2.手把手教你从零写一个简单的 VUE--模板篇 今天给大家带来的是实现一个简单的类似 VUE 一样的前端框架,VUE 框架现在应 ...
- 手把手教你从零写一个简单的 VUE--模板篇
教程目录1.手把手教你从零写一个简单的 VUE2.手把手教你从零写一个简单的 VUE--模板篇 Hello,我又回来了,上一次的文章教会了大家如何书写一个简单 VUE,里面实现了VUE 的数据驱动视图 ...
- 深夜,用canvas画一个时钟
深夜,用canvas画一个时钟 查看demo 这几天准备阿里巴巴的笔试,可以说已经是心力交瘁,自从阿里和蘑菇街的内推被刷掉之后,开始越来越怀疑起自己的能力来,虽然这点打击应该是微不足道的.毕竟校招在刚 ...
- 用Canvas写一个简单的游戏--别踩白块儿
第一次写博客也不知怎么写,反正就按照我自己的想法来吧!怎么说呢?还是不要扯那些多余的话了,直接上正题吧! 第一次用canvas写游戏,所以挑个简单实现点的来干:别踩白块儿,其他那些怎么操作的那些就不用 ...
- JS入门学习,写一个时钟~
<!-- 耽搁了几天,于是又继续回到JS的学习了~~ 各种头大,加油吧... --> <!doctype html><html><head> <t ...
- 利用canvas写一个验证码小功能
刚刚开始接触canvas,写个验证码小功能练练手,实现效果图如下: 主要代码如下: html <!DOCTYPE html> <html lang="en"> ...
- 用HTML5的canvas做一个时钟
对于H5来说,canvas可以说是它最有特色的一个地方了,有了它之后我们可以随意的在网页上画各种各样的图形,做一些小游戏啊什么的.canvas这个标签的用法,在网上也有特别多的教程了,这里就不作介绍了 ...
- 教你用Vue写一个开心消消乐
之前做过一个算法题,算法要求就是写一个开心消消乐的逻辑算法,当时也是考虑了一段时间才做出来.后来想了想,既然核心算法都有了,能不能实现一个开心消消乐的小游戏呢,于是花了两天时间做了一个小游戏出来. 效 ...
随机推荐
- 获取列表菜单的选项值与选项以后的VALUE
<html> <body> <select id="izan" name="" onchange='izzzz()'> &l ...
- jdk1.8.0环境变量设置
jdk1.8.0环境变量设置 1.jdk安装完毕 打开如下链接:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloa ...
- js的arguments到底是什么?
类数组对象:arguments 总所周知,js是一门相当灵活的语言.当我们在js中在调用一个函数的时候,我们经常会给这个函数传递一些参数,js把传入到这个函数的全部参数存储在一个叫做arguments ...
- Appium + Java 测试 [百度地图] APP的一段简单脚本
1. 流程 进入 app ,手动处理前段预处理,程序一直等候到达指定搜索地名页面,填入[南通大学],点击[搜索] 2. Java 脚本 // part 1: 引入需要的包 import io.appi ...
- package-lock.json,我们应该了解
原谅我占2017年12月31日一个坑,后续补上
- navicat 几个 可用的东西
1.常用的 表格 一启动 就进入的某某连接某某数据库某某表 2. 结构 比对(菜单栏 “工具里面”) 3.数据对比 同上 4.保持连接 5.全局查询 在工具中查找 ------在数据库或模式中查找
- WEB站点服务器安全配置
WEB站点服务器安全配置 本文转自:i春秋社区 // 概述 // 熟悉网站程序 // 更改默认设置的必要性 // 目录分析与权限设置技巧 // 防止攻击其他要素 // 公司官网不可忽视的安全性 ...
- Javascript对象Oject的强制类型转换
众所周知Javascript作为一种动态类型,弱类型的脚本语言其数据类型在很多时候都会发生类型转换.而这些类型转换往往都是隐式的,这让我们在使用Js的时候会产生许多麻烦.而Js的基础数据类型的转换在此 ...
- 简单读!spring-mvc源码之穿越http请求
相信spring-mvc这种被玩坏了的架构理念,大家都烂熟于胸了,不过还是想来扒一扒他的细节. 一个http请求,怎么样被 spring 接收,又怎样做出响应呢? 一般地,我们会配置一个 web.xm ...
- php--include 、require
一.include .require 定义:包含并运行指定文件 问题:查询了这两个语言结构的资料,有人说,什么require 先执行,什么include后执行. 思考:我觉得官方文档已经解释的很清楚 ...