JavaScript实现仿Clock ISO时钟

作者:交互手记时间:2026-10-22 15:44:27浏览:193

本文详细介绍如何利用HTML5、CSS3和JavaScript技术,从零开始构建一个仿ISO风格的模拟时钟。内容涵盖页面布局、CSS3伪元素与动画定义、以及通过JavaScript获取系统时间并计算指针角度的核心逻辑,最终实现具备真实时间显示功能的动态时钟效果。

项目概述

接下来,我们将尝试在网页中还原一个类似ISO系统界面的时钟组件:ISO Clock。

最终实现的视觉效果如下所示:

项目概述

ISO Clock

项目分析与布局

项目整体分析与规划

第一步,我们需要从本地客户端获取当前的系统时间数据。

第二步,时钟界面包含三个指针,我们可以利用CSS动画技术,使它们围绕中心点持续旋转。

第三步,根据获取到的小时(hour)、分钟(minute)和秒(second)数值,分别计算出时针、分针和秒针对应的旋转角度。

HTML与CSS基础构建

页面布局结构设计


<div class="box">
 <article class="clock">
 <div class="hours-container">
  <div class="hours"></div>
 </div>
 <div class="minutes-container">
  <div class="minutes"></div>
 </div>
 <div class="seconds-container">
  <div class="seconds"></div>
 </div>
 </article>
</div>

首先,设置一个名为.box的容器,主要用于辅助整体布局定位。

其次,为每个指针分别创建一个对应的容器(如hours-container等),以便独立控制。

CSS样式编写

加载背景图片,并将其放置在页面的合适位置。


html{  font-size: 10px;
}html,body{  margin: 0;  padding: 0;
}.box{ width: 35rem; height: 38rem;       background: rgb(205,205,205); border-radius: 1rem; margin: 5% auto; display: flex; justify-content: center; align-items: center;
}.clock{  width: 30rem;  height: 30rem;  background: #fff url(ios_clock.svg) no-repeat center;  background-size: 88%;  border-radius: 50%;  position: relative;
}

项目概述

设置.box的宽度为35rem,高度为38rem,这一比例在视觉上较为协调。

.box采用Flex布局,确保内部的.clock元素在水平和垂直方向上均居中。熟悉Flex布局的开发者应能轻松理解。

.clock的背景引用了一张图片,具体地址可参考相关资源链接。

中心轴与指针样式

中心轴的实现

利用CSS3的伪元素(:after)为时钟添加一个实心小圆点,所有指针均围绕该点旋转。


.clock:after{  content: '';  width: 1.5rem;  height: 1.5rem;  background: #000;  border-radius: 50%;  position: absolute;  top: 50%;  left: 50%;  transform: translate(-50%,-50%);   /* 向左上移动自身的50% */
  z-index: 10;
}

项目概述

必须设置content: '';,否则即使指定了宽高,伪元素也不会显示。

由于相对定位默认从元素左上角开始计算,仅设置top: 50%和left: 50%无法使圆点居中。需配合transform: translate(-50%,-50%);,使其向左上方移动自身宽高的一半,从而精确居中。

设置z-index: 10;,确保该小圆点位于视图最上层,以遮挡指针交叉处的杂乱线条。

指针容器的定位


.hours-container,.minutes-container,.seconds-container{  position: absolute;  top: 0;  right: 0;  bottom: 0;  left: 0;
}

容器已放置在.clock上方,但暂无具体样式,接下来将创建具体的指针元素。

指针元素的创建


.hours {  width: 3%;  height: 20%;  background: #000;  transform-origin: 50% 100%;  position: absolute;  top: 30%;  left: 48.5%;
}.minutes {  width: 2%;  height: 37%;  background: #000;  transform-origin: 50% 100%;  position: absolute;  top: 13%;  left: 49%;
}.seconds {  width: 1%;  height: 40%;  background: #f00;  transform-origin: 50% 90%;  position: absolute;  top: 20%;  left: 49.5%;  z-index: 8;
}

