前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【demo50】倒计时动画

【demo50】倒计时动画

作者头像
客怎眠qvq
发布2022-11-01 16:26:39
6000
发布2022-11-01 16:26:39
举报
文章被收录于专栏:某菜鸟の小屋

📢前言

代码取自开源项目50projects50days,用作个人学习和巩固三件套的知识,增加了注释,可能会有小改动。

在线演示地址

📝实现思路及效果

💻代码

index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>倒计时动画</title>
  <link rel="shortcut icon" href="../logo.svg">
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <!-- 计数 倒数3 2 1 的盒子 -->
  <div class="counter">
    <div class="nums">
      <!-- 初始化 第一个数一定是倒计时的第一个数 -->
      <span class="in">3</span>
      <span>2</span>
      <span>1</span>
      <span>0</span>
    </div>
    <h4>Get Ready</h4>
  </div>


  <!-- 添加js交互 点击replay按钮 重新倒计时 -->
  <div class="final">
    <h1>GO</h1>
    <button id="replay">
      <span>Replay</span>
    </button>
  </div>
  <script src="script.js"></script>
</body>

</html>

style.css

代码语言:javascript
复制
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');

* {
    box-sizing: border-box;
}

body {
    font-family: 'Roboto', sans-serif;
    margin: 0;
    height: 100vh;
    overflow: hidden;
}

h4 {
    font-size: 20px;
    margin: 5px;
    /* 文本大小写转换  uppercase 强制该文本全部大写 */
    text-transform: uppercase;
}

.counter {
    /* 经典的 盒子在网页的 中心位置显示设置 */
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
}

.counter.hide {
    transform: translate(-50%, -50%) scale(0);
    /* 动画 淡出(慢速结束) 控制 3 2 1 倒计时的转换和隐藏*/
    animation: hide 0.2s ease-out;
}

@keyframes hide {
    0% {
        transform: translate(-50%, -50%) scale(1);
    }
    100% {
        transform: translate(-50%, -50%) scale(0);
    }
}

.final {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    text-align: center;
}

.final.show {
    transform: translate(-50%, -50%) scale(1);
    animation: show 0.2s ease-out;
}

@keyframes show {
    0% {
        transform: translate(-50%, -50%) scale(0);
    }

    30% {
        transform: translate(-50%, -50%) scale(1.5);
    }

    100% {
        transform: translate(-50%, -50%) scale(1);
    }
}

.nums {
    color: #3498db;
    font-size: 50px;
    position: relative;
    overflow: hidden;
    widows: 250px;
    height: 50px;
}

.nums span {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(120deg);
    transform-origin: bottom center;
}

.nums span.in {
    transform: translate(-50%, -50%) rotate(0deg);
    animation: goIn 0.5s ease-in-out;
    /* 淡入淡出 */
}
.nums span.out {
    animation: goOut 0.5s ease-in-out;
}

/* 实现旋转 左右摆动的视觉效果 */
@keyframes goIn {
    0% {
        transform: translate(-50%, -50%) rotate(120deg);
    }
    30% {
        transform: translate(-50%, -50%) rotate(-20deg);
    }
    60% {
        transform: translate(-50%, -50%) rotate(10deg);
    }
    100% {
        transform: translate(-50%, -50%) rotate(0deg);
    }
}

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

#replay {
    background-color: #3498db;
    border-radius: 3px;
    border: none;
    color: aliceblue;
    padding: 5px;
    text-align: center;
    display: inline-block;
    cursor: pointer;
    transition: all 0.3s;
}

#replay span {
    cursor: pointer;
    display: inline-block;
    position: relative;
    transition: 0.3s;
}

script.js

代码语言:javascript
复制
const nums = document.querySelectorAll(".nums span");
const counter = document.querySelector(".counter");
const finalMessage = document.querySelector(".final");
const replay = document.querySelector("#replay");

runAnimation();

function resetDOM() {
  // 使用元素的 classList 属性可以访问或添加、删除及修改元素的 class 属性。需注意的是,支持 classList 属性的浏览器主要是一些较新版的,例如:IE10+、Firefox3.6+。使用 classList 属性访问 class 属性的格式如下:element.classList

  // classList 是一个只读属性,其返回的值为 DOMTokenList,其中包含了元素的所有 class 属性,不同的 class 属性之间使用一空格分隔。

  //  classList 调用 add()、remove() 和 toggle() 等方法可以添加、移除或修改元素 class 属性
  counter.classList.remove("hide");
  finalMessage.classList.remove("show");

  nums.forEach((num) => {
    num.classList.value = "";
  });
  nums[0].classList.add("in");
}

function runAnimation() {
  nums.forEach((num, idx) => {
    const nextToLast = nums.length - 1;
    // nextElementSibling 返回当前元素在其父元素的子元素节点中的后一个元素节点,如果该元素已经是最后一个元素节点,则返回null,该属性是只读的.
    num.addEventListener("animationend", (e) => {
      if (e.animationName === "goIn" && idx !== nextToLast) {
        num.classList.remove("in");
        num.classList.add("out");
      } else if (e.animationName === "goOut" && num.nextElementSibling) {
        num.nextElementSibling.classList.add("in");
      } else {
        // 隐藏计数 显示replay按钮
        counter.classList.add("hide");
        finalMessage.classList.add("show");
      }
    });
  });
}

replay.addEventListener("click", () => {
  resetDOM();
  runAnimation();
});
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 📢前言
  • 📝实现思路及效果
  • 💻代码
    • index.html
      • style.css
        • script.js
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档