实现自定义大转盘抽奖

7 篇文章 0 订阅
7 篇文章 0 订阅

转盘抽奖

  • 最近接了个需求实现转盘抽奖活动, 所以就先写了个demo先发出来记录一下
  • 点击开始旋转的按钮是图片
  • 因为奖品是后台配置,所以每一个扇叶(奖品选项)是代码计算出来写的
  • 项目使用vue框架,所以是vue语法
  • 单独封装了game.js, 需要引入到组件

效果

choujiang

开始旋转按钮图片资源
在这里插入图片描述

game.js

 // 游戏
 const game = {
     turntable: null, // 盘子
     angle: 0, // 旋转角度
     lastAngle: 0, // 上次旋转角度
     transitionTime: 6, // 过渡时间 默认6秒
     init(turntable) {
         this.turntable = turntable
         this.turntable.style.transition = `all ${this.transitionTime}s`
     },
     rotate(angle, callback) {
         const defaultAngle = 3600 // 默认先转6圈
         this.angle += defaultAngle + angle - this.lastAngle
         this.lastAngle = angle
         console.log(this.angle, '旋转的角度');
         this.turntable.style.transform = `rotate(${this.angle}deg)`
         setTimeout(() => {
             callback()
         }, this.transitionTime * 1000)
     }
 }
 export default game

整个组件代码

<template>
  <div class="home">
    <div class="container">
      <div class="content" id="luckyDraw">
        <div class="flabellum" v-for="(item, index) in dataList" :key="index">
          {{ item.name }}
        </div>
      </div>
      <!-- 开始按钮 -->
      <img
        class="arrow"
        @click="handlerStartGame"
        src="../assets/img/1.png"
        id="startBtn"
        alt=""
      />
    </div>
  </div>
</template>

<script>
import game from "../utils/game";
export default {
  components: {},
  data() {
    return {
      dataList: [
        {
          name: "运动",
        },
        {
          name: "学习",
        },
        {
          name: "休息",
        },
        {
          name: "喝奶茶",
        },
        {
          name: "看书",
        },
        {
          name: "赛车",
        },
        {
          name: "吃鸡",
        },
        {
          name: "王者",
        },
      ],
      isRotate: true, // 是否可以点击按钮开始抽奖
    };
  },
  computed: {},
  mounted() {
    // 页面加载后再执行游戏相关操作
    window.onload = () => {
      const luckyDraw = document.getElementById("luckyDraw");
      const startBtn = document.getElementById("startBtn");
      // 初始化游戏
      game.init(luckyDraw);
      // 绑定开始抽奖按钮点击事件
      startBtn.onclick = this.startGame;
    };
    this.setBladeWidth();
    this.settingDataItemRotate();
  },
  methods: {
    // 动态计算每一扇叶元素宽度
    setBladeWidth() {
      let $ = function (selector) {
        return document.querySelectorAll(selector);
      };
      let num = this.dataList.length;
      //diameter转盘直径(根据自己测量直径填入就好);width扇叶元素宽度;deg每一叶的旋转角度
      let diameter = 300,
        width = 0,
        deg = 360 / num;
      width = diameter * Math.tan(((deg / 2) * Math.PI) / 180);
      $(".flabellum").forEach((e, ind) => {
        // 动态初始化每一扇叶的宽度
        e.style.width = width + "px";
        // 动态初始化每一扇叶该旋转的角度
        e.style.transform = `rotateZ(${ind * (360 / this.dataList.length)}deg)`;
      });
    },
    // 动态计算出当前数组每一项应该旋转的角度并传入数组每一项obj作为key
    settingDataItemRotate() {
      // 设置dataList中的rotate
      const value = 360 / this.dataList.length;
      let arr = JSON.parse(JSON.stringify(this.dataList)).reverse();
      arr.forEach((ele, ind) => {
        arr[ind].rotate = value * (ind + 1);
        if (ind == arr.length - 1) arr[ind].rotate = 0;
      });
      this.dataList = JSON.parse(JSON.stringify(arr)).reverse();
    },
    handlerStartGame() {
      if (!this.isRotate) return;
      this.isRotate = false;
      // 产生随机数,获得随机抽奖结果
      const num = Math.floor(Math.random() * this.dataList.length);
      // 启动旋转
      game.rotate(this.dataList[num].rotate, () => {
        // 动画结束,展示结果
        alert(`恭喜你获得-${this.dataList[num].name}`);
        this.isRotate = true;
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.container {
  position: relative;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  background: #f7c894;
  display: flex;
  justify-content: center;
  overflow: hidden;
  border: 20px solid #ffbd72;
}
.content {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  border-radius: 50%;
  overflow: hidden;
}

.flabellum {
  position: absolute;
  width: 100px;
  height: 50%;
  clip-path: polygon(50% 100%, 0% 0%, 100% 0%);
  -webkit-clip-path: -webkit-polygon(50% 100%, 0% 0%, 100% 0%);
  transform-origin: 50% 100%;
  text-align: center;
  color: #000;
  font-size: 30px;
}
.container .flabellum:nth-child(odd) {
  background-color: #f7c894;
}

.container .flabellum:nth-child(even) {
  background-color: red;
}

.arrow {
  width: 60px;
  height: 80px;
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 999;
  transform: translateX(-50%);
  transform: translate(-50%, -50%);
}
</style>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值