As the New Year is approaching, I wish you all a happy and prosperous New Year in advance. Many of you have already had a memorable or boring annual party, so here comes the belated lottery component, 233333333
data
Let’s take a look at some of the data we’re going to use
data () {
return {
bgStatus: true, // Control the flashing of the lottery borderbgInterval: ' '// Store background switchsetPrizeList: [], // List of prizes to render idList: [], // Array of prize ids to store cur: undefined, // Speed: 100, // speed couldClick:true// Control the clickable state of the lottery button}}Copy the code
Let’s take a look ata structure of data, using variable comments, and then if you have any questions you can go here
template
Take a look at our template structure
<template>
<div class="md-div"> <! ----------- run ma deng -------------> <div class="md-bd-bg" :class="bgStatus ? 'md-bd-bg1' : 'md-bd-bg2'"> <! ---------- raffle container --------------> <div class="item-out"> <! ---------- circular award --------------> <div class="prize-item flex-column flex-just-center flex-align-center" v-for="k in prizeList" :key="k.prizeid"
:class="k.prizeid === cur ? 'prize-y' : 'prize-n'"
>
<div class="prize-img flex-row flex-just-end flex-align-center">
<img :src="`https://${k.photo}`" alt=""> </div> <! -- <div class="prize-word">{{k.prize_name}}</div>--> </div> <! ----------- raffle button -------------> <div class="prize-btn" @click="doPrize" :class="couldClick ? '' : 'refuse-click'"></div>
</div>
</div>
</div>
</template>
Copy the code
To analyze the structure, we give an outer layer (class= MD-BD-bg) to be used as the flicker control for the outer light. Here it is very simple, all we need is two images with almost the same background
.md-bd-bg1{background-image: url(".. /.. /statics/tbIcon/shine1.png")}
.md-bd-bg2{background-image: url(".. /.. /statics/tbIcon/shine2.png")}
.md-bd-bg{
width: 100%;
height: 100%;
background-size: 100% 100%;
padding: 6vw;
}
Copy the code
This is the style of the outer border, mD-BD-BG1 and MD-BD-BG2 correspond to the two states respectively, the next step is to make it move
controlBg() {// Background transform functionlet vm = this
vm.bgInterval = setInterval(() => { vm.bgStatus = ! vm.bgStatus }, 500) }Copy the code
We use bgInterval to store a setInterval. The reason we use a variable to store a setInterval is to clear events when cleaning components
To the chase!
Finally to our serious horse light lottery, the first analysis of the structure
<! ---------- circular award --------------> <div class="prize-item flex-column flex-just-center flex-align-center" v-for="k in prizeList" :key="k.prizeid"
:class="k.prizeid === cur ? 'prize-y' : 'prize-n'"
>
<div class="prize-img flex-row flex-just-end flex-align-center">
<img :src="`https://${k.photo}`" alt=""> </div> <! -- <div class="prize-word">{{k.prize_name}}</div>-->
</div>
Copy the code
Loop render the requested array of prizes using V-for
.prize-y{background-image: url(".. /.. /statics/tbIcon/prize_y.png"); } .prize-n{background-image: url(".. /.. /statics/tbIcon/prize_n.png")} .prize-item:nth-of-type(1){top: .1vw; left: .1vw; } .prize-item:nth-of-type(2){top: .1vw; Left: 27.35 vw; } .prize-item:nth-of-type(3){top: .1vw; Left: 54.6 vw; }. Prize - item: the NTH - of - type (4) {top: 27.35 vw; Left: 54.6 vw; }. Prize - item: the NTH - of - type (5) {top: 54.6 vw; Left: 54.6 vw; }. Prize - item: the NTH - of - type (6) {top: 54.6 vw; Left: 27.35 vw; }. Prize - item: the NTH - of - type (7) {top: 54.6 vw; left: .1vw; }. Prize - item: the NTH - of - type (8) {top: 27.35 vw; left: .1vw; }Copy the code
Vw units are used here. Vw, VH, Vmin and vmax are all used. The above code places the awards in a circle, leaving space for buttons
.prize-btn{width: 27vw; height: 27vw; background-size: 100% 100%; position: absolute; background-image: url(".. /.. /statics/tbIcon/prize-btn.png"); Top: 27.35 vw; Left: 27.35 vw; }Copy the code
All right, with everything in place, let’s have fun writing logic
Click on the draw
Check out our lucky draw button
<template>
<div class="prize-btn" @click="doPrize" :class="couldClick ? '' : 'refuse-click'"> < / div > < / template > / * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- forbid click -- -- -- -- -- -- -- -- -- -- -- -- - * /. Refuse - click {filter: grayscale (10%). } | | \ | | / / /doPrize () {
let vm = this
if (vm.couldClick) {
vm.couldClick = false// Disallows the next drawing vm before the first drawing is completed.$axios(urls.doPrize, {}).then(res => {
let code = res.code
if (code === 'success') {
vm.prizeAnimate(res)
} else {
vm.$q.notify({ message: res.msg })
}
})
}
}
Copy the code
When clicked, it will be the primary color of the design drawing, and when not clicked, it will be a gray filter. CSS filter is also very interesting. But first to the service to request the result of the lottery, that is to say, the animation behind are redundant, you click on the time has already determined your winning result, so we don’t write animation, so we can directly use
Continue to
Just as a joke, I pasted my raffle animation code
prizeAnimate (result) {
let vm = this
vm.cur = undefined
let num = vm.idList.indexOf(Number(result.prizeid))
let len = vm.idList.length
letAllSteps = math.floor (math.random () * 3 + 2) * len + num // Total number of steps to take 2~5let a = 0
function myInt () {
setTimeout(() => {
if(a <= allSteps) {// A is the number of steps that have been takenif(allSteps -a < len * 2 && allSteps -a >= len) {// Enter the penultimate circle, add delay vm.speed = 200}else if(allSteps -a < len) {// Enter the penultimate circle and add the delay vm.speed = 400} vm.cur = vm.idList[a % vm.idlist.length] // A++ // after performing the jump, remember to add 1 to the number of jumps myInt() // recursive call}else{// Finally finish the vm.couldClick =trueVm. speed = 100 // Restore the speed // ------- // lottery animation to complete the next operation, such as popup notification of winning the lottery}}, vm.speed)} myInt()}}Copy the code
In the first step, we empty cur, and then extract the index value of the winning result in the prize array, which is the allSteps used to generate the total number of steps. To make the animation look as’ we really animated it ‘as possible, we set 2 to 5 turns plus the index value, and now we have the total number of steps to take
So start
Here I declare myInt to be used as the body of a recursive setTimeout function. The purpose of this is, first of all, our lottery is animated, so the speed must not be uniform. If we use setInterval, changing the speed will not change the beating speed of the animation. SetInterval can also be used, but you have to write three, a fast, a medium speed, a low speed, and then execute one by one. Haha, I would like to explain this function again, but I feel like it is written in the remarks, so I will pack up and go home for Chinese New Year, 886~~
The whole assembly is served
<template>
<div class="md-div">
<div class="md-bd-bg" :class="bgStatus ? 'md-bd-bg1' : 'md-bd-bg2'">
<div class="item-out">
<div class="prize-item flex-column flex-just-center flex-align-center" v-for="k in prizeList" :key="k.prizeid"
:class="k.prizeid === cur ? 'prize-y' : 'prize-n'"
>
<div class="prize-img flex-row flex-just-end flex-align-center">
<img :src="`https://${k.photo}`" alt=""> </div> <! -- <div class="prize-word">{{k.prize_name}}</div>--> </div> <! ----------- raffle button -------------> <div class="prize-btn" @click="doPrize" :class="couldClick ? '' : 'refuse-click'"></div>
</div>
</div>
</div>
</template>
<script>
import urls from 'src/api/urls'
export default {
name: 'module'.data () {
return {
bgStatus: true.bgInterval: ' 'IdList: [], cur: undefined, couldClick:true// The lucky draw button can be clicked}},created () {
letVm = this vm.controlBg() // open background transform vm.queryList() // request award}, methods: {controlBg() {// Background transform functionlet vm = this
vm.bgInterval = setInterval(() => { vm.bgStatus = ! vm.bgStatus }, 500) },queryList () {
let vm = this
vm.$axios(urls.getPrizeList, {}).then(res => {
let code = res.code
if (code === 'success') {
// console.log(res)
for (let k in res.lottery_prize) {
vm.idList.push(res.lottery_prize[k].prizeid)
}
vm.prizeList = res.lottery_prize
vm.$emit('subNotice', res)
} else {
vm.$router.go(-1)
}
})
},
doPrize () {
let vm = this
if (vm.couldClick) {
vm.couldClick = false// Disable vm execution immediately next time.$axios(urls.doPrize, {}).then(res => {
let code = res.code
if (code === 'success') {
vm.prizeAnimate(res)
} else {
vm.$q.notify({ message: res.msg })
}
})
}
},
prizeAnimate (result) {
let vm = this
vm.cur = undefined
let num = vm.idList.indexOf(Number(result.prizeid))
let len = vm.idList.length
letAllStamps = math.floor (math.random () * 3 + 2) * len + num // The total number of steps to take 2~5let a = 0
function myInt () {
setTimeout(() => {
if (a <= allStamps) {
if (allStamps - a < len * 2 && allStamps - a >= len) {
vm.speed = 200
} else if (allStamps - a < len) {
vm.speed = 400
}
vm.cur = vm.idList[a % vm.idList.length]
a++
myInt()
} else {
vm.couldClick = true
vm.$emit('subDc', result)
vm.speed = 100
}
}, vm.speed)
}
myInt()
}
}
}
</script>
<style scoped>
.md-div{
width: 94vw;
height: 94vw;
position: relative;
margin: 3vw;
}
.md-bd-bg1{background-image: url(".. /.. /statics/tbIcon/shine1.png")}
.md-bd-bg2{background-image: url(".. /.. /statics/tbIcon/shine2.png")} .md-bd-bg{ width: 100%; height: 100%; background-size: 100% 100%; padding: 6vw; } .item-out{width: 100%; height: 100%; position: relative; } .prize-item{ width: 27vw; height: 27vw; background-size: 100% 100%; position: absolute; } .prize-btn{width: 27vw; height: 27vw; background-size: 100% 100%; position: absolute; background-image: url(".. /.. /statics/tbIcon/prize-btn.png"); Top: 27.35 vw; Left: 27.35 vw; } .prize-img{width: 70%; height: 40%; } .prize-img img{width: 100%; height: auto; } .prize-word{color:# 832909; The font - size: 1.4 rem; }
.prize-y{background-image: url(".. /.. /statics/tbIcon/prize_y.png"); } .prize-n{background-image: url(".. /.. /statics/tbIcon/prize_n.png")} .prize-item:nth-of-type(1){top: .1vw; left: .1vw; } .prize-item:nth-of-type(2){top: .1vw; Left: 27.35 vw; } .prize-item:nth-of-type(3){top: .1vw; Left: 54.6 vw; }. Prize - item: the NTH - of - type (4) {top: 27.35 vw; Left: 54.6 vw; }. Prize - item: the NTH - of - type (5) {top: 54.6 vw; Left: 54.6 vw; }. Prize - item: the NTH - of - type (6) {top: 54.6 vw; Left: 27.35 vw; }. Prize - item: the NTH - of - type (7) {top: 54.6 vw; left: .1vw; }. Prize - item: the NTH - of - type (8) {top: 27.35 vw; left: .1vw; } / * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- forbid click -- -- -- -- -- -- -- -- -- -- -- -- - * /. Refuse - click {filter: grayscale (10%). } </style>Copy the code