【项目实战】基于Vue3+Vant3造一个网页版的类掘金app项目 - 抽奖十连抽加动画

836 阅读4分钟

「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战

前言

大家好,继续来分享我们的掘金项目实战。昨天我们已经实现了幸运抽奖的免抽和单抽功能。最后还将抽奖结果以弹窗的形式展示给用户,但是还有一些不足,在昨天的文章结尾也已经提到了,就是在点击了抽奖按钮时,幸运转盘并没有转起来,而是过了一会啪的就弹出了抽奖结果,这显然是很不友好的,今天我们就来给转盘添加上动画效果,让用户知道我们的幸运转盘是在转动的。另外还有一个十连抽还没有实现,我们也在这次分享中一并实现。本次分享要实现的功能:

  • 幸运转盘动画效果
  • 十连抽及结果展示

幸运转盘动画效果

刚开始没有一点点思路,不知道该如何给幸运转盘添加动画效果,也看不到官方的源码真是一头雾水。后来灵机一动:用软件把动画效果录制下来,别说还真有发现(如下图)。其实就是轮询给每个奖品添加一个chosen的class,而这个类中只有一个background,也就是说轮询更换奖品的背景色就可以实现了。于是思路就打开了。 test2.gif 实现起来也很简单

  • 首先经过分析发现每个奖品对应的元素都会有两个相同的类名:turntable-item和item
  • 我们只需要用document.querySelectorAll获取到所有的奖品元素
  • 然后再用一个定时器setInterval加计数器counter来循环给每个奖品添加额外的chosen类(即添加背景)即可,但需要注意的是在给某个奖品添加chosen之前必须先把其它奖品的背景恢复为原来的状态
  • 另外还需要注意一点,有的奖品是需要抽多少次才能解锁的,因此在这个奖品还没解锁前,幸运转盘转动时应该是跳过该奖品的
    • 实现起来也很简单,就是在用v-for初始化奖品元素时再添加一个额外的locked属性,赋值为unlock_count
    • 如果unlock_count大于0 就跳过该奖品 核心代码接效果图如下:
<div
   v-for="item in lottery"
   :key="item.lottery_id"
   class="turntable-item item"
   :locked="item.unlock_count" <!--新增locked属性-->
 >
 <!--省略。。。。-->
 </div>
const animate = function () {
     const items = document.querySelectorAll(".turntable-item.item");
     let counter = 0;
     let interval = setInterval(() => {
       items.forEach((el) => {
         el.className = "turntable-item item";
       });
       let locked = items[counter].getAttribute("locked");
       if (locked == 0) {//跳过未解锁的奖品
         items[counter].className = "turntable-item item chosen";
       }
       counter++;
       if (counter === items.length) {
         counter = 0;
       }
     }, 100);
     return interval;
   };

test2.gif

十连抽

十连抽功能实现起来也很简单,经过对官网分析发现,十连抽跟单抽调用的后台api不同,十连抽调用的是一个名为ten_draw的接口,post请求,返回结果是一个长度为10的数组。因此后端需要再单独封装一个十连抽ten_draw的api。另外返回结果的弹出框跟单抽的也不同,单抽只有一个结果,直接把奖品信息作为message传给vant的Dialog组件即可。但由于十连抽返回的是一组10个结果,因此对弹出窗的信息还需要进行单独处理,让10个结果都能呈现出来 源码及效果图:

const draw = function (type) {
     if (type === 0) {
       //免抽一次
       let interval = animate();
       api.drawFree().then((res) => {
         clearInterval(interval);
         const title = `恭喜抽中${res.data.lottery_name}`;
         const message = `<div><img src="${res.data.lottery_image}" alt="image" /></div>;`;
         showResult(title, message);
       });
     } else if (type === 1) {
       //单抽消耗200矿石
       let interval = animate();
       api.draw1().then((res) => {
         clearInterval(interval);
         const title = `恭喜抽中${res.data.lottery_name}`;
         const message = `<div><img src="${res.data.lottery_image}" alt="image" /></div>;`;
         showResult(title, message);
       });
     } else if (type === 10) {
       //十连抽
       let interval = animate();
       api.tenDraw().then((res) => {
         clearInterval(interval);
         const message = '<div class="gifts">';
         res.data.forEach((item) => {
           message += `<div class="gift"><img src="${item.lottery_image}" class="gift-img">
           <p class="gift-name">${item.lottery_name}</p>
       </div>`;
         });
         message += "</div>";
         showResult("十连抽奖励", message);
       });
     }
  };

test2.gif

总结

今天的分享中我们实现了幸运转盘的动画效果,同时还实现了十连抽及相关结果展示,为了实现这个抽奖功能,已经损耗我1个w多矿石了,哈哈哈。关于这个抽奖页面中的核心功能已经基本实现了。接下来就是一些边边角角的修饰了,比如幸运值展示,中奖播报以及大奖围观等。今天的分享就到这里了,欢迎小伙伴们点赞加关注哦!