JS实现电子时钟

558 阅读3分钟

哈喽啊,我是不睡,今天就用JS简单实现一个电子时钟的效果,就像上面的效果,就这样看你可能会有点没头绪。那么好,如果我把它变成这样呢?

image.png

是不是感觉有点思绪了,可以看到,当我把上面时,分,秒的指针盘移开后,下面就只是一个简单的背景图片,和六根固定的刻度指向线,有两根比较粗,用于展示更加真实的表盘刻度。 那么我们可以将其分成两部分来完成。

先实现底部内容
  • 外表盘大图片
  • 六根指向刻度
再就是内部表盘
  • 内表盘图片
  • 内表盘指针

分析了一波之后是不是有手就行了,(来点废话文学😂),那么好我们一步一步来 首先:实现底部内容

<div class="clock">
        <div class="outer-clock-face">
            <div class="marking marking-one"></div>
            <div class="marking marking-two"></div>
            <div class="marking marking-three"></div>
            <div class="marking marking-four"></div>
        </div>
    </div>

接下来就是css部分了

body{
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    
}
.clock{
    width: 300px;
    height: 300px;
    border: 7px solid rgb(167, 225, 248);
    border-radius: 50%;
    background-image: url(https://ts1.cn.mm.bing.net/th/id/R-C.3d42ebd17fddd1c4752854256b3d310e?rik=RXb5yBBC8A6hJA&riu=http%3a%2f%2fimg.keaitupian.cn%2fuploads%2f2021%2f05%2f06%2f5drsvnyybmk.jpg&ehk=1MU6PnGSeBHG7etADNQFa%2f4QTPfdeekpV0pFv8e8yFU%3d&risl=&pid=ImgRaw&r=0);
    background-size: 150%;
    padding: 20px;
}   
.outer-clock-face{
        width: 100%;
        height: 100%;
        border-radius: 50%;
        position: relative;  // 设置为定位基准
}
.marking{
    width: 3px;
    height: 100%;
    background-color: #5c5c76;
    position: absolute;  // 相对于父容器定位
    left: 50%;
    margin-left: -1.5px;
    border-radius: 8px;
    transform-origin: 50% 50%; // 设置旋转基点为中心
}
.marking-one{
    transform: rotateZ(30deg);  // 控制旋转 
}
.marking-two{
    transform: rotateZ(60deg);
}
.marking-three{
    transform: rotateZ(120deg);
}
.marking-four{
    transform: rotateZ(150deg);
}

这里使用到的居中方式是——弹性盒子 在这一篇文章有详细介绍(juejin.cn/post/740839…)

  • 设置父容器为弹性盒子
  • 将子容器水平垂直居中
  • 在子容器中放6根刻度线
  • oi 这里你是不是会疑惑只放了四根刻度,对这里我把两根较粗的刻度放在了伪元素上 冒充了页面上的两个元素
.outer-clock-face::before,  // 开标前之前
.outer-clock-face::after {   // 闭标签之后
    content: '';
    width: 10px;
    height: 100%;
    background-color: rgb(50, 58, 66);
    display: block;
    position: absolute;  // 相对于父容器定位
    left: 50%;
    margin-left: -5px;
    border-radius: 8px;

}
.outer-clock-face::after {
    transform: rotateZ(90deg);
}

可以在浏览器上看到::before::after会处于父容器的相对位置 image.png

🆗呀,让我们实现内表盘效果

下面是完整的html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>clock</title>
    <link rel="stylesheet" href="./style.css">

</head>
<body>
    <div class="clock">
        <div class="outer-clock-face">
            <div class="marking marking-one"></div>
            <div class="marking marking-two"></div>
            <div class="marking marking-three"></div>
            <div class="marking marking-four"></div>
            <div class="inner-clock-face">  // 这部分是内表盘的html结构
                <div class="hand hour-hand"></div>
                <div class="hand min-hand"></div>
                <div class="hand second-hand"></div>
            </div>
        </div>
    </div>
</body>
<script src="./index.js">

</script>
</html>
内部表盘的css
.inner-clock-face{
    width: 80%;
    height: 80%;
    border-radius: 100%;
    /* background-color: #5b93a1; */
    background-image: url(https://ts1.cn.mm.bing.net/th/id/R-C.3d42ebd17fddd1c4752854256b3d310e?rik=RXb5yBBC8A6hJA&riu=http%3a%2f%2fimg.keaitupian.cn%2fuploads%2f2021%2f05%2f06%2f5drsvnyybmk.jpg&ehk=1MU6PnGSeBHG7etADNQFa%2f4QTPfdeekpV0pFv8e8yFU%3d&risl=&pid=ImgRaw&r=0);
    background-size: 180%;
    position: absolute;
    z-index: 1;  // 设置z轴位置为 1
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);  // 实现居中效果
}
.hand{
    width: 30%;
    height: 6px;
    background-color: #ca3939;
    position: absolute;
    top: 50%;
    right: 50%;
    border-radius: 6px;
    margin-top: -3px;
    transform-origin: 100% 50%;  // 设置旋转基点
    transform: rotate(90deg);
}
.min-hand{
    width: 35%;
    height: 4px;
    margin-top: -1px;
    background-color: #ca3939;
}
.second-hand{
    width: 45%;
    height: 2px;
    margin-top: -1px;
    background-color: #303b3a;
}

image.png 来到这里你就已经实现80%了,真厉害! Suggestion (2).gif

最后就是让指针实现转动

我们可以使用 document.querySelector('.second-hand')拿到秒针元素,在让秒针移动 在使用一个定时器函数每秒触发一次跳动

var secondHand = document.querySelector('.second-hand')
function setDate() {
    // 拿到当前时间
    var now = new Date()
    // 读秒
    var seconds = now.getSeconds()
    // 计算旋转角度
    var secondsDeg = ((seconds / 60) * 360) + 90
    // 设置秒针角度
    secondHand.style.transform = `rotate(${secondsDeg}deg)`
}

setInterval(setDate, 1000)

这样你的秒针就可以实现实时的转动了。同样的方法让你的时针和分针转动。

完整的js代码

var secondHand = document.querySelector('.second-hand')

var minHand = document.querySelector('.min-hand')

var hourHand = document.querySelector('.hour-hand')
function setDate() {
    // 拿到当前时间
    var now = new Date()

    // 读秒
    var seconds = now.getSeconds()

    // 计算旋转角度
    var secondsDeg = ((seconds / 60) * 360) + 90
    // 设置秒针角度
    secondHand.style.transform = `rotate(${secondsDeg}deg)`

    var minutes = now.getMinutes();
    var minutesDeg = ((minutes / 60) * 360) + ((seconds / 60) * 6) + 90;
    minHand.style.transform = `rotate(${minutesDeg}deg)`;

    var hours = now.getHours();
    var hoursDeg = ((hours / 12) * 360) + ((minutes / 60) * 30) + 90;
    hourHand.style.transform = `rotate(${hoursDeg}deg)`;
}

setInterval(setDate, 1000)

就像下面的效果