50个html+css+js项目小练习(二:动画的倒计时效果)

2.animated-navigation

在这里插入图片描述

实现效果:
  • 倒计时321后显示go
  • 数字依次从x轴负方向,顺时针倒下去
    • x=y
    • 第一个数(0,y)—>(-x,0)
  • 第一个数字倒下去的同时,第二个数从x轴正方向升起
    • 第二个数(x,0)—>(0,y)
  • 就像八百一千米体测开始一样😜
实现步骤:
  • 进入页面,显示倒计时321,倒计时时间到,显示Go
  • 点击Ready后,重新倒计时
  • 倒计时升起倒下动画
    • 进入页面后,先让倒计时显示,Go隐藏
    • 第一个数3升起后,判断
      • 动画= 升起动画goIn
      • 当前数组元素的索引0 ! = 当前数组元素3
      • 第一个数3倒下goOut
    • 第一个数3倒下后,判断
      • 动画= 升起动画goOut
      • num.nextElementSibling = < span class=“out”>2< /span>
      • 第二个数2升起goIn
    • 第二个数2升起后,判断
      • 动画= 升起动画goIn
      • 当前数组元素的索引1 ! = 当前数组元素2
      • 第二个数2倒下goOut
    • 第二个数2倒下后,判断
      • 动画= 升起动画goOut
      • num.nextElementSibling = 1
      • 第三个数1升起goIn
    • 第三个数1升起后,判断
      • 动画 = 升起动画goIn
      • 当前数组元素的索引1 = 当前数组元素1 不满足条件
      • 属于else:让倒计时隐藏,让GO出现
知识点:
使用classList添加class、删除class、查询class:
  • add( 新):添加一个或多个类名,已存在,取消添加;
    • num[0].classList.add(‘in’):给第一个num添加类名为in的类。
  • contains(旧):检查类属性中有无指定的类名,返回true 、false;
  • remove(旧):移除已经存在的类名;
  • toggle(类名);classList中存在指定的值,则删除它,否则,添加它;
    • 只有一个参数时:切换 class的值; 🎉
    • 类存在:删除它,返回false;不存在:添加它,返回true。
    • 第二个参数:计算结果: true,添加指定的类;计算结果 : false,则删除此类名。
    • boxesContainer.classList.toggle(‘big’)):
      • big被设置则删除它big,否则添加它big。
  • classList.replace( 旧,新 ):类名替换。
行内块、行内、块级元素
1.块级元素(可独块)block
  • 独占一行
  • 宽度:父元素宽度(默认)
  • 高度:由内容撑开(默认)
  • 可设置宽高
2.行内元素(不可多行)inline
  • 一行显多个,不换行
  • 宽度由内容撑开
  • 不可设宽高
  • (水平方向)padding和margin可以设置
3.行内块元素(可多行内块)inline-block
  • 一行多个(中间存在间隙)
  • 可设宽高
nextSibling 和nextElementSibling:
1.nextSibling
  • 返回指定节点之后的下一个兄弟节点。
    • 相同节点树层中的下一个节点。
  • 包括文本节点、注释节点(回车、换行、空格、文本)
  • 空格、回车 = 文本,也属于文本。
2.nextElementSibling
  • 只返回元素节点之后的下一个兄弟元素节点
    • 相同节点树层中的下一个元素节点
  • 不包括文本节点、注释节点
  • 只读属性
