1.Canvas画板标签
html结构:
<div id="container">
<canvas id="watch" width="600" height="600"></canvas>
</div>
css部分:
div#container{
width: 600px;
height: 600px;
margin: 150px auto;
border: 1px solid #000;
}
2.JavaScript AIP绘制图形
- 创建Canvas 2D环境
//获取画板
var watch = document.querySelector('#watch');
//创建2D环境
var ctx = watch.getContext('2d');
//设置宽高
var width = ctx.canvas.width;
var height = ctx.canvas.height;
var r = width / 2;
3.绘制表盘最外层圆环
function drawBackground() {
//保存当前图像状态
ctx.save();
//绘制坐标
ctx.translate(r,r);
//创建路径
ctx.beginPath();
//设置外层表盘宽度
ctx.lineWidth = 30;
//设置外层表盘的边框颜色
ctx.strokeStyle = '#ccc';
//设置外层表盘形状为圆形
ctx.arc(0,0,r-15,0,2 * Math.PI,false);
//绘制路径并显示
ctx.stroke();
}
4.绘制表盘背景
ctx.beginPath();
ctx.fillStyle = '#000';
ctx.arc(0, 0, r - 30, 2 * Math.PI, false);
ctx.fill();
5.绘制表盘数字
//创建储存时钟数字的数组
var hourNums = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
//设置数字颜色
ctx.fillStyle = '#fff';
设置数字字体大小
ctx.font = '30px Arial';
//让数字在表盘内对齐居中显示
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
//遍历数组中的数字
for(var i in hourNums) {
var hour = hourNums[i];
var radius = 2 * Math.PI / 12 * i;
var x = Math.cos(radius) * (r - 55);
var y = Math.sin(radius) * (r - 55);
ctx.beginPath();
ctx.fillText(hour, x, y);
}
6.绘制表盘刻度
for(var i = 0; i < 60; i++) {
var radius = 2 * Math.PI / 60 * i;
var x = Math.cos(radius) * (r - 80);
var y = Math.sin(radius) * (r - 80);
ctx.beginPath();
if(i % 5 === 0) {
var round_r = 5;
ctx.fillStyle = '#cc5547';
} else {
var round_r = 3;
ctx.fillStyle = '#999';
}
ctx.arc(x, y, 5, 2 * Math.PI, false);
ctx.fill();
}
7.绘制时钟
function drawHour(hour, minute) {
ctx.save();
ctx.beginPath();
var radius = 2 * Math.PI / 12 * hour;
var m_radius = 2 * Math.PI / 12 / 60 * minute;
ctx.strokeStyle = '#ccc'
ctx.lineCap = 'round';
ctx.lineWidth = 20;
ctx.rotate(radius + m_radius);
ctx.moveTo(0, 40);
ctx.lineTo(0, -r / 2);
ctx.stroke();
ctx.restore();
}
8.绘制分钟
function drawMinute(minute) {
ctx.save();
ctx.beginPath();
var radius = 2 * Math.PI / 60 * minute;
ctx.strokeStyle = '#ccc'
ctx.lineCap = 'round';
ctx.lineWidth = 15;
ctx.rotate(radius);
ctx.moveTo(0, 40);
ctx.lineTo(0, -r + 80);
ctx.stroke();
ctx.restore();
}
9.绘制秒钟
function drawSecond(second){
ctx.save();
ctx.beginPath();
var radius = 2*Math.PI / 60 * second;
ctx.strokeStyle = 'red';
ctx.lineCap = 'round';
ctx.lineWidth = 5;
ctx.rotate(radius);
ctx.moveTo(0,40);
ctx.lineTo(0, -r + 80);
ctx.stroke();
ctx.restore();
}
10.绘制中心定位圆点
function drawCentralRound(){
ctx.save();
ctx.beginPath();
ctx.fillStyle = '#fff';
ctx.arc(0,0,20,0, 2 * Math.PI,false);
ctx.fill();
ctx.restore();
}
11.编写时钟动态方法
function draw() {
ctx.clearRect(0,0,width,height);
var time = new Date();
var hour = time.getHours();
var minute = time.getMinutes();
var second = time.getSeconds();
drawBackground();
drawHour(hour, minute);
drawMinute(minute);
drawSecond(second);
drawCentralRound();
ctx.restore();
}
draw();
setInterval(draw,1000);
完成后的效果如下:
所有的源码如下;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>canvas绘制逼真的机械时钟</title>
<style type="text/css">
div#container {
width: 600px;
height: 600px;
margin: 150px auto;
}
</style>
</head>
<body>
<div id="container">
<canvas id="watch" width="600" height="600"></canvas>
</div>
</body>
<script type="text/javascript">
var watch = document.querySelector('#watch');
var ctx = watch.getContext('2d');
var width = ctx.canvas.width;
var height = ctx.canvas.height;
var r = width / 2;
draw();
setInterval(draw,1000);
function drawBackground() {
//保存当前图像状态
ctx.save();
//绘制坐标
ctx.translate(r, r);
//创建路径
ctx.beginPath();
//设置外层表盘宽度
ctx.lineWidth = 30;
//设置外层表盘的边框颜色
ctx.strokeStyle = '#ccc';
//设置外层表盘形状为圆形
ctx.arc(0, 0, r - 15, 0, 2 * Math.PI, false);
//绘制路径并显示
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = '#000';
ctx.arc(0, 0, r - 30, 2 * Math.PI, false);
ctx.fill();
//创建储存时钟数字的数组
var hourNums = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
//设置数字颜色
ctx.fillStyle = '#fff';
//设置数字字体大小
ctx.font = '30px Arial';
//让数字在表盘内对齐居中显示
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
//遍历数组中的数字
for(var i in hourNums) {
var hour = hourNums[i];
var radius = 2 * Math.PI / 12 * i;
var x = Math.cos(radius) * (r - 55);
var y = Math.sin(radius) * (r - 55);
ctx.beginPath();
ctx.fillText(hour, x, y);
}
for(var i = 0; i < 60; i++) {
var radius = 2 * Math.PI / 60 * i;
var x = Math.cos(radius) * (r - 80);
var y = Math.sin(radius) * (r - 80);
ctx.beginPath();
if(i % 5 === 0) {
var round_r = 5;
ctx.fillStyle = '#cc5547';
} else {
var round_r = 3;
ctx.fillStyle = '#999';
}
ctx.arc(x, y, 5, 2 * Math.PI, false);
ctx.fill();
}
}
function drawHour(hour, minute) {
ctx.save();
ctx.beginPath();
var radius = 2 * Math.PI / 12 * hour;
var m_radius = 2 * Math.PI / 12 / 60 * minute;
ctx.strokeStyle = '#ccc'
ctx.lineCap = 'round';
ctx.lineWidth = 20;
ctx.rotate(radius + m_radius);
ctx.moveTo(0, 40);
ctx.lineTo(0, -r / 2);
ctx.stroke();
ctx.restore();
}
function drawMinute(minute) {
ctx.save();
ctx.beginPath();
var radius = 2 * Math.PI / 60 * minute;
ctx.strokeStyle = '#ccc'
ctx.lineCap = 'round';
ctx.lineWidth = 15;
ctx.rotate(radius);
ctx.moveTo(0, 40);
ctx.lineTo(0, -r + 80);
ctx.stroke();
ctx.restore();
}
function drawSecond(second) {
ctx.save();
ctx.beginPath();
var radius = 2 * Math.PI / 60 * second;
ctx.strokeStyle = 'red';
ctx.lineCap = 'round';
ctx.lineWidth = 5;
ctx.rotate(radius);
ctx.moveTo(0, 40);
ctx.lineTo(0, -r + 80);
ctx.stroke();
ctx.restore();
}
function drawCentralRound() {
ctx.save();
ctx.beginPath();
ctx.fillStyle = '#fff';
ctx.arc(0, 0, 20, 0, 2 * Math.PI, false);
ctx.fill();
ctx.restore();
}
function draw() {
ctx.clearRect(0,0,width,height);
var time = new Date();
var hour = time.getHours();
var minute = time.getMinutes();
var second = time.getSeconds();
drawBackground();
drawHour(hour, minute);
drawMinute(minute);
drawSecond(second);
drawCentralRound();
ctx.restore();
}
</script>
</html>