3D 数字时钟实现
效果展示
CSS / JavaScript 知识点
- box-shadow 属性运用,实现 3D 效果的数字时钟
- transform 属性灵活运用,实现数值时钟上的数字部分
- JavaScript Date()对象的运用
页面整体布局
<div class="clock"><!-- 时钟仪表盘 --><div class="numbers"><!-- 时钟指针 --><div class="circle" id="sec" style="--clr: #04fc43"><i></i></div><div class="circle" id="min" style="--clr: #fee800"><i></i></div><div class="circle" id="hrs" style="--clr: #ff2927"><i></i></div><!-- 数字,360 / 12 = 30,从0度开始 --><span style="--i:0"><b>12</b></span><span style="--i:1"><b>1</b></span><span style="--i:2"><b>2</b></span><span style="--i:3"><b>3</b></span><span style="--i:4"><b>4</b></span><span style="--i:5"><b>5</b></span><span style="--i:6"><b>6</b></span><span style="--i:7"><b>7</b></span><span style="--i:8"><b>8</b></span><span style="--i:9"><b>9</b></span><span style="--i:10"><b>10</b></span><span style="--i:11"><b>11</b></span></div><!-- 数字仪表盘 --><div id="time"><div id="hour" style="--clr: #ff2927">00</div><div id="minutes" style="--clr: #fee800">00</div><div id="seconds" style="--clr: #04fc43">00</div><div id="ampm" style="--clr: #fff">AM</div></div>
</div>
实现数字时钟外部盒子样式
.clock {position: relative;width: 450px;height: 550px;display: flex;justify-content: center;align-items: center;background: #c9d5e0;border-radius: 50px;border-top-left-radius: 250px;border-top-right-radius: 250px;box-shadow: 45px 45px 45px -15px rgba(0, 0, 0, 0.15), inset 15px 15px 10pxrgba(255, 255, 255, 0.75), -15px -15px 35px rgba(255, 255, 255, 0.55), inset -2px -2px15px rgba(0, 0, 0, 0.2);
}
实现上述代码后效果如下:
实现数字时钟上数字时钟仪表盘的基础样式
.numbers {position: absolute;top: 30px;width: 390px;height: 390px;background: #152b4a;border-radius: 50%;display: flex;justify-content: center;align-items: center;box-shadow: 7px 7px 22px #152b4a66, inset 7px 7px 7px rgba(255, 255, 255, 0.55),-9px -9px 15px rgba(255, 255, 255, 1);
}/* 使用伪块实现时钟仪表盘上指针中心圆点 */
.numbers::before {content: "";position: absolute;width: 4px;height: 4px;border-radius: 50%;background: #e91e63;z-index: 100000;box-shadow: 0 0 0 1px #e91e63, 0 0 0 3px #fff, 0 0 5px 5px rgba(0, 0, 0, 0.15);
}.numbers span {position: absolute;inset: 15px;text-align: center;color: #fff;font-size: 1.25em;/* 使用 transform 属性让数字容器实现360度分散布局(360 / 12 = 30) */transform: rotate(calc(30deg * var(--i)));
}.numbers span b {font-weight: 400;display: inline-block;/* 因数字容器做了角度旋转,所以数字要正常显示的话,也需要旋转对应的角度 */transform: rotate(calc(-30deg * var(--i)));
}
实现数字时钟上指针的基础样式
.numbers .circle {position: absolute;width: 280px;height: 280px;border: 1px solid rgba(0, 0, 0, 0.75);border-radius: 50%;display: flex;justify-content: center;align-items: flex-start;z-index: 10;
}.numbers .circle i {position: absolute;width: 6px;height: 50%;background: var(--clr);opacity: 0.75;transform-origin: bottom;transform: scaleY(0.5);
}.numbers .circle#sec i {width: 2px;
}.numbers .circle#min i {width: 4px;
}.numbers .circle#min {width: 230px;height: 230px;
}.numbers .circle#hrs {width: 180px;height: 180px;
}.numbers .circle::before {content: "";position: absolute;width: 10px;height: 10px;background: var(--clr);top: -6px;left: 50%;border-radius: 50%;transform: translateX(-50%);box-shadow: 0 0 20px var(--clr), 0 0 60px var(--clr);
}
实现上述代码后效果如下:
实现数字时钟上数字仪表盘部分样式样式
#time {position: absolute;bottom: 35px;display: flex;padding: 10px 20px;font-size: 2em;font-weight: 600;border-radius: 40px;background: #152b4a;/* 使用内部阴影和外部阴影实现3D仪表样式 */box-shadow: 7px 7px 22px #152b4a66, inset 7px 7px 7px rgba(255, 255, 255, 0.55),-9px -9px 15px rgba(255, 255, 255, 1);
}#time div {position: relative;width: 60px;text-align: center;color: var(--clr);opacity: 0.75;
}#time div:last-child {font-size: 0.5em;display: flex;justify-content: center;align-items: center;font-weight: 500;
}#time div:nth-child(1)::after,
#time div:nth-child(2)::after {content: ":";position: absolute;right: -4px;
}#time div:nth-child(2)::after {/* 使用动画实现秒钟元素的闪缩 */animation: animate 1s steps(1) infinite;
}@keyframes animate {0% {opacity: 1;}50% {opacity: 0;}
}
实现上述代码后效果如下:
使用 JavaScript 实现数字时钟运动效果
let hr = document.querySelector("#hrs");
let mn = document.querySelector("#min");
let sc = document.querySelector("#sec");setInterval(() => {let day = new Date();let hh = day.getHours() * 30;let mm = day.getMinutes() * 6;let ss = day.getSeconds() * 6;hr.style.transform = `rotateZ(${hh + mm / 12}deg)`;mn.style.transform = `rotateZ(${mm}deg)`;sc.style.transform = `rotateZ(${ss}deg)`;let hour = document.getElementById("hour");let minute = document.getElementById("minutes");let seconds = document.getElementById("seconds");let ampm = document.getElementById("ampm");let h = new Date().getHours();let m = new Date().getMinutes();let s = new Date().getSeconds();let am = h >= 12 ? "PM" : "AM";if (h > 12) {h = h - 12;}h = h < 10 ? "0" + h : h;m = m < 10 ? "0" + m : m;s = s < 10 ? "0" + s : s;hour.innerHTML = h;minute.innerHTML = m;seconds.innerHTML = s;ampm.innerHTML = am;
});
完整代码下载
完整代码下载