其他知识点:
  • value:用于设置或者返回属性的值。
  • 在运行倒计时,要设置遍历倒计时321,将属性值都设空;否则第二次执行时,会暂停在第一次的最后结果0。🎉
  * {
      box-sizing: border-box;
    }
    body {
      font-family: 'Roboto', sans-serif;
      margin: 0;
      height: 100vh;
      overflow: hidden;
      background-color: rgb(161, 158, 228);
    }
    h4 {
      font-size: 20px;
      margin: 5px;
      /* 所有字母变大写 */
      text-transform: uppercase;
    }
    .counter,
    .final {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      text-align: center;
    }
    .counter.hide {
      transform: translate(-50%, -50%) scale(0);
      animation: hide .2s ease-out;
    }
    @keyframes hide {
      0% {
        transform: translate(-50%, -50%) scale(1);
      }
      100% {
        transform: translate(-50%, -50%) scale(0);
      }
    }
    .final {
      transform: translate(-50%, -50%) scale(0);
    }
    .final.show {
      transform: translate(-50%, -50%) scale(1);
      animation: show .2s ease-out;
    }
    @keyframes show {
      0% {
        transform: translate(-50%, -50%) scale(0);
      }
      30% {
        transform: translate(-50%, -50%) scale(1.4);
      }
      100% {
        transform: translate(-50%, -50%) scale(1);
      }
    }
    .nums {
      color: rgb(53, 15, 203);
      font-size: 50px;
      position: relative;
      overflow: hidden;
      width: 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 .5s ease-in-out;
    }
    .nums span.out {
      animation: goOut .5s ease-in-out;
    }
    @keyframes goIn {
      0% {
        transform: translate(-50%, -50%) rotate(120deg);
      }
      30% {
        /* 会有回弹的感觉由-20--10--0 */
        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: rgb(95, 39, 193);
      border-radius: 3px;
      /* 去掉button的边框黑线 */
      border: none;
      color: aliceblue;
      padding: 5px;
      text-align: center;
      display: inline-block;
      cursor: pointer;
      transition: all .3s;
    }
    #replay span {
      cursor: pointer;
      display: inline-block;
      position: relative;
      transition: .3s;
    }
    #replay span::after {
      /* 在span后面添加》 */
      content: '\00bb';
      position: absolute;
      opacity: 0;
      top: 0;
      right: -20px;
      transition: .5s;
    }
    #replay:hover span {
      padding-right: 25px;
    }
    #replay:hover span::after {
      opacity: 1;
      right: 0;
    }
<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>
  <div class="final">
    <h1>GO</h1>
    <button id="replay">
      <span>Replay</span>
    </button>
</div>
const nums = document.querySelectorAll('.nums span')
const counter = document.querySelector('.counter')
const final = document.querySelector('.final')
const replay = document.querySelector('#replay')
// 隐藏和显示切换
function resetDOM () {
      // 让倒计时显示,让Go隐藏
      counter.classList.remove('hide')
      final.classList.remove('show')
      // 遍历倒计时321,将属性值都设空,否则第二次执行的时候,会暂停在第一次的最后结果0
      nums.forEach((num) => {
        num.classList.value = ''
      })
      num[0].classList.add('in')
}
// 页面一加载出来就要显示倒计时动画
runAnimation()

    // 倒计时移动动画
function runAnimation () {
      nums.forEach((num, idx) => {
        const nextToLast = nums.length - 1
        num.addEventListener('animationend', (e) => {
          // 动画名=goIn且当前数组元素的索引!=当前数组元素
          if (e.animationName === 'goIn' && idx !== nextToLast) {
            // console.log(idx)
            // console.log(nextToLast)
            // 删除in类名,添加out类名(倒计时倒下)
            num.classList.remove('in')
            num.classList.add('out')
            // 如果动画名=goOut并且等于返回下一个兄弟元素节点
          } else if (e.animationName === 'goOut' && num.nextElementSibling) {
            console.log(num.nextElementSibling)
            // 给下一个数添加动画in(倒计时升起)
            num.nextElementSibling.classList.add('in')
          } else {
            // 让倒计时隐藏,让GO出现
            counter.classList.add('hide')
            final.classList.add('show')
          }
        })
      })
}
// 点击Replay按钮,重新执行倒计时动画
replay.addEventListener('click', () => {
      resetDOM()
      runAnimation()
})

在这里插入图片描述
倒计时结束后:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值