转盘抽奖
涉及的重点:JQ特效,概率
逻辑设计:
1.把前端页面设计好,转盘可以用table标签做,样式设计好
2.控制器把抽奖物查询出来,有序输出到前端页面设计好的转盘上
3.写JQ特效,原理就是轮流给每个抽奖项添加特定样式,实现看起来转盘转动的效果
4.抽奖,Ajax调用控制器的方法,该方法有三步:
1.查询出抽奖物(2步骤类似)
2.调用概率方法
3.把调用概率选中的抽奖物返回给前端页面Ajax
5.成功:根据返回的抽奖物设定的位置,让转盘最后转到返回的抽奖物位置;失败:提示“请求失败”
有个问题:用户如何快速点击抽奖按钮,会多次触发点击事件,使转盘连续转动多次。我想实现的效果是无论用户点击多少次,等转盘转完后(整个流程完整一轮)再执行下一次点击事件,再转动起来。我运用了弹框停顿阻止一下,但如果快速连续点击还是会执行多次点击事件,请有经验的大佬指导一下,谢谢!!
重点部分代码:
1.概率方法get_rand():
//抽奖概率运算
function get_rand($proArr) {
$result = array();
foreach ($proArr as $key => $val) {
$arr[$key] = $val['v']; //概率
}
//概率存在百分百时
if(in_array(100, $arr)){
foreach($arr as $key => $value){
if($value == 100){
$data[] = $key;
}
}
shuffle($data);//打乱数组
$ke = $data[0];//获取第一次值
return $proArr[$ke];
}
// 概率数组的总概率
$proSum = array_sum($arr);
asort($arr);
// 概率数组循环
foreach ($arr as $k => $v) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $v) {
$result = $proArr[$k];
break;
} else {
$proSum -= $v;
}
}
return $result;
}
2.转盘转动抽奖JQ
类似类里调用方法(定义一个变量lottery,里面有变量的初始化和方法,可以运用lottery.方法,实现调用)。layer是弹框插件,需要有layer插件包才有效果
注意:JQ运行时不用等方法调回结果再往下执行
<script type="text/javascript">
$(function() {
// layer.open({
// content: "积分抽奖暂时关闭,系统升级中"
// ,btnAlign: 'c'
// ,btn: ['确定']
// ,style:'width: 80%;max-width: 340px;'
// ,yes: function(){
// window.location.href="{:U('Mobile/User/index')}";
// }, no: function(){
// window.location.href="{:U('Mobile/User/index')}";
// }
// });
var msg='',flag = 0;
var lottery = {
place: 0, //请求后指定停留在某个位置
click: false, //默认值为false可抽奖,防止重复点击
index: -1, //当前转动到哪个位置,起点位置
count: 0, //总共有多少个位置
timer: 0, //使用setTimeout返回的ID,用clearTimeout清除
speed: 20, //初始转动速度
times: 0, //转动次数
cycle: 50, //转动基本次数:即至少需要转动多少次再进入抽奖环节
prize: -1, //中奖位置
init: function(id) {
if ($("#" + id).find(".lottery-unit").length > 0) {
$lottery = $("#" + id);
$units = $lottery.find(".lottery-unit");
this.obj = $lottery;
this.count = $units.length;
$lottery.find(".lottery-unit-" + this.index).addClass("active");
};
},
getLottery: function() {
//ajax请求中奖接口,本案例注释便于案例正常展示效果,实际中可参考注释的代码
$.ajax({
url: "/Mobile/User/luck_draw",//中奖接口
type: 'POST',
dataType: 'json',
data: {
// 'activityCategory': 'POINT_SHOP'//提交字段
}
})
.done(function(data) {
if(data.res){
lottery.place = data.res.sort;
lottery.speed = 100;
lottery.stop(); //转圈过程不响应click事件,会将click置为false
lottery.click = true; //一次抽奖完成后,设置click为true,可继续抽奖
}else{
alert(data.msg);
flag = 1;
return false;
}
})
.fail(function() {
alert('请求失败,请重试!');
return false;
});
// if(odds >= 0){
// lottery.speed = 100;
// lottery.stop(); //转圈过程不响应click事件,会将click置为false
// lottery.click = true; //一次抽奖完成后,设置click为true,可继续抽奖
// }else{
// $('.prize_pic').attr('src','__ELSE__/img/cj5.png');
// $('.prize_yes').addClass('on');
// $('.prize_name,.go_prize_center').css('display','none');
// $('.gongxi').text('抽奖机会用完啦!');
// }
},
roll: function() {
var index = this.index,
count = this.count,
lottery = this.obj;
$(lottery).find(".lottery-unit-" + index).removeClass("active");
index += 1;
if (index > count - 1) {
index = 0;
};
$(lottery).find(".lottery-unit-" + index).addClass("active");
this.index = index;
return false;
},
stop: function() {
lottery.times += 1;
lottery.roll(); //转动过程调用的是lottery的roll方法,这里是第一次调用初始化
if (lottery.times > lottery.cycle + 10 && lottery.prize == lottery.index) {
clearTimeout(lottery.timer);
lottery.prize = -1;
lottery.times = 0;
lottery.click = false;
//可以在这个位置写上中奖弹框,这个是转盘停止时触发事件
//开启中奖弹窗
var src = $(".lottery-unit-"+lottery.index).find('img').attr('src');
var name = $(".lottery-unit-"+lottery.index).find('span').text();
$('.prize_pic').attr('src',src);
$('.prize_yes').addClass('on');
if(lottery.index == 11){
$('.prize_name').css('display','none');
$('.gongxi').text('很遗憾~~');
}else{
$('.prize_name').text(name);
}
console.log('您抽中了第' + lottery.place + '个奖品');
} else {
if (lottery.times < lottery.cycle) {
lottery.speed -= 10;
} else if (lottery.times == lottery.cycle) {
//lottery.place = Math.random() * (lottery.count) | 0; //案例中奖物品通过一个随机数生成
lottery.prize = lottery.place;
// lottery.prize = lottery.place; //这个可以通过ajax请求回来的数据赋值给lottery.place
} else {
if (lottery.times > lottery.cycle + 10 && ((lottery.prize == 0 && lottery.index == 7) || lottery.prize == lottery.index + 1)) {
lottery.speed += 110;
} else {
lottery.speed += 20;
}
}
if (lottery.speed < 40) {
lottery.speed = 40;
};
lottery.timer = setTimeout(lottery.stop, lottery.speed); //循环调用
}
return false;
}
};
// var odds=3;//抽奖机会
$("#lottery .cjBtn").on('click', function(event) {
lottery.getLottery();
if(flag){
return false;
}
event.preventDefault();//防止链接打开
lottery.init('lottery');
if (lottery.click) { //click控制一次抽奖过程中不能重复点击抽奖按钮,后面的点击不响应
layer.open({
content: "正在抽奖过程中,请稍等"
,btnAlign: 'c'
,btn: ['确定']
,style:'width: 80%;max-width: 340px;'
});
return false;
} else {
// lottery.getLottery();
return false;
}
//剩余抽奖机会
// odds=odds-1;
// if(odds > 0){
// $('.sy_num').text(odds);
// }else{
// $('.sy_num').text(0);
// }
});
//闪灯效果
var num = 0;
$(".shanDeng").attr("class",function(){
setInterval(function(){
num++;
if(num%2==0){
$('#deng').addClass("shanDeng2");
}else{
$('#deng').addClass("shanDeng");
$('#deng').removeClass('shanDeng2');
}
},500)
})
//关闭弹窗
$('.close_it').click(function(){
$('.prize_yes').removeClass('on');
$('.prize_pic').attr('src','');
$('.prize_name').text('');
$('.gongxi').text('恭喜你中奖了!');
})
});
</script>