JavaScript仿IOS Clock
参考
描述
用JavaScript模仿IOS上Clock时钟
效果
IOS Clock项目分析
- 时钟,首先得获取本地时间
- 时钟有3个指针,通过添加动画的方式让它围绕中心点旋转
- 通过获取到的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是为了布局的方便
- 每个指针都需要一个*.container容器
添加背景样式
html {
/* font-size必须大于等于12,否则不生效*/
font-size: 12px;
}
html, body {
margin: 0px;
padding: 0px;
}
.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('./images/ios_clock.svg') no-repeat center;
background-size: 88%;
border-radius: 50%;
position: relative;
}
Background
- 设置.box的width和height,建议用rem单位,这样手机上效果也很好
- .box采用Flex布局,并且.clock在水平和垂直方向上都居中,具体Flex布局后面章再介绍
- Clock的背景使用了一张图片,具体见最后的项目地址
添加中心轴
.clock:after {
/* content是必须的,不然伪元素不会显示 */
content: '';
width: 1.5rem;
height: 1.5rem;
background: #000;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
/* 向坐上移动自身的50% */
transform: translate(-50%, -50%);
z-index: 10;
}
Central Axis
- 使用CSS3中的伪元素为时钟添加实心小圆点,指针都围绕这个点转
- 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;
}
- 添加指针容器后,暂时并无效果
- 指针的转动,实际是通过动态调整指针容器的角度实现的
- 添加指针容器后,可以添加指针的样式了
添加指针
.hours {
width: 3%;
height: 20%;
background: #000;
position: absolute;
top: 30%;
left: 48.5%;
}
.minutes {
width: 2%;
height: 37%;
background: #000;
position: absolute;
top: 13%;
left: 49%;
}
.seconds {
width: 1%;
height: 40%;
background: #f00;
position: absolute;
top: 20%;
left: 49.5%;
z-index: 8;
}
Hand
- 分别添加时针、分针、秒针
- 时针较粗,分针次之,秒针最细,采用3%、2%、1%递减,可以自己调整
- %是相对于各自的*.container容器元素的
- 时针top: 30%; height: 20%; 两者相加正好为50%,即下边缘与中心轴重合,分针同理
- 时针width: 3%; left: 48.5%; width/2 + left == 50%,分针、秒针同理
- 秒针top: 20%; height: 40%; top + height == 60%,秒针下边缘超过中心轴,超出10%
动画
定义动画规则
@keyframes rotate {
100% {
transform: rotateZ(360deg);
}
}
采用@keyframes规则定义一个动画,动画名称为rotate,这个动画的元素会沿着Z轴旋转360°
定时器
.hours-container {
animation: rotate 36s infinite linear;
}
.minutes-container {
animation: rotate 18s infinite steps(60);
}
.seconds-container {
animation: rotate 3s infinite steps(60);
}
Animation
- 为了演示的方便,固定的事件并未按真实的时间来设置。时针是12小时(43200秒)、分针是60分钟(3600秒),秒针是60秒。
- 为了有咔嚓咔嚓的跳动,秒针、分针采用steps(60),每步60°
- 由于CSS的时间是有一定误差的,所以不能直接采用1. 中的值
- 请删除或注释定义动画规则和定时器中的CSS代码
时钟
获取本地时间,并计算每个指针应该旋转的角度,并设置
获取每个指针
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中角度单位一共有4种:
- deg (度,一个圆360度)
- grad (梯度,一个圆400梯度)
- turn (转/圈,一个圆1圈)
- rad (弧度,一个圆2π弧度)
const secondDegree = second * 6;
const minuteDegree = minute * 6;
const hourDegree = (hour * 30) + (minute / 2);
- 秒针一圈是360°,60秒,每秒360 / 60 = 6°,所以秒针角度为second * 6
- 分针一圈是360°,60分钟,每分钟360 / 60 = 6°,所以分针角度为minute * 6
- 时针一圈是360°,12小时,每小时360 / 12 = 30°,又由于分针转动时,时针也会产生微小的移动,minute * 30° / 60分钟 = minute / 2,所以时针角度为(hour * 30) + (minute / 2)
设置角度值
hourHand.style.transform = `rotateZ(${hourDegree}deg)`;
minuteHand.style.transform = `rotateZ(${minuteDegree}deg)`;
secondHand.style.transform = `rotateZ(${secondDegree}deg)`;
以上可以根据本地时间设置时钟角度,但想要时钟实时转动,则需要增加setInterval
定时更新
<script>
function clockWalk() {
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();
const secondDegree = second * 6;
const minuteDegree = minute * 6;
const hourDegree = (hour * 30) + (minute / 2);
hourHand.style.transform = `rotateZ(${hourDegree}deg)`;
minuteHand.style.transform = `rotateZ(${minuteDegree}deg)`;
secondHand.style.transform = `rotateZ(${secondDegree}deg)`;
}
setInterval(function() {
clockWalk();
}, 1000);
</script>
F12
通过以上动态图可知,指针转动实际是通过转动*.container对应的div来实现的
这样,整个时钟就完成了
项目地址:码云/c02954/ios_clock
网友评论