H5红包雨效果

 HTML核心代码:

<ul class="red_packet" id="red_packet">
      <li
        v-for="(item, index) in liParams"
        :key="index"
        :style="{
          left: item.left,
          animationDuration: item.durTime,
        }"
        class="move_1"
        :data-index="index"
        @webkitAnimationEnd="removeDom"  //没点击的红包到底部消除节点
        :class="{ active: selectedItems.includes(item.activeId) }"  //点击红包后消失
        @click.prevent="onClick(item.activeId)"
      >
        <span>
          <i
            :style="{
              transform: item.transforms,
              'background-image':
                'url(' +
                (activeItems.includes(item.activeId)  //点击前红包的图片和点击后红包的图片
                  ? prizeInfo.redPacketImageClick
                  : prizeInfo.redPacketImageNoClick) +
                ')',
            }"
          ></i>
        </span>
      </li>
    </ul>

TS代码:

export default class RedEnvelopeRain extends Mixins(Mixin){
  liParams: Array<{
    left?: string;
    cls?: string;
    transforms?: string;
    durTime?: string;
    activeId: number;
  }> = []; //红包item数组
  timer = 0; //红包下落
  duration = 0; // 游戏时间
  countdown = 5; //倒计时5秒
  priczeNum = 0; //点击红包的个数
  selectedItems: Array<number> = []; //点击红包消失id数组
  activeItems: Array<number> = []; //点击红包切换图片的数组
  itemId = 0; //初始红包下标0开始计算
  prizeInfo: cms.ActivityInfoDto = { menuType: "" }; //接口返回信息
  mounted(): void {
   this.startRedPacket();
  }

   /**
   * 开启动画
   */
  startRedPacket(): void {
    let win = document.documentElement.clientWidth || document.body.clientWidth;
    let left = Math.random() * (win - 50) + 0;
    let rotate = 0; // 旋转角度
    let scales = (Math.random() * (12 - 8 + 1) + 8) * 0.1; // 图片尺寸
    let durTime = Math.random() * (2.5 - 1.2 + 1) + 2 + "s"; // 时间 1.2和1.2这个数值保持    一样
    this.itemId++;
    this.liParams.push({
      left: left + "px",
      cls: "move_1",
      transforms: "rotate(" + rotate + ") scale(" + scales + ")",
      durTime: durTime,
      activeId: this.itemId,
    });

    let onceTime =
      this.duration /
      (this.prizeInfo.redPacketNum    //  游戏总时间(接口返回)/ 红包数量 
        ? this.prizeInfo.redPacketNum
        : this.duration);
    this.timer = Number(
      setTimeout(() => {
        this.startRedPacket();
      }, onceTime) //多少时间执行一次
    );
  }


  /*
   * 点击红包
   */
 onClick(id: number): void {
    if (this.selectedItems.includes(id) || this.activeItems.includes(id)) {
      //如果当前红包已点击红包就禁止连续点击
      return;
    }
    this.priczeNum++;
    this.activeItems.push(id);
    let timer = setTimeout(() => {
      //设置定时器当红包展示打开过程后才消失。
      this.selectedItems.push(id);
      clearTimeout(timer);
    }, 200);
  }

  /**
   * 回收dom节点
   */
  removeDom(e: { currentTarget: Element }): void {
    let target = e.currentTarget;
    if (target) {
      (document.querySelector("#red_packet") as Element).removeChild(target);
    }
    return;
  }
}

css样式:

 .red_packet {
    display: block;
    position: relative;
    overflow: hidden;
    width: 100%;
    height: 100%;
    i {
      width: 1.1rem;
      height: 1.2rem;
      display: block;
      background-repeat: no-repeat;
      background-size: cover;
    }
    li {
      position: absolute;
      animation: all 3s linear;
      top: -100px;
      z-index: 10;
      &.move_1 {
        -webkit-animation: aim_move 5s linear 1 forwards;
        animation: aim_move 5s linear 1 forwards;
      }
    }
    a {
      display: block;
    }
  }

  .active {
    display: none;
  }

  @keyframes aim_move {
    0% {
      -webkit-transform: translateY(0);
      transform: translateY(0);
    }
    100% {
      -webkit-transform: translateY(120vh);
      transform: translateY(120vh);
    }
  }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值