移动端H5 vue实现九宫格抽奖动画

<div class="wrapper_circle">
        <div class="circle_prize">
          <div
            v-for="(item, index) in prizeList9"
            :key="index"
            :class="prizeselected == index ? 'selected' : ''"
          >
            <div v-if="index !== 4">
              <div class="img_box">
                <img :src="item.icon" alt="" srcset="" />
              </div>
              <div class="prize_level">{{ item.name1 }}</div>
              <div class="prize_name">{{ item.name2 }}</div>
            </div>
            <div
              v-else
              @click="doPrize"
              :class="win_flag ? 'selected' : ''"
            ></div>
          </div>
        </div>
        <!-- <img src="../assets/images/index_bg.png" alt="" /> -->
      </div>
.wrapper_circle {
    width: 100vw;
    height: 127vw;
    margin: 0 auto;
    background: url("../assets/images/index_bg.png") no-repeat center;
    background-size: 105% 100%;
    padding: 10vw 9vw;
    .circle_prize {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      justify-content: space-between;
      & > div {
        width: 27vw;
        height: 27vw;
        background: url("../assets/images/block1.png") no-repeat;
        background-size: 100% 100%;
        margin-bottom: 0.5vw;
      }
      & > div {
        & > div {
          width: 100%;
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: center;
          flex-direction: column;
        }
        .img_box {
          width: 10vw;
          height: 10vw;
        }
        .prize_level {
          color: #850000;
          font-size: 14px;
          font-weight: bold;
        }
        .prize_name {
          color: #da5400;
          font-size: 12px;
        }
      }
      & > div.selected {
        background: url("../assets/images/block2.png") no-repeat;
        background-size: 100% 100%;
      }
      & > div:nth-child(5) {
        & > div {
          background: url("../assets/images/draw_btn.png") no-repeat;
          background-size: 100% 100%;
        }
        .selected {
          background: url("../assets/images/draw_btn2.jpg") no-repeat;
          background-size: 100% 100%;
        }
      }
    }

    img {
      width: 100%;
      position: relative;
    }
  }
prizeList: [
        {
          img: "xxx",
          prizeLevel: "三等奖",
          prizeName: "0.18元现金红包",
        },
        {
          img: "xxx",
          prizeLevel: "一等奖",
          prizeName: "5000元金元宝",
        },
        {
          img: "xxxx",
          prizeLevel: "幸运奖",
          prizeName: "京东优惠券",
        },
        {
          img: "xxx",
          prizeLevel: "",
          prizeName: "更多好礼",
        },
        {},
        {
          img: "xxx",
          prizeLevel: "三等奖",
          prizeName: "0.58元现金红包",
        },
        {
          img: "xxxx",
          prizeLevel: "幸运奖",
          prizeName: "京东优惠券",
        },
        {
          img: "xxxx",
          prizeLevel: "三等奖",
          prizeName: "1.18元现金红包",
        },
        {
          img: "xxxx",
          prizeLevel: "二等奖",
          prizeName: "华为运动手环",
        },
      ],
      prizeselected: undefined,
      /*
       * 页面中奖项的实际数组下标
       * 0  1  2
       * 3     5
       * 6  7  8
       * 所以得出转圈的执行顺序数组为 ↓
       */
      order_arr: [0, 1, 2, 5, 8, 7, 6, 3],
      // 抽奖状态,是否转完了
      isTurnOver: true,
      /*
       * 数组的长度就是最多所转的圈数,最后一圈会转到中奖后的位置
       * 数组里面的数字表示从一个奖品跳到另一个奖品所需要的时间
       * 数字越小速度越快
       * 想要修改圈数和速度的,更改数组个数和大小即可
       */
      num_interval_arr: [100, 90, 80, 100, 200],
      prizeList9: [],
      // 中奖信息
      prizeInfo: {},
//1.第一步:先处理获取到的奖项数组,给下标为4的添加空对象
this.prizeList.splice(4, 0, {});
//2.第二步:在抽奖的时候把抽奖得到的对象保存下来,并将对应的id保存
this.prizeInfo = res.data.data;
let prize_id = _this.prizeInfo.prizeId;
 _this.lottery(prize_id);
