本次大转盘可以适配任意商品个数,根据后台读取的商品个数进行适配,
顺便吐槽一下,公司让我一周整好10个活动。。。。。,老虎机,大转盘,摇一摇,砸金蛋,翻牌,刮刮乐等活动,还要用vue-cli脚手架搭建来写,我怕是要猝死啊,呜呜,记录下来我辛苦的日子。我要是忽然不更新了,我怕是已经凉了,记着捞我。
这个是老虎机抽奖
图片效果我给你们看一下
我先说一下,这里我确实也用了网上其他人写的大转盘,作为参考
我先设计大转盘,我现在需要图片放的地方,然后还要有分隔线
<ul class="ulOne" :class="{'win':indexa===0&&prize_list.length==3}">
<li v-for="(item,index) in arrOne" :class="{'win':index===indexa}" :style="{ zIndex: item.zIndex,transform: item.deg }"></li>
</ul>
<ul class="ulTwo" :class="{'win':indexa===arrOne.length-1}">
<li v-for="(item,index) in arrTwo" :class="{'win':index===indexb}" :style="{ zIndex: item.zIndex,transform: item.deg }"></li>
<li v-if="prize_list.length==3" :class="{'win':indexb===0}" style="border:none;z-index:4; transform: rotate(329deg)"></li>
</ul>
第一个和第二个class是分割线,
写起来好麻烦,直接全代码上,反正会看的看的懂,不会的讲了也不会。。。。。
我这里面还有个活动规则和中奖记录的模板,是我另外引入的,我就懒的写了。还有个初始判断是不是登录的弹窗。
<template>
<div class="content">
<div class="conts">
<div class="box">
<div class="pointer" @click="chou()" :style="{backgroundImage:beganToDraw}">
</div>
<div class="boxbg" :style="{transform:rotate_angle,transition:rotate_transition,backgroundImage:beganToDrawImg}">
<div class="turn">
<div class="turnplateborder default"></div>
<div :class="{'wheel-bg6':true}">
<div class="prize-list">
<ul class="ulOne" :class="{'win':indexa===0&&prize_list.length==3}">
<li v-for="(item,index) in arrOne" :class="{'win':index===indexa}" :style="{ zIndex: item.zIndex,transform: item.deg }"></li>
</ul>
<ul class="ulTwo" :class="{'win':indexa===arrOne.length-1}">
<li v-for="(item,index) in arrTwo" :class="{'win':index===indexb}" :style="{ zIndex: item.zIndex,transform: item.deg }"></li>
<li v-if="prize_list.length==3" :class="{'win':indexb===0}" style="border:none;z-index:4; transform: rotate(329deg)"></li>
</ul>
<div></div>
</div>
<div class="prize-list">
<div class="prize-item" v-for="(item,index) in prize_list" :key="index" :style="{transform:item.troter,width:item.width}">
<div class="prize-pic">
<img :src="item.goodsIconUrl">
</div>
<div class="prize-name">
{{item.prizeName}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="popup" v-show="toast_control">
<div class="popbg"></div>
<div class="popbox">
<div class="img" :class="{'img1':isImgTrue}"></div>
<div class="words1">{{hasPrize.words1}}</div>
<div class="words2">{{hasPrize.words2}}</div>
<div class="words3" v-show="hasPrize.words3!=''">{{hasPrize.words3}}</div>
</div>
<div class="close" @click="toast_control=false"></div>
</div>
<bottomComponent></bottomComponent>
<div class="btn_group">
<div class="add_btn">
<div class="act_rule" @click="showdiv(1)">活动规则</div>
<div class="luck_recond" @click="showdiv(2)">中奖记录</div>
</div>
</div>
<ruleComponent :itemsListName="itemsListName" v-if="isShowRule"></ruleComponent>
<codeComponent :itemsListCodeName="itemsListCodeName" v-if="isShowCode" @touchmove.prevent></codeComponent>
<mt-popup v-model="popupVisible" :closeOnClickModal=false :modal = false>
<div class="pop_box" @touchmove.prevent>
<div class="tell_tit">
<h1 class="pop-idea">用户登录</h1>
</div>
<div class="info-set">
<div class="writer"><span>手机号:</span> <input v-model.trim="ruleForm.phone" type="tel" placeholder="请输入您的入手机号" maxlength="11" class="tel_writer"></div>
<div class="writer"><span>随机码:</span>
<input v-model.trim="ruleForm.code" type="text" placeholder="请输入随机码" maxlength="5" class="tel_writer">
<img :src="createCode" @click="imgClick" class="print-code">
</div>
<div class="writer"><span>验证码:</span> <input v-model.trim="ruleForm.createCode" type="tel" placeholder="请输入验证码" maxlength="4" class="tel_writer"> <div :style="btnImg" @click="reginInto" id="btn">{{reginValue}}</div></div>
</div>
<div class="sure_btn" @click="buttomRegin">立即登录</div>
<div class="close-btn" @click="popupVisible=false"><img src="~img/close.png"></div>
</div>
</mt-popup>
<transition name="fade">
<div class="isVodel" v-show="popupVisible" @touchmove.prevent>
</div>
</transition>
<div class="isVodel" v-if="isShowRule" @touchmove.prevent></div>
<div class="isVodel" v-if="isShowCode" @touchmove.prevent></div>
</div>
</template>
<script>
import ruleComponent from "./rule.vue"
import bottomComponent from "./bottom.vue"
import codeComponent from "./code.vue"
import {
initApi,
loginApi,
lotteryApi,
awardApi,
getCaptcha,
sendCaptcha,
registerApi,
winning
} from "../api/api";
export default {
data() {
return {
winnum: '0', //中奖的下标
indexa: '', //中奖的下标在第一个ul下li的index下标,背景变深颜色
indexb: '', //中奖的下标在第二个ul下li的index下标,背景变深颜色
toast_control: false, //抽奖结果和活动规则弹出框控制器
click_flag: true, //是否可以旋转抽奖
start_rotating_degree: 0, //转盘初始旋转角度
rotate_angle: 0, //转盘将要旋转的角度
start_rotating_degree_pointer: 0, //指针初始旋转角度
rotate_angle_pointer: 0, //指针将要旋转的度数
rotate_transition: "", //初始化选中的过度属性控制
rotate_transition_pointer: "transform 12s ease-in-out", //初始化指针过度属性控制
beganToDraw: {},
beganToDrawImg: {},
turnprize: [],
prize_list: [], //奖品列表
arrOne: [],
arrTwo: [],
reginValue: "获取验证码",
shopUid: '',
userinfo: '',
isImgTrue:false,
btnImg: {},
prizeinfo: {
isGet: '',
prizeInfos: [{
validTime: '',
invalidTime: '',
type: ''
}]
}, //中奖优惠券或实物的信息
hasPrize: {}, //抽奖之后弹出框信息
nums: '0',
isButton: false,
popupVisible: false,
createCode: "",
isCode: true, //验证码开关
ruleForm: {
phone: '',
code: '',
createCode: "",
},
isShowRule:false,
isShowCode:false,
itemsList:"",
itemsListName:"",
codeComponent:[],
}
},
mounted() {
this.loginMenu();
},
components: {
ruleComponent,
bottomComponent,
codeComponent
},
methods: {
showdiv(index){
if(index==1){
this.itemsListName = this.itemsList;
this.isShowRule = true;
}else{
if (this.isButton) {
this.popupVisible = true;
return
}
this.winningMenu();
}
},
winningMenu(){
winning().then((res)=>{
if(res.httpCode=200){
this.itemsListCodeName = res.data;
this.isShowCode = true;
}
})
},
buttomRegin() {
if (this.ruleForm.phone != "" || this.ruleForm.phone) {
if (/^1[34578]\d{9}$/.test(this.ruleForm.phone)) {
console.log("手机号通过验证");
} else {
this.$toast("请输入正确的手机号")
return false;
}
} else {
this.$toast("请输入手机号")
return false;
}
if (this.ruleForm.code == "") {
this.$toast("请输入随机码")
return false;
}
if (this.ruleForm.createCode == "") {
this.$toast("请输入验证码")
return false;
}
this.$indicator.open({
text: '加载中...',
spinnerType: 'fading-circle'
});
let params = {
"phone": this.ruleForm.phone,
"phoneCode": this.ruleForm.createCode,
}
registerApi(params).then((res) => {
this.$indicator.close()
if (res.httpCode == 200) {
this.isButton = false;
this.popupVisible = false;
} else {
this.$toast(res.retMsg)
}
}).catch((err)=>{
this.$indicator.close();
this.$toast("接口异常");
})
},
reginInto() {
if (this.ruleForm.phone != "" || this.ruleForm.phone) {
if (/^1[34578]\d{9}$/.test(this.ruleForm.phone)) {
console.log("手机号通过验证");
} else {
this.$toast("请输入正确的手机号")
return false;
}
} else {
this.$toast("请输入手机号")
return false;
}
if (this.ruleForm.code == "") {
this.$toast("请输入随机码")
return false;
}
if (!this.isCode) {
return false;
}
this.sendCaptchaMenu(this.ruleForm.code);
},
//发送验证码
sendCaptchaMenu(code) {
let params = {
"mobile": this.ruleForm.phone,
"type": "sms_login",
"captcha": code,
}
sendCaptcha(params).then((res) => {
if (res.httpCode == 200) {
this.btnImg = {
"background": "#d3d4d6"
}
this.reginValue = "60秒"
let isNum = 60
this.isCode = false;
var inteval = setInterval(() => {
isNum--
this.reginValue = isNum + "秒"
if (isNum == 0) {
clearInterval(inteval);
this.isCode = true;
this.reginValue = "获取验证码"
this.btnImg = {
"background": "#fc817e"
}
}
}, 1000);
} else {
this.$toast(res.retMsg);
this.isCode = true;
this.reginValue = "获取验证码"
this.btnImg = {
"background": "#fc817e"
}
return false;
}
})
},
//随机码
imgClick() {
getCaptcha().then(res => {
console.log(res);
this.createCode = "data:image/png;base64," + res.data;
this.suId = res.data.suId;
});
//$("#codeImg").attr("src","createCode?r="+Math.random())
},
//兑奖apo
awardApiMenu() {
let _this = this
awardApi().then((res) => {
if (res.httpCode == 200) {
_this.game_over(1);
}else{
_this.game_over(2);
}
})
},
//活动抽奖
lotteryApiMenu() {
},
loginMenu() {
console.log(this.$route);
let paramsName = "";
if (window.location.host.split(".")[0] != "192") {
paramsName = window.location.host.split(".")[0];
} else {
paramsName = "m02bsfsk"
}
loginApi(paramsName).then((res) => {
if (res.httpCode == 200) {
window.localStorage.setItem("activity_lefeng", res.data.sign);
this.initApiMenu();
}
})
},
initApiMenu() {
initApi().then((res) => {
if (res.httpCode == 200) {
this.ObjectAll = res.data;
this.popupVisible = res.data.proRegister;
this.isButton = res.data.proRegister;
this.imgClick();
res.data.marketingCampaign.terms.forEach((item, index) => {
if (item.termType == 10) {
this.itemsList = item.termVal;
}
})
res.data.marketingCampaign.prizes.forEach((item, index) => {
this.prize_list.push({
"prizeType": index + 1,
"prizeName": item.prizeName,
"goodsIconUrl": item.goodsInfo.goodsIconUrl,
"goodsId": item.goodsId,
})
})
// let markIndex = res.data.marketingCampaign.prizes.length
// if(markIndex<5){
// for(var i=0;i<8-markIndex;i++){
//
// this.prize_list.push({
// "prizeType": i + markIndex + 1,
// "prizeName": res.data.marketingCampaign.prizes[(i%markIndex)].goodsInfo.goodsName,
// "goodsIconUrl": res.data.marketingCampaign.prizes[(i%markIndex)].goodsInfo.goodsIconUrl,
// "goodsId": res.data.marketingCampaign.prizes[(i%markIndex)].goodsId,
// })
// }
// }
this.setSan()
res.data.marketingCampaign.pictures.forEach((item) => {
if (item.picType == "1000") {
// this.styleObject = {
// "background-image": "url("+item.picUrl+")"
// },
document.body.style.backgroundImage = "url(" + item.picUrl + ")"
} else if (item.picType == "1202") {
this.beganToDraw = "url(" + item.picUrl + ")"
} else if (item.picType == "1200") {
this.beganToDrawImg = "url(" + item.picUrl + ")"
}
})
}
})
},
chou() {
if (this.isButton) {
this.popupVisible = true;
return
}
if (!this.click_flag) return;
//活动抽奖
lotteryApi().then((res) => {
if (res.httpCode == 200) {
this.prize_list.forEach((item, index) => {
if (item.goodsId == res.data.goodsId) {
let _this = this;
_this.indexa = ''
_this.indexb = ''
_this.nums = Number(_this.prize_list.length - 1) - Number(_this.winnum)
_this.winnum = index;
_this.rotating(_this.winnum)
}
})
}else{
if(res.retCode=="10030001"){
this.loginMenu();
}else{
this.$toast(res.retMsg)
}
}
});
},
setSan() {
let _this = this
_this.arrOne = [];
_this.arrTwo = [];
_this.rotate_angle = "rotate(" + Math.floor(-360 * 100 / _this.prize_list.length) / 200 + "deg)";
_this.start_rotating_degree = Math.floor(-360 * 100 / _this.prize_list.length) / 200;
for (var i = 0; i < _this.prize_list.length; i++) {
_this.prize_list[i].troter = "rotate(" + Math.floor(360 * 100 / _this.prize_list.length) / 100 * (0.5 + Number(i)) + "deg) translateX(-50%)"
_this.prize_list[i].width = Math.floor(3.14 * 5.6 / this.prize_list.length) + "rem"
var item = {
value: _this.prize_list[i].name,
zIndex: Number(i) + 1,
deg: "rotate(" + Math.floor(360 * 100 / this.prize_list.length) * i / 100 + "deg)",
degnum: i,
}
if (i < _this.prize_list.length / 2) {
_this.arrOne.push(item)
} else {
_this.arrTwo.push(item)
}
}
},
rotating(index) { //转盘转动函数,index值为中奖的下标,后台会返回中奖的id,这边会首先for循环判断中奖的下标
let _this = this;
_this.rotate_transition = "transform 6s cubic-bezier(0.25,0.1,0.01,1)";
if (!_this.click_flag) return;
var type = 0; // 默认为 0 转盘转动 1 箭头和转盘都转动(暂且遗留)
var during_time = 5; // 默认为1s
var result_index = index; // 最终要旋转到哪一块,对应prize_list的下标
var rand_circle = 6; // 附加多转几圈,2-3
_this.click_flag = false; // 旋转结束前,不允许再次触发
if (type == 0) {
if (this.start_rotating_degree < 0) {
this.start_rotating_degree = 0
} else {
this.start_rotating_degree = this.start_rotating_degree - Math.floor(360 * 100 / _this.prize_list.length) / 200 - Math.floor(360 * 100 / this.prize_list.length) * _this.nums / 100;
console.log(this.start_rotating_degree)
}
var rotate_angle = this.start_rotating_degree + 360 * 10 + Math.floor(-360 * 100 / this.prize_list.length) / 200 - Math.floor(360 * 100 / this.prize_list.length) * result_index / 100;
this.start_rotating_degree = rotate_angle;
_this.rotate_angle = "rotate(" + rotate_angle + "deg)";
// 旋转结束后,允许再次触发
setTimeout(function() {
_this.click_flag = true;
if (_this.winnum < _this.prize_list.length / 2) {
_this.indexb = ''
_this.indexa = _this.winnum;
} else {
_this.indexa = ''
_this.indexb = _this.winnum - (_this.arrOne.length);
}
_this.awardApiMenu();
}, during_time * 1000 + 1500); // 延时,保证转盘转完
}
},
game_over(index) {
let _this = this;
_this.prizetype = 1
if (_this.prizetype != -1) {
_this.toast_control = true;
} else {
Alert.show("奖品已领完,下次请早到哦!")
}
var obj = {}
console.log(_this.prize_list);
if(index==1){
this.isImgTrue = false;
if (_this.prize_list[_this.winnum].prizeName == "谢谢参与") {
obj = {
type: 0,
words1: '谢谢参与',
words2: "不要气馁!",
words3: '还有更多大奖等着你~'
}
} else {
obj = {
type: 1,
words1: '恭喜您!',
words2: "获得" + _this.prize_list[_this.winnum].prizeName,
words3: ''
}
}
}else{
this.isImgTrue = true;
obj = {
type: 3,
words1: '抱歉!',
words2: '出现未知错误,请稍后再试',
words3: ''
}
}
_this.hasPrize = obj
},
}
}
</script>
<style media="screen">
.fade-enter-active, .fade-leave-active {
transition: opacity .2s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
.mint-indicator{
position: relative;
z-index: 2000;
}
.mint-popup {
z-index: 200!important;
}
/* .v-modal {
z-index: 100!important;
} */
</style>
<style scoped>
.btn_group {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 5rem;
top: 13rem;
}
.add_btn {
display: flex;
justify-content: space-between;
width: 100%;
}
.act_rule {
width: 2.3rem;
height: 0.68rem;
color: #ca7314;
text-align: center;
line-height: 0.6rem;
background: url("~img/zct_rule.png") no-repeat;
background-size: 100% 100%;
}
.luck_recond {
width: 2.3rem;
height: 0.68rem;
color: #ca7314;
text-align: center;
line-height: 0.6rem;
background: url("~img/luck_recond.png") no-repeat;
background-size: 100% 100%;
}
.pop_box {
border-radius: .08rem;
position: relative;
left: 0;
width: 6.2rem;
margin-left: auto;
margin-right: auto;
background-color: #fff;
z-index: 400;
padding-bottom: .35rem;
}
.isVodel{
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0.5;
background: #000;
z-index: 100;
}
.tell_tit {
width: 100%;
height: 1.44rem;
background-size: 100% 100%;
}
.pop-idea {
line-height: 1.44rem;
font-size: .38rem;
color: #fff;
text-align: center;
font-weight: 700;
background-color: #00aca6;
background-image: url(~img/clold.png);
}
.info-set {
text-align: center;
}
.writer {
position: relative;
width: 100%;
border-bottom: 1px solid #989594;
display: -ms-flexbox;
display: flex;
padding-top: .08rem;
padding-bottom: .08rem;
}
.writer span {
text-align: center;
width: 1.5rem;
color: #4d3932;
font-size: .28rem;
line-height: .8rem;
}
input[type=text] {
-webkit-appearance: none;
background: none;
outline: none;
}
.writer input {
-ms-flex: 1;
flex: 1;
color: #5a5340;
font-size: .26rem;
line-height: .3rem;
border: none;
}
.print-code {
position: absolute;
width: 1.39rem;
height: .5rem;
right: .2rem;
top: 50%;
transform: translateY(-50%);
font-size: 15px;
margin: 0;
padding: 0;
outline: none;
font-family: Hiragino Sans GB, "sans-serif";
}
.writer span {
text-align: center;
width: 1.5rem;
color: #4d3932;
font-size: .28rem;
line-height: .8rem;
}
#btn {
position: absolute;
width: 1.49rem;
height: .6rem;
line-height: .6rem;
right: .2rem;
top: 50%;
transform: translateY(-50%);
border-radius: .45rem;
text-align: center;
color: #fff;
background: #fc817e;
font-size: .22rem;
}
.sure_btn {
margin-top: .3rem;
line-height: .65rem;
width: 4.2rem;
background: #fc817e;
color: #fff;
font-size: .26rem;
margin-left: auto;
margin-right: auto;
border-radius: .45rem;
border-bottom: 4px solid #dc625d;
text-align: center;
}
.close-btn {
font-size: 15px;
margin: 0;
padding: 0;
outline: none;
font-family: Hiragino Sans GB, "sans-serif";
position: absolute;
top: -.19rem;
right: -.19rem;
}
.close-btn img {
width: .42rem;
height: .42rem;
}
</style>