使用JavaScript做一个面向对象的时钟

使用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>

最终效果

猜你喜欢

转载自www.cnblogs.com/zong0506/p/12694007.html