//3.第三步:处理对应的动画效果
// 转圈
    lottery(prize_id) {
      let num_interval_arr = this.num_interval_arr;
      let order_arr = this.order_arr;
      // 旋转的总次数
      let sum_rotate = num_interval_arr.length;
      // 每一圈所需要的时间
      let interval = 0;
      num_interval_arr.forEach((delay, index) => {
        setTimeout(() => {
          this.rotateCircle(delay, index + 1, sum_rotate, prize_id, order_arr);
        }, interval);
        //因为每一圈转完所用的时间是不一样的,所以要做一个叠加操作
        interval += delay * 8;
      });
    },
    /*
     * 封装旋转一圈的动画函数,最后一圈可能不满一圈
     * delay:表示一个奖品跳到另一个奖品所需要的时间
     * index:表示执行到第几圈
     * sum_rotate:表示旋转的总圈数
     * prize_id:中奖后的id号
     * order_arr_pre:表示旋转这一圈的执行顺序
     */
    rotateCircle(delay, index, sum_rotate, prize_id, order_arr_pre) {
      // console.log(index)
      let _this = this;
      // 执行顺序数组
      let order_arr = [];
      // 如果转到最后以前,把数组截取到奖品项的位置
      if (index == sum_rotate) {
        let prizeIndex = _this.prizeList9.findIndex(
          (_) => _.prizeId == prize_id
        );
        let orderIndex = this.order_arr.findIndex((_) => _ == prizeIndex);
        order_arr = order_arr_pre.slice(0, orderIndex + 1);
      } else {
        order_arr = order_arr_pre;
      }
      for (let i = 0; i < order_arr.length; i++) {
        setTimeout(() => {
          _this.prizeselected = _this.order_arr[i];
          // 如果转到最后一圈且转完了,并且是非重置圈,把抽奖状态改为已经转完了
          if (index === sum_rotate && i === order_arr.length - 1) {
            _this.isTurnOver = true;
            // _this.win_flag = false;
            setTimeout(() => {
              // 出现奖项的弹窗
              _this.winShow();
            }, 500);
          }
        }, delay * i);
      }
    },
    // 出现中奖的弹窗,这里根据对应的项目处理对应的逻辑
    winShow() {
      // 红包奖
      if (this.prizeInfo.prizeType == 0) {
        this.winFlag = true;
      } else if (this.prizeInfo.prizeType == 1) {
        //虚拟奖券
        // result: "5||http://www.baidu.com||凉茶310ml*12罐 礼盒装植物饮料||(满12元使用)"
        if (this.prizeInfo.result) {
          this.prizeInfo.prizeName1 = this.prizeInfo.result.split("||")[0]; //奖券金额
          this.prizeInfo.prizeName2 = this.prizeInfo.result.split("||")[1]; //奖券链接
          this.prizeInfo.prizeName3 = this.prizeInfo.result.split("||")[2]; //奖券名称
          this.prizeInfo.prizeName4 = this.prizeInfo.result.split("||")[3]; //奖券副标题
          this.prizeInfo.prizeName5 = this.prizeInfo.result.split("||")[4]; //钱的符号
          this.prizeInfo.prizeName6 = this.prizeInfo.result.split("||")[5]; //是否自动跳转 0不自动  1自动
          this.prizeInfo.prizeName7 = this.prizeInfo.result.split("||")[6]; //第三方跳转链接
          if (
            this.prizeInfo.result &&
            this.prizeInfo.result.split("||")[6] != 0
          ) {
            sessionStorage.setItem("isRedirected", "true");
            sessionStorage.setItem("tzUrl", this.prizeInfo.prizeName7);
          }
        }
        this.winFlag3 = true;
        // 1的情况下2秒后关闭弹框 自动跳转到第三方
        if (this.prizeInfo.prizeName6 == 1) {
          setTimeout(() => {
            this.winFlag3 = false;
            window.location.href = this.prizeInfo.prizeName2.replace(
              /\&amp;/g,
              "&"
            );
          }, 2000);
        }
      } else if (this.prizeInfo.prizeType == 2) {
        // 实物奖项
        this.winFlag4 = true;
      }
    },
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容