实现时钟功能有很多种方式,本文实例介绍了利用了js+css3的新特性进行时钟功能的实现。
先看效果图:
具体内容如下:
1. 思路
- 构建时钟的静态html结构,利用css控制时钟元素的样式和布局
- 使用css的绝对定位和transform属性固定住秒针、分针、时针和刻度等一些元素的位置
- 利用js控制指针元素的transform属性的rotate值,使其旋转。
- 利用js的Date对象获取当前时间和setInterval函数来不断更新指针位置。
2. html部分
<body>
<div class="outer-container">
<div class="inner-container">
<!-- 时钟中心点-->
<div class="clock-center"></div>
<!-- 垂直和水平方向的时间刻度-->
<div class="scale left-scale"></div>
<div class="scale top-scale"></div>
<div class="scale right-scale"></div>
<div class="scale bottom-scale"></div>
<!-- 普通小时的时间刻度-->
<div class="hour-scale one-scale"></div>
<div class="hour-scale two-scale"></div>
<div class="hour-scale four-scale"></div>
<div class="hour-scale five-scale"></div>
<div class="hour-scale seven-scale"></div>
<div class="hour-scale eight-scale"></div>
<div class="hour-scale ten-scale"></div>
<div class="hour-scale eleven-scale"></div>
<!-- 时针-->
<div class="pointer hour-pointer"></div>
<!-- 分针-->
<div class="pointer minute-pointer"></div>
<!-- 秒针-->
<div class="pointer second-pointer"></div>
</div>
</div>
</body>
html部分很简单,有一个外层容器和内层容器,目的是来制作时钟的边框效果,在内层容器中有一些必要的元素标签,包括指针、刻度、中心点,都加上类名加以区分。
2. css部分
html {
background-color: rgb(40, 40, 40);
}
.outer-container, .inner-container, .clock-center, .scale, .hour-scale {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
}
.outer-container {
width: 400px;
height: 400px;
border: 3px solid #232323;
box-shadow: 5px 5px 5px 5px #252525;
background-color: rgb(30, 30, 30);
}
.inner-container {
width: 375px;
height: 375px;
border: 1px solid #272626;
box-shadow: inset 5px 5px 5px 5px #272727;
background-color: rgb(50, 50, 50);
}
.clock-center {
background-color: #5c5757;
width: 15px;
height: 15px;
transform: translate(-50%, -50%);
z-index: 1;
}
.scale {
width: 8px;
height: 30px;
position: absolute;
border-radius: 3px;
background-color: #6de84d;
}
.top-scale {
transform: translate(-50%, -50%) translateY(-160px);
}
.bottom-scale {
transform: translate(-50%, -50%) rotate(180deg) translateY(-160px);
}
.left-scale {
transform: translate(-50%, -50%) rotate(90deg) translateY(-160px);
}
.right-scale {
transform: translate(-50%, -50%) rotate(270deg) translateY(-160px);
}
.hour-scale {
width: 5px;
height: 22px;
background-color: #fff;
border-radius: 3px;
}
.one-scale {
transform: translate(-50%, -50%) rotate(30deg) translateY(-160px);
}
.two-scale {
transform: translate(-50%, -50%) rotate(60deg) translateY(-160px);
}
.four-scale {
transform: translate(-50%, -50%) rotate(120deg) translateY(-160px);
}
.five-scale {
transform: translate(-50%, -50%) rotate(150deg) translateY(-160px);
}
.seven-scale {
transform: translate(-50%, -50%) rotate(210deg) translateY(-160px);
}
.eight-scale {
transform: translate(-50%, -50%) rotate(240deg) translateY(-160px);
}
.ten-scale {
transform: translate(-50%, -50%) rotate(300deg) translateY(-160px);
}
.eleven-scale {
transform: translate(-50%, -50%) rotate(330deg) translateY(-160px);
}
.pointer {
position: absolute;
top: 50%;
left: 50%;
/* 关键:控制指针旋转轴点*/
transform-origin: 50% 100% 0;
}
.hour-pointer {
width: 10px;
height: 80px;
background-color: #2a7ede;
transform: translate(-50%, -100%) rotate(0deg);
border-radius: 3px;
}
.minute-pointer {
width: 6px;
height: 105px;
background-color: #62b5fc;
transform: translate(-50%, -100%) rotate(0deg);
border-radius: 3px;
transition: transform 500ms ease-in;
}
.second-pointer {
width: 3px;
height: 130px;
background-color: #ee6629;
transform: translate(-50%, -100%) rotate(0deg);
}
这部分比较多,但是结合类名去看css属性就很容易明白了,这里也不做过多解释
唯一需要提及的就是 transform-origin: 50% 100% 0 属性值,这个属性是用来设置元素的旋转轴心的,有三个值,第一个是轴心点的x坐标,第二个是轴心点的y坐标,第三个是轴心点的z坐标,默认是 50% 50% 0(中心位置),所以我这里的设置是把轴心点设置为了底部中间位置。
3. js部分
(function(){
// 时针对象
const hourPointer = {
dom: document.querySelector('.hour-pointer'),
setPosition: function (currentMinute) {
const newHour = new Date().getHours()
// 时针会随着当前的分钟数偏移
const deg=(360 * newHour / 12)+(30*currentMinute/60)
this.dom.style.transform = `translate(-50%, -100%) rotate(${deg}deg)`
}
}
// 分针对象
const minutePointer = {
dom: document.querySelector('.minute-pointer'),
//当前分钟数
currentMinute: -1,
setPosition: function () {
const newMinute = new Date().getMinutes()
// 判断当前分钟数是否和新的分钟数相等,如果相等,就不需要偏移
if(this.currentMinute===newMinute){
return
}
this.currentMinute = newMinute
this.dom.style.transform = `translate(-50%, -100%) rotate(${360 * this.currentMinute / 60}deg)`
//分针每一次偏移,都需要调用时针偏移
hourPointer.setPosition(newMinute)
}
}
// 秒针对象
const secordPointer = {
dom: document.querySelector('.second-pointer'),
//当前秒数
currentSecords: -1,
setPosition: function () {
const newSecords = new Date().getSeconds()
// 判断是否为新的一秒,不是则return
if(this.currentSecords === newSecords) {
return
}
this.currentSecords = newSecords
this.dom.style.transform = `translate(-50%, -100%) rotate(${360 * this.currentSecords / 60}deg)`
// 秒针每次偏移都会调用一下分针的偏移
minutePointer.setPosition()
},
start: function () {
// 启动时立即调用一次,设置其位置
this.setPosition()
setInterval(() => {
this.setPosition()
}, 250)
// 这里使用250ms的间隔时间是为了提高时钟的显示效果。
}
}
// 开启秒针转动
secordPointer.start()
})()
4. 效果展示
一个漂亮的时钟就制作出来啦。