CSS、JS之倒计时动画效果

效果演示

图片

实现了一个倒计时动画效果,包括数字区域和倒计时结束区域。数字区域显示倒计时数字,数字进入时有动画效果,数字离开时也有动画效果。倒计时结束后,数字区域隐藏,倒计时结束区域显示,显示时也有动画效果。用户可以点击重新开始按钮重新开始倒计时。

Code

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>倒计时动画效果</title>
    <link rel="stylesheet" href="./10-倒计时动画效果.css">
</head>

<body>
    <div class="container">
        <div class="counter">
            <div class="nums">
                <span class="in">3</span>
                <span>2</span>
                <span>1</span>
                <span>0</span>
            </div>
            <h3>准备</h3>
        </div>
        <div class="final">
            <h1>活动开始</h1>
            <button class="replay">重来</button>
        </div>
    </div>
</body>
<script src="./10-倒计时动画效果.js"></script>
</html>
/* 清除所有元素的默认margin和padding */  
* {  
    margin: 0; /* 清除外边距 */  
    padding: 0; /* 清除内边距 */  
}  
  
/* 设置body的高度为视口高度,并使用flex布局进行居中 */  
body {  
    height: 100vh; /* 视口高度 */  
    display: flex; /* 弹性布局 */  
    justify-content: center; /* 主轴居中对齐 */  
    align-items: center; /* 交叉轴居中对齐 */  
    background: linear-gradient(to bottom, #fdfbfb, #ebedee); /* 背景线性渐变,从上到下 */  
}  
  
/* 容器元素,设置为相对定位 */  
.container {  
    position: relative; /* 相对定位 */  
}  
  
/* 计数器容器,宽度100%,文本居中对齐 */  
.counter {  
    width: 100%; /* 宽度100% */  
    text-align: center; /* 文本居中对齐 */  
}  
  
/* 隐藏计数器动画 */  
.counter.hide {  
    transform: scale(0); /* 缩放到0 */  
    animation: hide 0.2s ease-out; /* 应用名为hide的动画,持续0.2秒,使用ease-out缓动函数 */  
}  
  
/* 数字容器样式 */  
.nums {  
    width: 250px; /* 宽度250px */  
    height: 80px; /* 高度80px */  
    color: #5696ff; /* 字体颜色 */  
    font-size: 80px; /* 字体大小 */  
    font-weight: bold; /* 字体加粗 */  
    display: flex; /* 弹性布局 */  
    justify-content: center; /* 主轴居中对齐 */  
    align-items: center; /* 交叉轴居中对齐 */  
    margin-bottom: 15px; /* 下边距15px */  
    position: relative; /* 相对定位 */  
    overflow: hidden; /* 溢出内容隐藏 */  
}  
  
/* 数字容器内的span元素样式 */  
.nums span {  
    position: absolute; /* 绝对定位 */  
    transform-origin: bottom center; /* 变换原点设置在底部中心 */  
    transform: rotate(120deg); /* 旋转120度 */  
}  
  
/* 数字进入动画 */  
.nums span.in {  
    animation: goIn 0.5s ease-in-out; /* 应用名为goIn的动画,持续0.5秒,使用ease-in-out缓动函数 */  
}  
  
/* 数字退出动画 */  
.nums span.out {  
    animation: goOut 0.5s ease-in-out; /* 应用名为goOut的动画,持续0.5秒,使用ease-in-out缓动函数 */  
}  
  
/* 最终显示的内容容器样式 */  
.final {  
    position: absolute; /* 绝对定位 */  
    top: 0; /* 顶部对齐 */  
    left: 0; /* 左侧对齐 */  
    width: 100%; /* 宽度100% */  
    text-align: center; /* 文本居中对齐 */  
    transform: scale(0); /* 缩放到0 */  
}  
  
/* 最终显示内容显示动画 */  
.final.show {  
    transform: scale(1); /* 缩放到1 */  
    animation: show 0.3s ease-in; /* 应用名为show的动画,持续0.3秒,使用ease-in缓动函数 */  
}  
  
/* 重播按钮样式 */  
.replay {  
    width: 100%; /* 宽度100% */  
    background-color: #5696ff; /* 背景颜色 */  
    color: #fff; /* 字体颜色 */  
    border: none; /* 无边框 */  
    padding: 10px 0; /* 上下内边距10px */  
    margin-top: 20px; /* 上边距20px */  
    cursor: pointer; /* 鼠标悬停时变为手形图标 */  
}

/* 隐藏动画:从正常大小逐渐缩小到0 */  
@keyframes hide {  
    0% {  
        transform: scale(1); /* 动画开始时,元素为正常大小 */  
    }  
  
    100% {  
        transform: scale(0); /* 动画结束时,元素缩小到0 */  
    }  
}  
  
/* 显示动画:从0开始放大,稍微超过正常大小,然后回到正常大小 */  
@keyframes show {  
    0% {  
        transform: scale(0); /* 动画开始时,元素为0大小 */  
    }  
  
    80% {  
        transform: scale(1.4); /* 动画过程中,元素放大到1.4倍大小 */  
    }  
  
    100% {  
        transform: scale(1); /* 动画结束时,元素回到正常大小 */  
    }  
}  
  
/* 进入动画:数字从旋转120度逐渐恢复到0度 */  
@keyframes goIn {  
    0% {  
        transform: rotate(120deg); /* 动画开始时,元素旋转120度 */  
    }  
  
    30% {  
        transform: rotate(-20deg); /* 动画过程中,元素旋转到-20度 */  
    }  
  
    60% {  
        transform: rotate(10deg); /* 动画过程中,元素旋转到10度 */  
    }  
  
    90%,  
    100% {  
        transform: rotate(0); /* 动画结束前和结束时,元素旋转到0度 */  
    }  
}  
  
/* 退出动画:数字从0度逐渐旋转到-120度 */  
@keyframes goOut {  
    0%,  
    30% {  
        transform: rotate(0); /* 动画开始时和动画过程中,元素为0度 */  
    }  
  
    60% {  
        transform: rotate(20deg); /* 动画过程中,元素旋转到20度 */  
    }  
  
    100% {  
        transform: rotate(-120deg); /* 动画结束时,元素旋转到-120度 */  
    }  
}
// 获取所有类名为'nums'的元素下的'span'子元素,并将它们存储在'nums'数组中  
const nums = document.querySelectorAll('.nums span');  
  
// 获取类名为'counter'的元素,并存储在'counter'变量中  
const counter = document.querySelector('.counter');  
  
// 获取类名为'final'的元素,并存储在'final'变量中  
const final = document.querySelector('.final');  
  
// 获取类名为'replay'的元素,并存储在'replay'变量中  
const replay = document.querySelector('.replay');  
  
// 重置函数:将界面重置为初始状态  
function reset() {  
    // 移除'counter'元素上的'hide'类,使其可见  
    counter.classList.remove('hide');  
    // 移除'final'元素上的'show'类,使其隐藏  
    final.classList.remove('show');  
    // 遍历'nums'数组中的每个元素  
    nums.forEach(num => {  
        // 移除当前'span'元素上的所有类名  
        num.className = '';  
    });  
    // 给'nums'数组中的第一个'span'元素添加'in'类,使其开始进入动画  
    nums[0].classList.add('in');  
}  
  
// 运行函数:为'nums'数组中的每个'span'元素添加动画结束事件监听器  
function run() {  
    nums.forEach((num, index) => {  
        // 当动画结束时触发此函数  
        num.addEventListener('animationend', e => {  
            // 如果动画名称为'goIn'且当前元素不是最后一个元素  
            if (e.animationName === 'goIn' && index !== nums.length - 1) {  
                // 移除当前元素的'in'类,使其停止进入动画  
                num.classList.remove('in');  
                // 给当前元素添加'out'类,使其开始退出动画  
                num.classList.add('out');  
            }   
            // 如果动画名称为'goOut'且当前元素有下一个兄弟元素  
            else if (e.animationName === 'goOut' && num.nextElementSibling) {  
                // 给下一个兄弟元素添加'in'类,使其开始进入动画  
                num.nextElementSibling.classList.add('in');  
            }   
            // 如果以上条件都不满足(即最后一个元素动画结束)  
            else {  
                // 隐藏'counter'元素  
                counter.classList.add('hide');  
                // 显示'final'元素  
                final.classList.add('show');  
            }  
        })  
    })  
}  
  
// 当'replay'元素被点击时,触发重置和运行函数  
replay.addEventListener('click', function () {  
    reset();  
    run();  
});  
  
// 页面加载完成后立即运行run函数  
run();

实现思路拆分

*{
    margin: 0;
    padding: 0;
}

这段代码是设置所有元素的外边距和内边距为0,这是为了避免不同浏览器的默认样式差异。

body{
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background: linear-gradient(to bottom,#fdfbfb,#ebedee);
}

这段代码是设置页面的背景颜色为从上到下的渐变色,同时将页面垂直居中。

.container{
  position: relative;
}

这段代码是设置一个相对定位的容器,用于包含倒计时数字区域和倒计时结束区域。

.counter{
  width: 100%;
  text-align: center;
}

这段代码是设置倒计时数字区域的样式,包括宽度和居中对齐。

.counter.hide{
  transform: scale(0);
  animation: hide 0.2s ease-out;
}

这段代码是设置倒计时数字区域隐藏时的样式,使用transform属性将其缩放为0,并使用动画效果使其缓慢消失。

.nums{
  width: 250px;
  height: 80px;
  color: #5696ff;
  font-size: 80px;
  font-weight: bold;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 15px;
  position: relative;
  overflow: hidden;
}

.nums span{
  position: absolute;
  transform-origin: bottom center;
  transform: rotate(120deg);
}

这段代码是设置倒计时数字的样式,包括宽度、高度、颜色、字体大小、字体粗细、居中对齐、相对定位和溢出隐藏。同时,使用绝对定位和transform属性将数字旋转120度,为后续动画效果做准备。

.nums span.in{
  animation: goIn 0.5s ease-in-out;
}

这段代码是设置数字进入时的动画效果,使用animation属性指定动画名称、时长和加速减速方式。

.nums span.out{
  animation: goOut 0.5s ease-in-out;
}

这段代码是设置数字离开时的动画效果,同样使用animation属性指定动画名称、时长和加速减速方式。

.final{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  text-align: center;
  transform: scale(0);
}

这段代码是设置倒计时结束区域的样式,包括相对定位、宽度、居中对齐和缩放为0,使其默认隐藏。

.final.show{
  transform: scale(1);
  animation: show 0.3s ease-in;
}

这段代码是设置倒计时结束区域显示时的样式,使用transform属性将其缩放为1,并使用动画效果使其缓慢出现。

.replay{
  width: 100%;
  background-color: #5696ff;
  color: #fff;
  border: none;
  padding: 10px 0;
  margin-top: 20px;
  cursor: pointer;
}

这段代码是设置重新开始按钮的样式,包括宽度、背景颜色、字体颜色、边框、内边距、上边距和鼠标指针样式。

@keyframes hide {
  0%{
    transform: scale(1);
  }
  100%{
    transform: scale(0);
  }
}

@keyframes show {
  0%{
    transform: scale(0);
  }
  80%{
    transform: scale(1.4);
  }
  100%{
    transform: scale(1);
  }
}

@keyframes goIn {
  0%{
    transform: rotate(120deg);
  }
  30%{
    transform: rotate(-20deg);
  }
  60%{
    transform: rotate(10deg);
  }
  90%,100%{
    transform: rotate(0);
  }
}

@keyframes goOut {
  0%,30%{
    transform: rotate(0);
  }
  60%{
    transform: rotate(20deg);
  }
  100%{
    transform: rotate(-120deg);
  }
}

这段代码是定义了四个动画效果,分别是倒计时数字区域的隐藏动画、倒计时结束区域的显示动画、数字进入动画和数字离开动画。这些动画效果在前面的代码中被引用和使用。

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值