实现效果:
实现思路:
1.实现一个时钟效果,要包含三个用于显示时针、分针和秒针的div元素。使用React Hooks中的useState和useEffect钩子配合实现时间的动态更新,然后计算出当前对应的时间的小时、分钟以及秒钟。然后使用less实现效果;
2.定义@duration和@step两个变量,用来控制动画的时长和每一次旋转的角度。使用less中的keyframe()函数来创建名为rotate的动画,接下来要为时针、分针和秒针分别指定使用rotate动画,并传递不同的步数参数(分别为12、60和60),注意,使用keyframe()函数时,将动画名称作为第一个参数传入,并在其后面添加分号(例如keyframe(rotate; 60)),这样可以告诉less将其解析为动画名称,从而生成正确的css代码;
3.最后设置一个灰白色背景,以及圆形的样式,每个针的样式使用了绝对定位,通过设置top和left将其固定在时钟中间位置。
Clock.tsx
import React, { useEffect, useState } from "react";
import styles from './index.module.less';
const Clock = () => {
const [time, setTime] = useState(new Date())
useEffect(() => {
const timer = clearInterval(() => {
setTime(new Date())
}, 1000)
return () => {
clearInterval(timer)
}
}, [])
const hour = time.getHours() % 12 || 12;
const minute = time.getMinutes();
const second = time.getSeconds();
return <>
<div className={styles.clock}>
<div className={styles.hour} style={{ transform: `rotate(${30 * hour}deg)` }}></div>
<div className={styles.minute} style={{ transform: `rotate(${6 * minute}deg)` }}></div>
<div className={styles.second} style={{ transform: `rotate(${6 * second}deg)` }}></div>
</div>
</>
}
}
clock.module.less
@duration: 1s;
@step: 0.5;
.keyframes(rotate; @duration, @step) {
from {
transform: rotate(0deg);
}
to {
transform: rotate(@step * 360deg);
}
}
.clock {
width: 200px;
height: 200px;
border-radius: 50%;
position: relative;
background-color: #f6f6f6;
position: relative;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
border: 2px solid #e8e8e8;
background-image: radial-gradient(circle at center, white 30%, #e8e8e8 180%);
overflow: hidden;
&::before {
content: '';
display: block;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #333;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.hour,
.minute,
.second {
position: absolute;
top: 50%;
left: 50%;
margin-left: -1px;
transform-origin: bottom center;
background-color: black;
}
.hour {
width: 8px;
height: 50px;
background-color: #333;
margin-top: -50px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.4), 0 -3px 5px rgba(0, 0, 0, 0.2) inset;
animation: keyframes(rotate, 12) linear infinite;
}
.minute {
width: 6px;
height: 70px;
background-color: #333;
margin-top: -70px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.4), 0 -3px 5px rgba(0, 0, 0, 0.2) inset;
animation: keyframes(rotate, 60) linear infinite;
}
.second {
width: 2px;
height: 90px;
background-color: #d00;
margin-top: -90px;
box-shadow: 0 0 10px rgba(221, 0, 0, 0.4), 0 -3px 10px rgba(221, 0, 0, 0.2) inset;
animation: keyframes(rotate, 60) linear infinite;
}
}