前端vue转盘抽奖
一、 最近有個(gè)需求在前端做抽獎(jiǎng)的業(yè)務(wù),然后查了些資料,實(shí)現(xiàn)了一下。效果圖如下:
?二、實(shí)現(xiàn)原理:CSS的transitions:rotate屬性,傳入度數(shù)即可旋轉(zhuǎn);調(diào)整中獎(jiǎng)概率也寫的幾乎人人可以看懂的流程,也比較巧妙地實(shí)現(xiàn)了對(duì)概率的控制,稱不上多厲害的算法,但確實(shí)達(dá)到了想要效果。
1.在html中:
<template><div id="bg"><img @click="go" class="pointer" src="./pointer.png" alt="pointer"><img ref="turntable" class="turntable" src="./turntable.png" alt="turntable"><h1>你的抽獎(jiǎng)次數(shù)為:{{goTimes}}</h1></div> </template>2.在js中:
export default {data(){return {isGo: false, //是否正在執(zhí)行動(dòng)畫oTurntable:'', //執(zhí)行動(dòng)畫的對(duì)象randomDeg: 0, //即將旋轉(zhuǎn)的度數(shù) lastDeg:0, //上一次旋轉(zhuǎn)的度數(shù)goTimes:5 //抽獎(jiǎng)次數(shù)}},methods:{//這里是調(diào)自己的后端接口selectPersonResultSum(){var vm = this;vm.userId = localStorage.getItem("userId");vm.$axios.get("/personResult/selectPersonResultSum/" + vm.userId).then(function (response) {if (response.data.code === "0000") {vm.num=response.data.data.num;if(vm.num%10==0){vm.goTimes=1;}} else if (response.data.code === "1111") {vm.$message({message: "",type: "info",});}});},go(){if(!this.isGo && this.goTimes >0){ this.getNumber() }else if(!this.isGo && this.goTimes <=0){ alert('抱歉您的抽獎(jiǎng)次數(shù)用完了') } else return //表明正在抽獎(jiǎng),未結(jié)束 點(diǎn)擊無效},getRandom(n,m){ //該方法產(chǎn)生[n,m]之間隨機(jī)數(shù)let result = Math.floor(Math.floor(Math.random()*(m-n+1)+n))return result;},getNumber(){/* 調(diào)整中獎(jiǎng)概率(讓每次旋轉(zhuǎn)前指針都在初始位置,這樣才準(zhǔn)確)想轉(zhuǎn)到第一項(xiàng),需要轉(zhuǎn):360/7*0 + 360/7/2; --->該項(xiàng)為超級(jí)大獎(jiǎng)獎(jiǎng)項(xiàng)想轉(zhuǎn)到第二項(xiàng),需要轉(zhuǎn):360/7*1 + 360/7/2;想轉(zhuǎn)到第三項(xiàng),需要轉(zhuǎn):360/7*2 + 360/7/2;想轉(zhuǎn)到第四項(xiàng),需要轉(zhuǎn):360/7*3 + 360/7/2;想轉(zhuǎn)到第五項(xiàng),需要轉(zhuǎn):360/7*4 + 360/7/2;想轉(zhuǎn)到第六項(xiàng),需要轉(zhuǎn):360/7*5 + 360/7/2;想轉(zhuǎn)到第七項(xiàng),需要轉(zhuǎn):360/7*6 + 360/7/2; --->該項(xiàng)為未中獎(jiǎng)項(xiàng)*/let number = this.getRandom(0,100)let caseNum = ''if(number === 0){caseNum = 0 //粗略概率為1%}else if(number > 0 && number <5){caseNum = 1 //粗略概率為5%}else if(number >= 5 && number <10){caseNum = 2 //粗略概率為5%}else if(number >= 10 && number <15){caseNum = 3 //粗略概率為5%}else if(number >= 15 && number <20){caseNum = 4 //粗略概率為5%}else if(number >= 20 && number <25){caseNum = 5 //粗略概率為5%}else{ caseNum = 6 //粗略概率為75%}switch (caseNum) {case 0:this.ratating((360 / 7) * 0 + 360 / 7 / 2, "5");break;case 1:this.ratating((360 / 7) * 1 + 360 / 7 / 2, "1");break;case 2:this.ratating((360 / 7) * 2 + 360 / 7 / 2, "4");break;case 3:this.ratating((360 / 7) * 3 + 360 / 7 / 2, "1");break;case 4:this.ratating((360 / 7) * 4 + 360 / 7 / 2, "2");break;case 5:this.ratating((360 / 7) * 5 + 360 / 7 / 2, "3");break;default:this.ratating((360 / 7) * 6 + 360 / 7 / 2, "1");break;}},ratating(deg,text){this.goTimes --this.isGo = truelet times = this.getRandom(3,6)//圈數(shù)(從用戶體驗(yàn)角度考慮,設(shè)計(jì)隨機(jī)轉(zhuǎn)3-6圈。最少3圈,最多6圈)this.randomDeg = deg + 360 * times //記錄這次要旋轉(zhuǎn)的度數(shù)(傳來的度數(shù)+圈數(shù))let realDeg = (360 - this.lastDeg % 360) + this.lastDeg + this.randomDeg /*上次指針離初始狀態(tài)的度數(shù) + 上次的度數(shù) + 這次要旋轉(zhuǎn)的度數(shù)(這樣的目的是為了每次旋轉(zhuǎn)都從原點(diǎn)開始,保證數(shù)據(jù)準(zhǔn)確)*/this.oTurntable.style.transform = `rotate(${realDeg}deg)`;setTimeout(() => {this.isGo = falseconsole.log(`以原點(diǎn)為基準(zhǔn)共旋轉(zhuǎn)了${this.randomDeg}度,以一圈為基準(zhǔn)相對(duì)旋轉(zhuǎn)了${this.randomDeg % 360}度,最終結(jié)果為${text}`)this.lastDeg = realDeg //把這次度數(shù)存儲(chǔ)起來,方便下一次獲取},4000) //4000ms為css里面寫的執(zhí)行動(dòng)畫的時(shí)間},},mounted(){this.oTurntable = this.$refs.turntable} } </script>3.在css樣式中:
<style>#bg {width: 650px;height: 600px;margin: 0 auto;background: url('./turntable-bg.jpg') no-repeat;position: relative;}.pointer{position: absolute;z-index: 10;top: 155px;left: 247px;}.turntable{position: absolute;z-index: 5;top: 60px;left: 116px;transition: all 4s; /*動(dòng)畫執(zhí)行時(shí)間為4s */} </style>?三、總結(jié)
大家細(xì)心讀完代碼程序會(huì)發(fā)現(xiàn)我們每次旋轉(zhuǎn)都加上了上一次旋轉(zhuǎn)的度數(shù),這是為什么:
----如果不加上上一次旋轉(zhuǎn)的度數(shù),直接用這次的旋轉(zhuǎn)度數(shù),會(huì)有問題,比如:我第一次旋轉(zhuǎn)剛好旋轉(zhuǎn)了1000度,正常轉(zhuǎn),沒問題,但我第二次旋轉(zhuǎn)抽中旋轉(zhuǎn)500度,那么,旋轉(zhuǎn)對(duì)象會(huì)在第一次的基礎(chǔ)上往回退500度,因?yàn)樗看涡D(zhuǎn)都是以0參考對(duì)象,到時(shí)候一會(huì)逆時(shí)針轉(zhuǎn)一會(huì)順時(shí)針轉(zhuǎn),很難看,抽獎(jiǎng)的人到時(shí)候都暈了,因此必須在上一次旋轉(zhuǎn)的基礎(chǔ)上再加上這次旋轉(zhuǎn)的度數(shù);this.lastDeg % 360是獲得余數(shù),也就是排除圈數(shù),獲得離原點(diǎn)的度數(shù)。
?
總結(jié)
- 上一篇: 2021年10月份自考感悟
- 下一篇: vue表格导出到Excel