一步一步教你用Html5的Canvas绘制钟表
【摘要】 本博文一步一步教你用Html5的Canvas绘制一个钟表
1、表盘绘制
1.1、基础样式代码
定义body背景色为粉色,在body中定义一个800*800的灰色画布,clock.css文件内容如下。
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
overflow: hidden;
background: pink;
}
#clock {
background: gray;
position: absolute;
left: 50%;
top: 50%;
transform: translate3d(-50%, -50%, 0);
}
1.2、基础Html代码
clock.html代码结构如下。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="clock.css">
</head>
<body>
<canvas id="clock" width="800" height="800"></canvas>
</body>
<script type="text/javascript">
window.onload = function () {
// 获取画布元素
var clock = document.querySelector("#clock");
// 如果画笔存在
if (clock.getContext) {
// 获取画笔
var ctx = clock.getContext("2d");
}
}
</script>
</html>
效果如图:
1.3、定义表盘画笔通用样式
// 保存样式
ctx.save();
// 定义基本样式
// 定义基本线宽为10
ctx.lineWidth = 10;
// 定义线的颜色为黑色
ctx.strokeStyle = "black";
// 定义线段末端以圆形结束
ctx.lineCap = "round";
// 将原点移动到400, 400的位置
ctx.translate(400, 400);
// 逆时针旋转90度
ctx.rotate(-90 * Math.PI / 180);
ctx.beginPath();
ctx.restore();
1.4、绘制外层空心表盘
表盘参数:
- 圆盘颜色:#325FA2
- 圆盘宽度:20
- 圆盘半径:280
// 绘制外层空心表盘
ctx.save();
// 定义外层空心表盘颜色
ctx.strokeStyle = "#325FA2";
// 定义线宽为20
ctx.lineWidth = 20;
// 重置画笔路径
ctx.beginPath();
// 绘制半径为280的圆形表盘
ctx.arc(0, 0, 280, 0, 360 * Math.PI / 180);
ctx.stroke();
ctx.restore();
效果如图:
1.5、绘制时针刻度
时针刻度参数:
- 长度为30
- 宽度为10
- 外层空心圆盘与时针刻度之间的距离也为30
// 绘制时针刻度
ctx.save();
for (var i = 0; i < 12; i++) {
// 绘制12个时针刻度,每30度一个
ctx.rotate(30 * Math.PI / 180);
ctx.beginPath();
// 每个刻度从220 绘制到 250
ctx.moveTo(220, 0)
ctx.lineTo(250, 0);
ctx.stroke();
}
ctx.restore();
效果如图:
1.5、绘制分针刻度
分针刻度参数:
- 长度为10
- 宽度为5
// 绘制分针刻度
ctx.save();
ctx.lineWidth = 5;
for (var i = 0; i < 60; i++) {
// 绘制48个分针刻度,每6度一个
ctx.rotate(6 * Math.PI / 180);
// 如果是时针位置,则不绘制
if ((i + 1) % 5 !== 0) {
ctx.beginPath();
ctx.moveTo(240, 0)
ctx.lineTo(250, 0);
ctx.stroke();
}
}
ctx.restore();
效果如图:
2、表针绘制
2.1、获取系统时间时分秒的值
// 获取系统时间的时分秒的值
var date = new Date();
// 获取系统时间的秒的值
var s = date.getSeconds();
// 获取系统时间的分钟的值
var m = date.getMinutes() + s / 60;
// 获取系统时间的小时的值
var h = date.getHours() + m / 60;
// 如果小时超过12则剪掉12,采用12小时制
h = h > 12 ? h - 12 : h;
2.2、绘制时针
时针参数:
- 宽度为30
- 头部离圆心180,尾部离圆心40
// 绘制时针
ctx.save()
// 定义线宽为30
ctx.lineWidth = 30;
// 绘制时针旋转位置
ctx.rotate(h * 30 * Math.PI / 180)
ctx.beginPath()
// 绘制时针线
ctx.moveTo(-40, 0);
ctx.lineTo(180, 0);
ctx.stroke();
ctx.restore()
效果如图:
2.3、绘制分针
分针参数:
- 宽度为20
- 头部离圆心220,尾部离圆心60
// 绘制分针
ctx.save()
// 定义线宽为20
ctx.lineWidth = 20;
// 绘制分针旋转位置
ctx.rotate(m * 6 * Math.PI / 180)
ctx.beginPath()
ctx.moveTo(-60, 0);
ctx.lineTo(220, 0);
ctx.stroke();
ctx.restore()
效果如图:
2.4、绘制秒针
秒针参数:
- 颜色:D40000
- 宽度为10
- 头部离圆心200,尾部离圆心70
- 中心实心圆盘半径为20
- 秒针头从215开始绘制半径为15、宽度为10的空心圆
// 绘制秒针
ctx.save();
// 定义线宽为10
ctx.lineWidth = 10;
// 定义秒针颜色及填充颜色为D40000
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
// 绘制秒针旋转位置
ctx.rotate(s * 6 * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(-70, 0);
ctx.lineTo(200, 0);
ctx.stroke();
// 绘制表座
ctx.beginPath();
ctx.arc(0, 0, 20, 0, 360 * Math.PI / 180);
ctx.fill();
// 绘制秒头
ctx.beginPath();
ctx.arc(215, 0, 15, 0, 360 * Math.PI / 180);
ctx.stroke();
ctx.restore()
效果如图:
3、让钟表动起来
3.1、将表盘及表针绘制内容封装成一个函数move
function move() {
// 保存样式
ctx.save();
// 定义基本样式
// 定义基本线宽为10
ctx.lineWidth = 10;
// 定义线的颜色为黑色
ctx.strokeStyle = "black";
// 定义线段末端以圆形结束
ctx.lineCap = "round";
// 将原点移动到400, 400的位置
ctx.translate(400, 400);
// 逆时针旋转90度
ctx.rotate(-90 * Math.PI / 180);
ctx.beginPath();
// 绘制外层空心表盘
ctx.save();
// 定义外层空心表盘颜色
ctx.strokeStyle = "#325FA2";
// 定义线宽为20
ctx.lineWidth = 20;
// 重置画笔路径
ctx.beginPath();
// 绘制圆形表盘
ctx.arc(0, 0, 280, 0, 360 * Math.PI / 180);
ctx.stroke();
ctx.restore();
// 绘制时针刻度
ctx.save();
for (var i = 0; i < 12; i++) {
// 绘制12个时针刻度,每30度一个
ctx.rotate(30 * Math.PI / 180);
ctx.beginPath();
// 每个刻度从220 绘制到 250
ctx.moveTo(220, 0)
ctx.lineTo(250, 0);
ctx.stroke();
}
ctx.restore();
// 绘制分针刻度
ctx.save();
ctx.lineWidth = 5;
for (var i = 0; i < 60; i++) {
// 绘制48个分针刻度,每6度一个
ctx.rotate(6 * Math.PI / 180);
// 如果是时针位置,则不绘制
if ((i + 1) % 5 !== 0) {
ctx.beginPath();
ctx.moveTo(240, 0)
ctx.lineTo(250, 0);
ctx.stroke();
}
}
ctx.restore();
// 获取系统时间的时分秒的值
var date = new Date();
// 获取系统时间的秒的值
var s = date.getSeconds();
// 获取系统时间的分钟的值
var m = date.getMinutes() + s / 60;
// 获取系统时间的小时的值
var h = date.getHours() + m / 60;
// 如果小时超过12则剪掉12,采用12小时制
h = h > 12 ? h - 12 : h;
// 绘制时针
ctx.save();
// 定义线宽为30
ctx.lineWidth = 30;
// 绘制时针旋转位置
ctx.rotate(h * 30 * Math.PI / 180);
ctx.beginPath();
// 绘制时针线
ctx.moveTo(-40, 0);
ctx.lineTo(180, 0);
ctx.stroke();
ctx.restore();
// 绘制分针
ctx.save();
// 定义线宽为20
ctx.lineWidth = 20;
// 绘制分针旋转位置
ctx.rotate(m * 6 * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(-60, 0);
ctx.lineTo(220, 0);
ctx.stroke();
ctx.restore();
// 绘制秒针
ctx.save();
// 定义线宽为10
ctx.lineWidth = 10;
// 定义秒针颜色及填充颜色为D40000
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
// 绘制秒针旋转位置
ctx.rotate(s * 6 * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(-70, 0);
ctx.lineTo(200, 0);
ctx.stroke();
// 绘制表座
ctx.beginPath();
ctx.arc(0, 0, 20, 0, 360 * Math.PI / 180);
ctx.fill();
// 绘制秒头
ctx.beginPath();
ctx.arc(215, 0, 15, 0, 360 * Math.PI / 180);
ctx.stroke();
ctx.restore()
ctx.restore();
}
3.2、使用计时器让钟表动起来
// 开始先执行一次
move();
// 定时执行,每1秒执行一次
setInterval(function () {
ctx.clearRect(0, 0, clock.width, clock.height);
move();
}, 1000);
4、Html完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="clock.css">
</head>
<body>
<canvas id="clock" width="800" height="800"></canvas>
</body>
<script type="text/javascript">
window.onload = function () {
var clock = document.querySelector("#clock");
if (clock.getContext) {
var ctx = clock.getContext("2d");
//move();
// 定时执行
setInterval(function () {
ctx.clearRect(0, 0, clock.width, clock.height);
move();
}, 1000);
function move() {
// 保存样式
ctx.save();
// 定义基本样式
// 定义基本线宽为10
ctx.lineWidth = 10;
// 定义线的颜色为黑色
ctx.strokeStyle = "black";
// 定义线段末端以圆形结束
ctx.lineCap = "round";
// 将原点移动到400, 400的位置
ctx.translate(400, 400);
// 逆时针旋转90度
ctx.rotate(-90 * Math.PI / 180);
ctx.beginPath();
// 绘制外层空心表盘
ctx.save();
// 定义外层空心表盘颜色
ctx.strokeStyle = "#325FA2";
// 定义线宽为20
ctx.lineWidth = 20;
// 重置画笔路径
ctx.beginPath();
// 绘制圆形表盘
ctx.arc(0, 0, 280, 0, 360 * Math.PI / 180);
ctx.stroke();
ctx.restore();
// 绘制时针刻度
ctx.save();
for (var i = 0; i < 12; i++) {
// 绘制12个时针刻度,每30度一个
ctx.rotate(30 * Math.PI / 180);
ctx.beginPath();
// 每个刻度从220 绘制到 250
ctx.moveTo(220, 0)
ctx.lineTo(250, 0);
ctx.stroke();
}
ctx.restore();
// 绘制分针刻度
ctx.save();
ctx.lineWidth = 5;
for (var i = 0; i < 60; i++) {
// 绘制48个分针刻度,每6度一个
ctx.rotate(6 * Math.PI / 180);
// 如果是时针位置,则不绘制
if ((i + 1) % 5 !== 0) {
ctx.beginPath();
ctx.moveTo(240, 0)
ctx.lineTo(250, 0);
ctx.stroke();
}
}
ctx.restore();
// 获取系统时间的时分秒的值
var date = new Date();
// 获取系统时间的秒的值
var s = date.getSeconds();
// 获取系统时间的分钟的值
var m = date.getMinutes() + s / 60;
// 获取系统时间的小时的值
var h = date.getHours() + m / 60;
// 如果小时超过12则剪掉12,采用12小时制
h = h > 12 ? h - 12 : h;
// 绘制时针
ctx.save();
// 定义线宽为30
ctx.lineWidth = 30;
// 绘制时针旋转位置
ctx.rotate(h * 30 * Math.PI / 180);
ctx.beginPath();
// 绘制时针线
ctx.moveTo(-40, 0);
ctx.lineTo(180, 0);
ctx.stroke();
ctx.restore();
// 绘制分针
ctx.save();
// 定义线宽为20
ctx.lineWidth = 20;
// 绘制分针旋转位置
ctx.rotate(m * 6 * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(-60, 0);
ctx.lineTo(220, 0);
ctx.stroke();
ctx.restore();
// 绘制秒针
ctx.save();
// 定义线宽为10
ctx.lineWidth = 10;
// 定义秒针颜色及填充颜色为D40000
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
// 绘制秒针旋转位置
ctx.rotate(s * 6 * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(-70, 0);
ctx.lineTo(200, 0);
ctx.stroke();
// 绘制表座
ctx.beginPath();
ctx.arc(0, 0, 20, 0, 360 * Math.PI / 180);
ctx.fill();
// 绘制秒头
ctx.beginPath();
ctx.arc(215, 0, 15, 0, 360 * Math.PI / 180);
ctx.stroke();
ctx.restore()
ctx.restore();
}
}
}
</script>
</html>
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)