动画animationend 事件在活动红包雨中的应用

100 篇文章 6 订阅
21 篇文章 0 订阅

最近搞了一个类似于红包雨的活动,研究了一下红包雨的实现方式。其中animationend 事件在 CSS 动画完成后触发,这个是我首次接触到的,所以就准备记录下来。
红包雨代码如下:

<template>
  <div class="ser_home">
    <ul class="red_packet" id="red_packet">
      <template v-for="(item, index) in liParams">
        <li
          :style="{
            left: item.left,
            animationDuration: item.durTime,
            webkitAnimationDuration: item.durTime,
          }"
          :class="item.cls"
          :data-index="index"
          @animationEnd="removeDom"
          :key="index"
        >
          <a href="javascript:;">
            <i
              :style="{
                transform: item.transforms,
                webkitTransform: item.transforms,
              }"
            ></i>
          </a>
        </li>
      </template>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      liParams: [],
      timer: null,
      duration: 10000, // 定义时间  红包雨持续的时间
    };
  },
  mounted() {
    this.startRedPacket();
    // 持续多长时间之后结束红包雨,清除这个方法,
    setTimeout(() => {
      // 多少时间结束
      clearTimeout(this.timer);
      console.log("结束定时器");
      return;
    }, this.duration);
  },
  methods: {
    /**
     * 开启动画
     */
    startRedPacket() {
      let win =
        document.documentElement.clientWidth || document.body.clientWidth;
      let left = parseInt(Math.random() * (win - 50) + 0);

      let rotate = parseInt(Math.random() * (45 - -45) - 45) + "deg"; // 旋转角度
      let scales = (Math.random() * (12 - 8 + 1) + 8) * 0.1; // 图片尺寸
      let durTime = Math.random() * (2.5 - 1.2 + 1) + 1.2 + "s"; // 时间  1.2和1.2这个数值保持一样
      console.log(durTime);
      this.liParams.push({
        left: left + "px",
        cls: "move_1",
        transforms: "rotate(" + rotate + ") scale(" + scales + ")",
        durTime: durTime,
      });

      // 持续多长时间之后结束红包雨,清除这个方法,
      // setTimeout(() => {
      //   // 多少时间结束
      //   clearTimeout(this.timer);
      //   console.log('结束定时器');
      //   return;
      // }, this.duration);

      // 每个100微秒去执行startRedPacket这个方法
      this.timer = setTimeout(() => {
        this.startRedPacket();
      }, 100);
    },
    /**
     * 回收dom节点
     */
    removeDom(e) {
      let target = e.currentTarget;
      document.querySelector("#red_packet").removeChild(target);
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.ser_home {
  width: 100%;
  height: 100%;
}

.red_packet {
  display: block;
  position: relative;
  // overflow: hidden;
  width: 100%;
  height: 100%;
  i {
    width: 48px;
    height: 69px;
    display: block;
    // background: url("../assets/repacked.png") no-repeat;
    background: url("../assets/repacked.png");
    background-size: 50px 50px;
    background-repeat: no-repeat;
  }
  li {
    position: absolute;
    animation: all 3s linear;
    top: -100px;
    z-index: 10;
    list-style: none;
    // animation的具体使用可以自己百度一下
    &.move_1 {
      -webkit-animation: aim_move 5s linear 1 forwards;
      animation: aim_move 5s linear 1 forwards;
    }
  }
  a {
    display: block;
  }
}

@keyframes aim_move {
  0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
  // vh:1vh等于视口高度的1%。
  // 视口单位中的“视口”,桌面端指的是浏览器的可视区域;移动端指的就是Viewport中的Layout Viewport, 
  // “视区”所指为浏览器内部的可视区域大小,即window.innerWidth/window.innerHeight大小,不包含任务栏标题栏以及底部工具栏的浏览器区域大小。。
  100% {
    -webkit-transform: translateY(120vh);
    transform: translateY(120vh);
  }
}
</style>

其中这段代码中的 @animationEnd=“removeDom” 是重点

      <li
          :style="{
            left: item.left,
            animationDuration: item.durTime,
            webkitAnimationDuration: item.durTime,
          }"
          :class="item.cls"
          :data-index="index"
          @animationEnd="removeDom"
          :key="index"
        >

animationend 事件在 CSS 动画完成后触发

CSS 动画播放时,会发生以下三个事件:

  • animationstart - CSS 动画开始后触发
  • animationiteration - CSS 动画重复播放时触发
  • animationend - CSS 动画完成后触发

在动画播放结束之后移除该元素,很好的一个思路。
而且其中关于css3中的动画属性animation和transform应用也值得借鉴。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值