Sfoglia il codice sorgente

feat: 大转盘抽奖

Burt 2 anni fa
parent
commit
992df91a05
5 ha cambiato i file con 236 aggiunte e 17 eliminazioni
  1. 1 0
      .eslintrc.cjs
  2. 11 1
      src/pages.json
  3. 202 0
      src/pages/lottery/big-wheel.vue
  4. 21 16
      src/pages/lottery/nine-grid.vue
  5. 1 0
      uni-pages.d.ts

+ 1 - 0
.eslintrc.cjs

@@ -63,6 +63,7 @@ module.exports = {
     'no-shadow': 'off',
     'vue/multi-word-component-names': 'off',
     '@typescript-eslint/no-explicit-any': 'off',
+    'no-underscore-dangle': 'off',
   },
   // eslint-import-resolver-typescript 插件,@see https://www.npmjs.com/package/eslint-import-resolver-typescript
   settings: {

+ 11 - 1
src/pages.json

@@ -73,9 +73,19 @@
         "navigationBarTitleText": "登录"
       }
     },
+    {
+      "path": "pages/lottery/big-wheel",
+      "type": "page",
+      "style": {
+        "navigationBarTitleText": "大转盘抽奖"
+      }
+    },
     {
       "path": "pages/lottery/nine-grid",
-      "type": "page"
+      "type": "page",
+      "style": {
+        "navigationBarTitleText": "九宫格抽奖"
+      }
     },
     {
       "path": "pages/my/index",

+ 202 - 0
src/pages/lottery/big-wheel.vue

@@ -0,0 +1,202 @@
+<route lang="json5">
+{
+  style: { navigationBarTitleText: '大转盘抽奖' },
+}
+</route>
+<template>
+  <view>
+    <view class="container">
+      <view class="prize-list" :style="styleObj">
+        <view
+          class="prize-item"
+          v-for="(item, index) in prizeList"
+          :key="item.id"
+          :style="prizeStyle(index)"
+        >
+          <image :src="item.pic" class="gift-img" />
+          <text class="gift-name">{{ item.name }}</text>
+        </view>
+      </view>
+      <view class="lottery-btn" @click="start"> </view>
+    </view>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { ref, computed } from 'vue'
+
+// 后台配置的奖品数据
+const prizeList = [
+  {
+    id: 0,
+    name: '双肩包',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/backpack.jpg',
+  },
+  {
+    id: 1,
+    name: '积木',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/jimu.jpg',
+  },
+  {
+    id: 2,
+    name: '红包',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/red-envelope.jpg',
+  },
+  {
+    id: 3,
+    name: '茶具',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/tea-set.jpg',
+  },
+  {
+    id: 4,
+    name: '可爱脸',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/tushetou.jpg',
+  },
+  {
+    id: 5,
+    name: '挖掘机',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/wajueji.jpg',
+  },
+  {
+    id: 6,
+    name: '无辜脸',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/xiaolian.jpg',
+  },
+  {
+    id: 7,
+    name: '烟灰缸',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/yanhuigang.jpg',
+  },
+]
+let isRunning = false // 是否正在抽奖
+const baseRunAngle = 360 * 5 // 总共转动角度 至少5圈
+let prizeId = 0 // 中奖id
+
+// 平均每个奖品角度
+const rotateAngle = computed(() => {
+  const _degree = 360 / prizeList.length
+  return _degree
+})
+
+// 要执行总角度数
+const totalRunAngle = computed(() => {
+  return baseRunAngle + 360 - prizeId * rotateAngle.value - rotateAngle.value / 2
+})
+
+// 计算绘制转盘背景
+const bgColor = (() => {
+  const _len = prizeList.length
+  const colorList = ['#5352b3', '#363589']
+  let colorVal = ''
+  for (let i = 0; i < _len; i++) {
+    colorVal += `${colorList[i % 2]} ${rotateAngle.value * i}deg ${rotateAngle.value * (i + 1)}deg,`
+  }
+  return `background: conic-gradient(${colorVal.slice(0, -1)});`
+})()
+
+const styleObj = ref(bgColor)
+// 每个奖品布局
+const prizeStyle = computed(() => {
+  const _degree = rotateAngle.value
+  return (i) => {
+    // 外框大小设置为90vw,里面是一半,45vw
+    return `
+              width: ${2 * 45 * Math.sin(((_degree / 2) * Math.PI) / 180)}vw;
+              height: 45vw;
+              transform: rotate(${_degree * i + _degree / 2}deg);
+              transform-origin: 50% 100%;
+            `
+  }
+})
+
+// 获取随机数
+const getRandomNum = () => {
+  const num = Math.floor(Math.random() * prizeList.length)
+  return num
+}
+
+const stopRun = () => {
+  isRunning = false
+  styleObj.value = `${bgColor} transform: rotate(${totalRunAngle.value - baseRunAngle}deg);`
+}
+
+const startRun = () => {
+  console.log(isRunning, totalRunAngle.value)
+  // 设置动效
+  styleObj.value = `${bgColor} transform: rotate(${totalRunAngle.value}deg); transition: all 4s ease;`
+  setTimeout(stopRun, 4000)
+}
+const start = () => {
+  if (!isRunning) {
+    isRunning = true
+
+    console.log('开始抽奖,后台请求中奖奖品')
+    setTimeout(() => {
+      // 请求返回的奖品编号 这里使用随机数
+      prizeId = getRandomNum()
+      console.log('中奖ID>>>', prizeId, prizeList[prizeId])
+    }, 2000)
+    startRun()
+  }
+}
+</script>
+
+<style lang="scss">
+.container {
+  position: relative;
+  width: 90vw;
+  height: 90vw;
+  margin: 20px auto;
+}
+
+.prize-list {
+  box-sizing: border-box;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  border-radius: 50%;
+
+  // 使用outline代替border可以省很多定位的问题
+  outline: 10px solid #98d3fc;
+}
+
+.prize-item {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  display: flex;
+  flex-direction: column;
+  margin: auto;
+
+  // border: 2px solid red;
+}
+
+.prize-item .gift-img {
+  display: block;
+  width: 30%;
+  height: 20%;
+  margin: 20px auto 10px;
+  border-radius: 50%;
+}
+
+.prize-item .gift-name {
+  font-size: 12px;
+  line-height: 20px;
+  color: #fff;
+  text-align: center;
+}
+
+.lottery-btn {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  width: 80px;
+  height: 80px;
+  margin: auto;
+  cursor: pointer;
+  background: url('https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/btn-enable.png')
+    no-repeat center / 100% 100%;
+  transform: translate(-50%, -50%);
+}
+</style>

+ 21 - 16
src/pages/lottery/nine-grid.vue

@@ -1,3 +1,8 @@
+<route lang="json5">
+{
+  style: { navigationBarTitleText: '九宫格抽奖' },
+}
+</route>
 <template>
   <view>
     <view class="container">
@@ -23,43 +28,43 @@ const currentIndex = ref(0) // 当前位置
 const prizeList = [
   {
     id: 0,
-    name: '手机',
-    pic: 'https://bkimg.cdn.bcebos.com/pic/3801213fb80e7bec54e7d237ad7eae389b504ec23d9e',
+    name: '双肩包',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/backpack.jpg',
   },
   {
     id: 1,
-    name: '手表',
-    pic: 'https://img1.baidu.com/it/u=2631716577,1296460670&fm=253&fmt=auto&app=120&f=JPEG',
+    name: '积木',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/jimu.jpg',
   },
   {
     id: 2,
-    name: '苹果',
-    pic: 'https://img2.baidu.com/it/u=2611478896,137965957&fm=253&fmt=auto&app=138&f=JPEG',
+    name: '红包',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/red-envelope.jpg',
   },
   {
     id: 3,
-    name: '棒棒糖',
-    pic: 'https://img2.baidu.com/it/u=576980037,1655121105&fm=253&fmt=auto&app=138&f=PNG',
+    name: '茶具',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/tea-set.jpg',
   },
   {
     id: 5,
-    name: '娃娃',
-    pic: 'https://img2.baidu.com/it/u=4075390137,3967712457&fm=253&fmt=auto&app=138&f=PNG',
+    name: '可爱脸',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/tushetou.jpg',
   },
   {
     id: 6,
-    name: '木马',
-    pic: 'https://img1.baidu.com/it/u=2434318933,2727681086&fm=253&fmt=auto&app=120&f=JPEG',
+    name: '挖掘机',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/wajueji.jpg',
   },
   {
     id: 7,
-    name: '德芙',
-    pic: 'https://img0.baidu.com/it/u=1378564582,2397555841&fm=253&fmt=auto&app=120&f=JPEG',
+    name: '无辜脸',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/xiaolian.jpg',
   },
   {
     id: 8,
-    name: '玫瑰',
-    pic: 'https://img1.baidu.com/it/u=1125656938,422247900&fm=253&fmt=auto&app=120&f=JPEG',
+    name: '烟灰缸',
+    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/yanhuigang.jpg',
   },
 ]
 const startBtn = {

+ 1 - 0
uni-pages.d.ts

@@ -9,6 +9,7 @@ interface NavigateToOptions {
        "pages/demo/lottery" |
        "pages/demo/lottery2" |
        "pages/login/login" |
+       "pages/lottery/big-wheel" |
        "pages/lottery/nine-grid" |
        "pages/my/index" |
        "pages/throughout/index" |