【前端html/js】使用canvas实现实时时钟
- 代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>飛宇时钟</title>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script type="text/javascript">
"use strict ";
function getDatetime(){
let da = new Date();
let hours = da.getHours();
hours=hours>12?hours-12:hours;
let minute = da.getMinutes();
let second = da.getSeconds();
return [hours,minute,second];
}
</script>
<script type="text/javascript">
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// 绘制刻度函数
function scaleRender(deg,start,end,bw,color){
ctx.beginPath();
ctx.rotate(deg); // 旋转
ctx.moveTo(start,0);
ctx.lineTo(end,0);
ctx.lineWidth=bw;
ctx.strokeStyle=color;
ctx.stroke();
ctx.closePath();
ctx.restore();
ctx.save();
}
function initClockBasicInfo(){
// 圆的中心的 x 坐标,圆的中心的 y 坐标,圆的半径,起始角,以弧度计,结束角,以弧度计。可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针
// ctx.arc(400,300,200,0,2*Math.PI)
ctx.beginPath();
ctx.arc(0,0,200,0,2*Math.PI)
ctx.strokeStyle="darkgrey";
ctx.lineWidth=10;
ctx.stroke();
ctx.closePath();
ctx.restore();
ctx.save();
// 绘制分钟刻度
for(let j=0;j<60;j++){
ctx.rotate(Math.PI/30)
ctx.beginPath();
ctx.moveTo(180,0);
ctx.lineTo(190,0);
ctx.lineWidth = 2;
ctx.strokeStyle="orangered"
ctx.stroke()
ctx.closePath();
}
ctx.restore();
ctx.save();
// 绘制时钟刻度
for(let i=0;i<12;i++){
ctx.rotate(Math.PI/6)
ctx.beginPath();
ctx.moveTo(180,0);
ctx.lineTo(200,0);
ctx.lineWidth = 10;
ctx.strokeStyle="darkgray"
ctx.stroke()
ctx.closePath();
}
ctx.restore();
ctx.save();
// 绘制时钟刻度数字
for(let i=1;i<=12;i++){
ctx.rotate((Math.PI/6));
ctx.save();
ctx.beginPath();
ctx.translate(165,-4);
ctx.rotate(Math.PI/2-(Math.PI/6)*i);
ctx.strokeStyle="skyblue"
// ctx.strokeText((i,150,0)
ctx.fillText(i, 0, 0);
// ctx.stroke();
ctx.closePath();
ctx.restore();
}
ctx.restore();
ctx.save();
}
// 初始化时钟
function initClock(){
ctx.clearRect(0,0,800,600);
ctx.save();
// 将画布移动画布中央
ctx.translate(400,300);
ctx.rotate(-Math.PI/2)
ctx.save();
initClockBasicInfo();
let time = getDatetime();
// 绘制秒针
scaleRender(Math.PI/30*time[2],-30,170,2,"coral");
// 绘制分针
scaleRender(Math.PI/30*time[1]+2*Math.PI/3600*time[2],-20,150,3,"darkblue");// 根据分针的时间进行旋转
// 绘制时针
scaleRender(Math.PI/6*time[0]+2*Math.PI/(12*60)*time[1] + 2*Math.PI/(12*3600)*time[2],
-10,140,3,"darkslategray");// 根据时针的时间进行旋转
//
ctx.beginPath();
ctx.arc(0,0,2,0,Math.PI*2);
ctx.strokeStyle="red";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
ctx.rotate(Math.PI/2)
ctx.font="20px 微软雅黑";
ctx.fillText(`${time[0]}:${time[1]}:${time[2]}`,-40,260);
ctx.restore();
}
initClock();
setInterval(function(){
initClock();
},1000);
</script>
</body>
</html>
贴图版时钟效果
html代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<meta name="full-screen" content="yes">
<meta charset="utf-8">
<title>飛宇时钟</title>
<script src="js/07clock.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
*{margin: 0;padding: 0;box-sizing: border-box;}
body{
display: flex;flex-direction: row;
justify-content: center;
align-items: center;
}
@media screen and (max-width: 800px){
body{
width: 100vw;height: 100vh;overflow: overlay;
}
}
</style>
</head>
<body>
<canvas id="clock" width="400" height="400"></canvas>
</body>
</html>
07clock.js 代码
window.onload = function(){
const disk = './image/clock/';
function getDatetime(){
let da = new Date();
let hours = da.getHours();
let minute = da.getMinutes();
let second = da.getSeconds();
return [hours,minute,second];
}
function timeleng(a){
return a.toString().padStart(2,'0');
}
const canvas = document.getElementById('clock');
let ctx = canvas.getContext('2d');
let time = getDatetime();
const dataImgs = ['time-number.png','hours.png','minute.png','circle-bottom.png',
'second.png','circle-center.png','circle-top.png'];
let numberImg = new Image();
let hourImg = new Image();
let minuteImg = new Image();
let secondImg = new Image();
let circleBottomImg = new Image();
let circleCenterImg = new Image();
let circleTopImg = new Image();
// 图片全部加载完毕
numberImg.src=disk+dataImgs[0];
numberImg.onload = function(){
hourImg.src=disk+dataImgs[1];
hourImg.onload = function(){
minuteImg.src=disk+dataImgs[2];
minuteImg.onload = function(){
circleBottomImg.src=disk+dataImgs[3];
circleBottomImg.onload = function(){
secondImg.src=disk+dataImgs[4];
secondImg.onload = function(){
circleCenterImg.src=disk+dataImgs[5];
circleCenterImg.onload = function(){
circleTopImg.src=disk+dataImgs[6];
circleTopImg.onload = function(){
initClock();
setInterval(()=>{
time[0]=time[0]>12?time[0]-12:time[0];
initClock();
time = getDatetime();
},16);
}
}
}
}
}
}
};
// 刻画刻度
function kedu(deg,start,end,size=1){
ctx.rotate(deg);
ctx.beginPath();
ctx.moveTo(start,0);
ctx.lineTo(end,0);
ctx.lineWidth=size;
ctx.stroke();
ctx.closePath();
}
// 图片中心旋转
function centerRotateImage(x,y,deg,img,w,h){
ctx.save();
ctx.translate(x,y)
ctx.rotate(Math.PI/180+deg);
ctx.translate(-x,-y)
ctx.beginPath();
ctx.drawImage(img,0,0,w,h);
ctx.closePath();
ctx.restore();
}
// 初始化跟图片相关
function timeImage(){
ctx.save();
let move = 18;
ctx.translate(-move/2,-move/2)
ctx.beginPath();
ctx.drawImage(numberImg,0,0,numberImg.width+move,numberImg.height+move);
ctx.closePath();
ctx.restore();
// 小时
let hourRotate = Math.PI/30*3 + Math.PI/6*time[0] + Math.PI/1800*time[1] + 2*Math.PI/(3600*60)*time[2];
centerRotateImage(move/2+200-4,move/2+200-4,hourRotate,hourImg,hourImg.width+move,hourImg.height+move);
// 分钟
let minuteRotate = (-Math.PI/30*13 + Math.PI/180) + Math.PI/30*time[1] + 2*Math.PI/3600*time[2];
centerRotateImage(move/2+200,move/2+200,minuteRotate,minuteImg,minuteImg.width+move,minuteImg.height+move);
// 底部
centerRotateImage(move/2+200-4,move/2+200-4,0,circleBottomImg,circleBottomImg.width+move,circleBottomImg.height+move);
// 秒
let secondRotate=(-Math.PI/30*4 + Math.PI/3600*8) + Math.PI/30*time[2] ;
centerRotateImage(move/2+200,move/2+200,secondRotate,secondImg,secondImg.width+move,secondImg.height+move);
// 中顶部
centerRotateImage(move/2+200-4,move/2+200-4,0,circleCenterImg,circleCenterImg.width+move,circleCenterImg.height+move);
centerRotateImage(move/2+200-4,move/2+200-4,0,circleTopImg,circleTopImg.width+move,circleTopImg.height+move);
}
// 初始化时钟
function initClock(){
ctx.clearRect(0,0,400,400);
ctx.save();
ctx.translate(200,200);
ctx.save();
ctx.beginPath();
ctx.arc(0,0,192,0,Math.PI*2);
ctx.lineWidth=5;
ctx.stroke();
ctx.closePath();
ctx.restore();
ctx.save();
ctx.textAlign="center";
// 绘制秒钟刻度
for(let j=0;j<60;j++){
kedu(Math.PI/30,178,190);
}
ctx.restore();
ctx.save();
ctx.textAlign="center";
// 绘制分钟刻度
for(let j=0;j<12;j++){
kedu(Math.PI/6,170,190,6);
}
ctx.restore();
ctx.restore();
ctx.save();
// 初始化跟图片相关
timeImage();
}
}
-素材下载地址: https://github.com/finnfy/study/tree/master/canvas/image/clock
演示地址
https://www.0fy0.com/clock.html
写于:2022年1月8日
作者QQ:420318184
邮箱:fy@0fy0.com