使用JavaScript做一个面向对象的时钟
一直用的是es5中的构造函数来做面向对象的程序,最近学校里老师布置了一个编写时钟的任务,故我决定这回使用es6中的class做一个动态生成的面向对象的可手动更改时间的时钟。
大致思路
时钟设置三个类,分别为:
指针类:设置一个指针类,不对时针分针单独分类,设置type属性以调节其转速。
表盘类:设置表盘,包括外表框、内表盘和针轴,同时for循环动态生成刻度。
时钟类:调取以上两个类,直接在时钟类中做初始化以及设置定时器。
在对整个时钟进行样式设置的时候,所有的宽度高度均为相对于父容器所设置的;而对于时间的设置可以是使用date获取本地时间,也可以进行手动设置。
代码
arm.js
// 钟针类
class Arm {
constructor(type, width, height, bgcolor, floor, fatherWidth, begintime) {
this.type = type;
this.ele = document.createElement('div');
this.width = width;
this.height = height;
this.bgcolor = bgcolor;
this.floor = floor;
this.fatherWidth = fatherWidth;
this.begintime = begintime || 0;
this.begintimeDeg = 0;
//时针计数器
this.count = 0;
}
armInit() {
this.ele.style.position = 'absolute';
this.ele.style.top = '50%';
this.ele.style.left = this.fatherWidth * 0.5 - this.width * 0.5 + 'px';
this.ele.style.transformOrigin = '50% 0px';
this.ele.style.width = this.width + 'px';
this.ele.style.height = this.height + 'px';
this.ele.style.backgroundColor = this.bgcolor;
this.ele.style.zIndex = this.floor;
this.ele.style.boxShadow = '1px 1px 2px ' + this.bgcolor;
this.ele.style.borderRadius = this.width * 0.5 + 'px';
if (this.type === 'hour') {
this.begintimeDeg = this.begintime * 30 + 180;
this.ele.style.transform = 'rotate(' + this.begintimeDeg + 'deg)';
} else {
this.begintimeDeg = this.begintime * 6 + 180;
this.ele.style.transform = 'rotate(' + this.begintimeDeg + 'deg)';
}
}
run() {
// 在秒针和分针转过一圈以后将度数调零以减少计算量
if (this.begintimeDeg == 540) {
this.begintimeDeg = 180;
}
// console.log(this.begintimeDeg)
switch (this.type) {
case 'second':
this.begintimeDeg += 6;
this.ele.style.transform = 'rotate(' + this.begintimeDeg + 'deg)';
break;
case 'minute':
// this.begintimeDeg += 0.1;
// 将浮点数运算转化为整数运算,提高精确度
this.begintimeDeg *= 10;
this.begintimeDeg++;
this.begintimeDeg /= 10;
this.ele.style.transform = 'rotate(' + this.begintimeDeg + 'deg)';
break;
case 'hour':
this.count++;
if (this.count >= 60) {
this.begintimeDeg += 0.5;
// this.begintimeDeg *= 10;
// this.begintimeDeg += 5;
// this.begintimeDeg /= 10;
this.ele.style.transform = 'rotate(' + this.begintimeDeg + 'deg)';
this.count = 0;
}
}
}
}
clockface.js
// 表盘类
class Clockface {
constructor(container, side, bdColor, innerColor) {
this.clockBorder = document.createElement('div');
this.clockInner = document.createElement('div');
this.clockAxis = document.createElement('div');
this.clockDial = document.createElement('ul');
this.side = side;
this.borderColor = bdColor || '#ff6600';
this.innerColor = innerColor || '#fff';
this.container = container;
}
clockInit() {
// 表盘边框初始化
this.clockBorder.style.position = 'relative';
this.clockBorder.style.width = this.side + 'px';
this.clockBorder.style.height = this.side + 'px';
this.clockBorder.style.borderRadius = '50%';
this.clockBorder.style.zIndex = 0;
this.clockBorder.style.boxShadow = this.side * 0.01 + 'px ' + this.side * 0.005 + 'px ' + this.side * 0.05 + 'px ' + this.borderColor;
this.clockBorder.style.backgroundColor = this.borderColor;
// 表盘初始化
this.clockInner.style.position = 'absolute';
this.clockInner.style.top = '3.5%';
this.clockInner.style.left = '3.5%';
this.clockInner.style.width = '93%';
this.clockInner.style.height = '93%';
this.clockInner.style.backgroundColor = this.innerColor;
this.clockInner.style.borderRadius = '50%';
this.clockInner.style.boxShadow = this.side * 0.003 + 'px ' + this.side * 0.003 + 'px ' + this.side * 0.03 + 'px ' + this.borderColor + ' inset';
this.clockInner.style.zIndex = 1;
// 钟轴初始化
this.clockAxis.style.position = 'absolute';
this.clockAxis.style.top = '50%';
this.clockAxis.style.left = '50%';
this.clockAxis.style.transform = 'translate(-50%, -50%)';
this.clockAxis.style.width = this.side * 0.05 + 'px';
this.clockAxis.style.height = this.side * 0.05 + 'px';
this.clockAxis.style.backgroundColor = this.borderColor;
this.clockAxis.style.borderRadius = '50%';
this.clockAxis.style.zIndex = 10;
// 刻度盘初始化
this.clockDial.style.position = 'absolute';
this.clockDial.style.top = '50%';
this.clockDial.style.left = '50%';
this.clockDial.style.margin = '0';
this.clockDial.style.padding = '0';
this.clockDial.style.zIndex = 2;
for (let i = 0; i < 12; i++) {
var li = document.createElement('li');
li.style.position = 'absolute';
li.style.width = this.side * 0.01 + 'px';
li.style.borderRadius = this.side * 0.005 + 'px';
li.style.height = this.side * 0.05 + 'px';
li.style.marginTop = -this.side * 0.025 + 'px';
li.style.marginLeft = -this.side * 0.005 + 'px';
li.style.listStyle = 'none';
li.style.transform = 'rotate(' + i * 30 + 'deg) translateY(' + this.side * 0.445 + 'px)';
if (i % 3 == 0) {
li.style.height = this.side * 0.10 + 'px';
li.style.marginTop = -this.side * 0.05 + 'px';
li.style.transform = 'rotate(' + i * 30 + 'deg) translateY(' + this.side * 0.42 + 'px)';
}
li.style.backgroundColor = this.borderColor;
li.style.boxShadow = '1px 1px 1px ' + this.borderColor;
this.clockDial.appendChild(li);
}
//将表盘元素放入容器中
this.clockInner.appendChild(this.clockAxis);
this.clockInner.appendChild(this.clockDial);
this.clockBorder.appendChild(this.clockInner);
this.container.appendChild(this.clockBorder);
}
}
clock.js
// 时钟类
class Clock {
constructor(Clockface, Arm, container, side, time, color) {
this.color = color || '#f60'
this.clockface = new Clockface(container, side, this.color);
this.second_arm = new Arm('second', side * 0.007, side * 0.43, this.color, 6, side * 0.94, time.second);
this.minute_arm = new Arm('minute', side * 0.014, side * 0.33, this.color, 5, side * 0.94, time.minute);
this.hour_arm = new Arm('hour', side * 0.02, side * 0.23, this.color, 4, side * 0.94, time.hour);
this.timer = null;
}
init() {
clearInterval(this.timer);
this.timer = null;
this.clockface.clockInit();
this.second_arm.armInit();
this.minute_arm.armInit();
this.hour_arm.armInit();
this.clockface.clockInner.appendChild(this.second_arm.ele);
this.clockface.clockInner.appendChild(this.minute_arm.ele);
this.clockface.clockInner.appendChild(this.hour_arm.ele);
this.tiemr = setInterval(() => {
this.second_arm.run();
this.minute_arm.run();
this.hour_arm.run();
}, 1000)
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>世界时钟</title>
</head>
<style>
* {
margin: 0;
padding: 0;
}
div.clock {
width: 300px;
height: 300px;
}
</style>
<body>
<div class="clock">
</div>
</body>
<script src="./js/arm.js"></script>
<script src="./js/clockface.js"></script>
<script src="./js/clock.js"></script>
<script>
const time = {
hour: 0,
minute: 0,
second: 0
}
let date = new Date();
time.second = date.getSeconds();
time.minute = date.getMinutes() + time.second / 60;
time.hour = date.getHours() + time.minute / 60;
let clock = document.querySelector('.clock');
let clockWidth = clock.offsetWidth;
let clock1 = new Clock(Clockface, Arm, clock, clockWidth, time, '#333');
clock1.init();
</script>
</html>