文章目录
- 打工搬砖记
- 转盘主要的逻辑实现
- 转盘的素材
- 小结
打工搬砖记
先来一个吃什么轮盘的预览图,这轮盘文案加字呈圆形铺出来,开始后旋转到指定的选项处停下来。
已上线小程序“打工人搬砖记”,可以扫码进行预览观看。
转盘主要的逻辑实现
1、通过绑定style绑定值为“prizeBoxStyle”,设置每个选项的颜色以及后续转盘转动需要操作这个值。
2、通过绑定style绑定值为“prizeStyle”,然后通过“rotateAngle()”方法计算出总共有几个选项,然后算出每个选项需要旋转的角度。
3、通过“totalRunAngle()”计算出转盘最后需要转动角度,所以说游戏在开始的一瞬间就程序就已经知道,抽中的是那一个。
4、为了使转盘有声音就使用“uni.createInnerAudioContext()”来创建音乐,这个地方需要注意的是,如果想要后续“.stop()”停下音乐,在创建的时候一定不要设置为自动播放,就是说“autoplay = false”。
具体代码如下:
<template>
<view>
<image src="../../static/lunch/lunchBcg.jpg" class="bcgImg" mode=""></image>
<view class="container">
<view class="container-title"></view>
<view class="prize-box-relative">
<view class="prize-box">
<view class="prize-list" ref="prizeWrap" :style="prizeBoxStyle">
<div class="prize-item" v-for="(item, index) in prizeList" :style="[prizeStyle(index)]">
<text>{{ item }}</text>
</div>
</view>
</view>
</view>
<image @click="openGame()" src="../../static/lunch/turntable.png" class="turntableImg" mode=""></image>
</view>
<!-- 弹框 :抽中要吃的-->
<view v-show="tipShow" class="tip_box">
<view class="tip_content">
<image src="../../static/lunch/tip.png" class="tip_img" mode=""></image>
<view class="tip_txt">
{{prizeList[prizeId] }}
</view>
<view class="tip_btn" @click="tipShow = false"></view>
</view>
</view>
</view>
</template>
<script>
import {
turnList
} from 'config/api.js';
export default {
data() {
return {
// colorList: ['#f69602', '#f8ca41', '#ffe7c9','#afe2ec'],
colorList: ['#fe9539', '#fadf94', '#5fcbd1', '#ffffff'],
prizeList: ["豆浆", "胡辣汤", "韭菜鸡蛋韭菜鸡蛋", "奖品4", "奖品5", "奖品6", "奖品4", "奖品5", "奖品6"],
isRunning: false, // 是否正在抽奖
baseRunAngle: 360 * 5, // 总共转动角度 至少5圈
prizeId: 0, // 中奖id
rotatePrize: 40,
tipShow: false,
prizeBoxStyle: '',
audioMusic: '',
}
},
onLoad() {
this.getPrizeList()
uni.$on('updateTurn', (data) => {
this.getPrizeList()
})
},
methods: {
getPrizeList() {
turnList({
data: {
eatType: this.activeMenu
},
custom: {
auth: true,
toast: false,
catch: true
}
}).then((res) => {
let arr = []
res.map(value => {
arr.push(value.name)
})
this.prizeList = arr
this.rotatePrize = 360 / arr.length
this.prizeBoxStyle = this.bgColor()
this.initGame()
})
},
// 初始化转盘游戏
initGame() {
this.rotateAngle()
},
// 开始游戏
openGame() {
this.startGame()
},
// 开始游戏
startGame() {
if (!this.isRunning) {
this.isRunning = true
this.prizeId = this.getRandomNum()
this.startRun()
}
},
// 游戏运行
startRun() {
this.prizeBoxStyle = `${this.bgColor()} transform: rotate(${this.totalRunAngle()}deg);transition: all 4s ease;`
this.audioMusic = uni.createInnerAudioContext();
this.audioMusic.autoplay = false;
this.audioMusic.startTime = 2;
this.audioMusic.sessionCategory = 'ambient';
this.audioMusic.src = '/static/lunch/music01.mp3';
this.audioMusic.play();
setTimeout(() => {
this.audioMusic.stop()
this.audioMusic.destroy()
this.audioMusic = null
}, 3700)
this.playAudio()
setTimeout(() => {
this.tipShow = true
this.isRunning = false
this.prizeBoxStyle = `${this.bgColor()} transform: rotate(${this.totalRunAngle() - this.baseRunAngle}deg);`
}, 4000)
},
getRandomNum() {
const num = Math.floor(Math.random() * this.prizeList.length)
return num
},
// 平均每个奖品角度
rotateAngle() {
this.rotatePrize = 360 / this.prizeList.length
},
// 奖品布局
prizeStyle(i) {
let _degree = this.rotatePrize
let style = {}
style.width = 2 * 130 * Math.sin(_degree / 2 * Math.PI / 180) + 'px'
style.height = '130px'
style.transform = `rotate(${_degree * i + _degree / 2}deg)`
style.transformOrigin = '50% 100%'
return style
},
// 计算绘制转盘背景
bgColor() {
let colorVal = ''
for (let i = 0; i < this.prizeList.length; i++) {
colorVal += `${this.colorList[i % 4]} ${this.rotatePrize * i}deg ${this.rotatePrize * (i + 1)}deg,`
}
return ` background: conic-gradient(${colorVal.slice(0, -1)});transform: rotate(-${this.rotatePrize/2}deg); `
},
// 要执行总转角度数
totalRunAngle() {
return this.baseRunAngle + 360 - this.prizeId * this.rotatePrize - this.rotatePrize / 2
},
// 转盘停下来时的声音
playAudio() {
setTimeout(() => {
const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
innerAudioContext.sessionCategory = 'ambient';
innerAudioContext.src = '/static/lunch/music.mp3';
innerAudioContext.onPlay();
}, 3800)
}
}
}
</script>
<style lang="scss">
.bcgImg {
position: fixed;
width: 750rpx;
height: 100vh;
}
.container {
position: relative;
width: 660rpx;
height: 660rpx;
margin: 0 auto;
}
.container-title {
font-size: 56rpx;
font-weight: bold;
color: #FFFFFF;
text-align: center;
line-height: 160rpx;
height: 160rpx;
letter-spacing: 20px;
}
.turntableImg {
width: 100%;
height: 100%;
position: absolute;
top: 160rpx;
}
.prize-box-relative {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.prize-box {
width: 300px;
height: 300px;
position: relative;
}
.prize-list {
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
}
.prize-item {
/*border: 2px solid red;*/
position: absolute;
left: 0;
right: 0;
top: 20px;
margin: auto;
text-align: center;
}
.prize-item text {
display: flex;
align-items: center;
writing-mode: vertical-rl;
color: #333333;
font-size: 26rpx;
font-weight: bold;
text-align: center;
line-height: 20px;
width: 100%;
}
.tip_box {
z-index: 10;
position: fixed;
top: 0;
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.tip_content {
position: relative;
}
.tip_img {
width: 640rpx;
height: 480rpx;
}
.tip_txt {
position: absolute;
top: 160rpx;
width: 600rpx;
text-align: center;
font-weight: bold;
font-size: 38rpx;
}
.tip_btn {
position: absolute;
bottom: 60rpx;
left: 210rpx;
width: 200rpx;
height: 100rpx;
}
.food_menu_list {
position: fixed;
bottom: 100rpx;
width: 710rpx;
padding: 50rpx 20rpx;
display: flex;
flex-wrap: wrap;
font-size: 26rpx;
color: #999999;
font-weight: bold;
.menu_box {
margin: 0 10rpx;
width: 174rpx;
background: rgba(244, 244, 244, 0.6);
box-shadow: 0 0 10rpx #FFFFFF;
display: flex;
align-items: center;
padding: 20rpx;
border-radius: 10rpx;
margin-bottom: 30rpx;
.menu_img {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
}
.menu_active {
color: #53851b;
background: #f4f4f4;
box-shadow: 0 0 10rpx #f4f4f4;
}
.menu_btn {
font-size: 36rpx;
color: #ffffff;
line-height: 80rpx;
text-align: center;
width: 100%;
border-radius: 10rpx;
border: 2rpx #FFFFFF solid;
}
}
</style>
转盘的素材
我发现穿上后好像就成为了jpg格式了,注意转盘哪个一定要是png格式的,不然会把转盘的内容给覆盖住,音乐和背景图的话就自己找找吧!
小结
总的来说实现过程不难,难的是思路以及行动力。加油打工人!!!