废话不多说。看效果.直接上源码
<div class="container">
<div class="clock">
<div class="time-box">
<div class="numbers" id="hours-first">
<li>0</li>
<li>1</li>
<li>2</li>
</div>
</div>
<div class="time-box">
<div class="numbers" id="hours-second">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</div>
</div>
<div class="dot">:</div>
<div class="time-box">
<div class="numbers" id="minutes-first">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</div>
</div>
<div class="time-box">
<div class="numbers" id="minutes-second">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</div>
</div>
<div class="dot">:</div>
<div class="time-box">
<div class="numbers" id="seconds-first">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</div>
</div>
<div class="time-box">
<div class="numbers" id="seconds-second">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</div>
</div>
</div>
</div>
// 获取DOM元素
const h1 = document.getElementById("hours-first");
const h2 = document.getElementById("hours-second");
const m1 = document.getElementById("minutes-first");
const m2 = document.getElementById("minutes-second");
const s1 = document.getElementById("seconds-first");
const s2 = document.getElementById("seconds-second");
// 初始化变量
let hour1 = 0,
hour2 = 0,
minute1 = 0,
minute2 = 0,
second1 = 0,
heightValue = 60;
/**
* 处理数字的函数
* 将输入的数字拆分为十位和个位数
* @param {number} num - 待处理的数字
* @returns {Array} 包含两个元素的数组,第一个元素为十位数,第二个元素为个位数
*/
function handleNumber(num) {
// 如果数字小于10,直接返回0和该数字
if (num < 10) {
return [0, num];
} else {
// 如果数字大于等于10,计算十位数和个位数
// 使用Math.floor()函数计算十位数,使用%运算符计算个位数
// Math.floor 向下取整数 (num / 10) 的整数部分就是十位数
// % 10 取余数 就是个位数
return [Math.floor(num / 10), num % 10];
}
}
function changeTime() {
let time = new Date();
// 获取当前时间,分别获取小时、分钟、秒数,并组装成两位数,并返回
const [h_1, h_2] = handleNumber(time.getHours());
const [m_1, m_2] = handleNumber(time.getMinutes());
const [s_1, s_2] = handleNumber(time.getSeconds());
// 判断是否需要更新数字
if (h_1 !== hour1) {
hour1 = h_1;
// 更新数字
// 使用CSS的transform属性,将数字元素垂直平移到对应的位置,每一个格子是 30px
h1.style.transform = `translateY(-${hour1 * heightValue}px)`;
}
if (h_2 !== hour2) {
hour2 = h_2;
h2.style.transform = `translateY(-${hour2 * heightValue}px)`;
}
if (m_1 !== minute1) {
minute1 = m_1;
m1.style.transform = `translateY(-${minute1 * heightValue}px)`;
}
if (m_2 !== minute2) {
minute2 = m_2;
m2.style.transform = `translateY(-${minute2 * heightValue}px)`;
}
if (s_1 !== second1) {
second1 = s_1;
s1.style.transform = `translateY(-${second1 * heightValue}px)`;
}
s2.style.transform = `translateY(-${s_2 * heightValue}px)`;
}
// 每秒调用一次changeTime函数
setInterval(changeTime,1000);
:root{
--height-value:60px;
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: linear-gradient(to right bottom, #f3efef, #417577);
}
li {
list-style: none;
height: var(--height-value);
width: var(--height-value);
margin: 0;
padding: 0;
font-size: 30px;
line-height: var(--height-value);
font-weight: 700;
color: #ffffff;
}
.container {
width: 100%;
position: fixed;
top: 50%;
left: 50%;
z-index: 4;
transform: translate(-50%, -50%);
}
.clock {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
width: 500px;
height: var(--height-value);
margin: 50% auto;
padding: calc( var(--height-value) / 3) calc( var(--height-value) / 1);
background-color: linear-gradient(to right bottom, #417577, #f3efef);
box-shadow: 2px 2px 10px 3px #2f2f2f;
transform: translateY(-50%);
border-radius: 20px;
overflow: hidden;
}
.time-box {
width: var(--height-value);
height: 100%;
border-radius: 15px;
overflow: hidden;
position: relative;
}
.numbers {
background-color: rgba(39, 39, 39,.1);
text-align: center;
transition: all 0.5s;
}
.dot{
font-size: calc(var(--height-value) / 2);
font-weight: 900;
color: #ffffff;
animation: jump infinite 1s ease;
}
@keyframes jump {
0% ,100%{
opacity: 1;
}
50% {
opacity: 0;
}
}