项目概述

分别构建时针、分针和秒针三个DOM元素。

使用百分比(%)作为单位,可使指针更好地适应不同屏幕尺寸。

设置transform-origin: 50% 90%;,定义指针旋转的轴心点:X轴方向居中,Y轴方向位于90%处(即指针底部附近,具体参考图示)。

项目概述

在定位时已考虑自身宽度,因此无需再额外向左上角移动。

动画定义与优化

动画效果定义

至此,时钟仅具备静态外观,接下来赋予其动态功能。

定义关键帧动画


@keyframes rotate {
  100% {    transform: rotateZ(360deg);
  }
}

使用@keyframes规则定义名为rotate的动画,使应用该动画的元素沿Z轴(即之前设定的旋转轴心)旋转360度。

定时功能配置

设定各指针旋转一周 360 度所需的时间。


.hours-container {  animation: rotate 60s infinite linear;
}.minutes-container {  animation: rotate 30s infinite linear;
}.seconds-container {  animation: rotate 10s infinite linear;
}

项目概述

为便于演示,此处使用了固定时间,并未完全遵循真实时钟的物理规律(真实时钟时针应为12小时/43200秒,分针3600秒,秒针60秒)。

优化为更真实的时钟体验

现实中的机械钟通常秒针和分针会呈现跳动效果,并伴随滴答声。我们可以尝试实现这一效果。


.hours-container {  animation: rotate 60s infinite linear;
}.minutes-container {  animation: rotate 3600s infinite steps(60);
}.seconds-container {  animation: rotate 60s infinite steps(60);
}

项目概述

只需将分针和秒针的动画方式调整为steps()函数即可实现跳动效果。

然而,上述动画每次刷新页面时均从0度开始,无法显示真实时间。如何实现显示当前真实时间的功能呢?

实时时间计算逻辑

实现实时时间显示

首先获取当前系统时间,随后计算每个指针应旋转的具体角度。

获取指针DOM元素


const hourHand = document.querySelector('.hours-container');const minuteHand = document.querySelector('.minutes-container');const secondHand = document.querySelector('.seconds-container');

获取当前时间数据


const now = new Date();const hour = now.getHours();const minute = now.getMinutes();const second = now.getSeconds();
`

计算每个指针应旋转的角度值

在CSS3中,角度单位主要有四种:

  • deg(度,圆周360度)
  • grad(梯度,圆周400梯度)
  • turn(转/圈,圆周1圈)
  • rad(弧度,圆周2π弧度)
  • 它们之间的换算关系如下:

90deg = 100grad = 0.25turn ≈ 1.570796326794897rad

显然,本例中我们需要使用的单位是deg(度)。


const secondDegree = second * 6 + 90;
const minuteDegree = minute * 6 + (second / 10) + 90;
const hourDegree = (hour * 30) + (minute / 2) + 90;

公式中+90的原因是:CSS角度起始位置为水平X轴(3点钟方向),而时钟指针默认指向Y轴(12点钟方向),需统一坐标系。

秒针计算最简单,公式为:(second / 60) * 360 + 90;。

分针需考虑秒针的影响(如过了30秒,相当于走了半分钟)。公式为:((minutes/ 60) * 360) + ((seconds / 60) * 6) + 90;。

时针计算稍复杂,需考虑分钟的影响(如过了30分钟,相当于走了半小时)。公式为:(( hours/ 12) * 360) + ((minutes / 60) * 30) + 90;。

应用计算出的角度值


hourHand.style.transform = `rotateZ(${hourDegree}deg)`;
minuteHand.style.transform = `rotateZ(${minuteDegree}deg)`;
secondHand.style.transform = `rotateZ(${secondDegree}deg)`;

为使页面实时更新,需将上述逻辑封装为函数,并通过定时器每秒执行一次。

至此,整个时钟的功能已全部实现!

作者最新文章