php+jquery实现转盘抽奖 几率可任意调php
php+jquery实现转盘抽奖 几率可任意调css
Posted by: xiaomiao 2014/05/13in Code, PHP 3 Commentshtml
php+jquery实现转盘抽奖前端
查看DEMO演示html5
转盘抽奖,炫丽的通常是flash作的。不懂flash而又不须要那么炫丽,能够简单的经过jquery来实现。网上教程有不少,跟着作了一下,也贴出来吧。要实现转盘抽奖,有两个关键点,一是让转盘或指针转起来并控制中止角度,一是几率控制。jquery
对于转起来控制中止角度这个问题,网上各教程都是用的jqueryrotate这个jquery插件,兼容性好使用也简单,要我本人本身写也不知道怎么写好,仍是拿来便可。对于几率控制,网上也一致的是这个经典算法:ajax
function getRand($proArr) {算法
$result = '';数据库
//几率数组的总几率精度json
$proSum = array_sum($proArr);
//几率数组循环
foreach ($proArr as $key => $proCur) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur) {
$result = $key;
break;
} else {
$proSum -= $proCur;
}
}
unset ($proArr);
return $result;
}
这里参数是一个几率数组,某一项的出现的几率是其几率精度/总几率精度。好比几率数组是array(’1′=>’40′,’2′=>’60′),那么‘1’这一项出现的几率就是40/(40+60)。为何是这个结果呢,好吧,简单的几率计算:
php经典几率算法解析
php经典几率算法解析
(原谅我为了输这分数,还去百度了一下,囧…)
对于几率数组的来源,实际应用中应该是从数据库里面取,这样方便作各类业务判断,好比某一奖项的几率除了人工干预还根据抽中次数自动变化。我这里为了显示,就写到一个数组里面,并且这找的转盘素材同一奖项还有多处出现,故用这样一个数组来存储(这里根据实际业务而定,不是重点)。
//奖项数据
$prize_arr=array(
'youpan'=>array('angle'=>array('16-40','196-220'),'prize'=>'U盘1个','v'=>10),
'money_2000'=>array('angle'=>array('46-74','170-194'),'prize'=>'2000元代金卷','v'=>5),
'chong_10'=>array('angle'=>array('80-104','226-250'),'prize'=>'10元充值卡','v'=>10),
'money_1000'=>array('angle'=>array('110-134','256-284'),'prize'=>'1000元代金卷','v'=>15),
'flower'=>array('angle'=>array('144-164','286-306'),'prize'=>'鲜花1朵,继续努力','v'=>45),
'chong_50'=>array('angle'=>array('316-340'),'prize'=>'50元充值卡','v'=>5),
'book'=>array('angle'=>array('0-10','346-359'),'prize'=>'书1本','v'=>10),
);
angel是角度,最小角度与最大角度用‘-’隔开,有多个。这个角度是控制转盘或指针最终停下来时离起点的角度,范围是0~360。根据实际素材而定,我这找的图不规则,做图的人坑爹,调了屡次才获得比较精准的角度。v则是几率。
根据上面的奖项设定,经过下面的函数返回转动信息到前台:
//得到旋转信息
function getRotate($prize_arr) {
$data=array();
$option=$_GET;//根据前台的选择更改原定默认几率
foreach($prize_arr as $k=>&$v) {
$v['v']=$option[$k];
}
$prize=getPrize($prize_arr);//经过几率原理设计函数得到其中一个奖项
$angle=$prize['angle'];
shuffle($angle);//打乱角度数组
$angle=$angle[0];
$angle_arr=explode('-',$angle);
$min=$angle_arr[0];
$max=$angle_arr[1];
$angle=mt_rand($min,$max);
$data['angle']=$angle;
$data['message']=$prize['prize'];
$data['duration']=mt_rand(2,5)*1000;
$data['n']=mt_rand(3,6);//为了避免那么单调,随机一下转动时间和转动圈数
echo json_encode($data);
}
至此后端的程序完毕。前端还得有个调整几率的功能,脑子里想到的就是滑动条,html5有这个特性,但样式简单也兼容性也有问题。百度了一下知道jqueryui有相关控件,但不怕笑话做为新人还没用过jqueryui,无心发现了noUiSlider这个专为不使用jqueryui实现滑动条而生的插件,短小精悍。最近又瞄了瞄BootStrap,顺手又拿来排版一下这前端页面,好吧,基本没用到它的什么东西。
如今时间凌晨1:52,夜已深,后面继续。。。
2014/5/14 23:13,继续。
对于改变几率值,上边说了使用noUiSlider,用法能够到官网查看:
$(".youpan").noUiSlider({
start:[10],//起始值
range:{//范围
'min':0,
'max':99,
},
connect:'lower',//写上左边就变色
serialization: {
lower: [
$.Link({
target: $('#youpan')//数值在哪里显示
})
],
format: {
decimals: 0,//数值保留几位小数
mark: ','
}
}
});
在页面加载函数里边给每一个须要滑动的元素绑定以上事件便可。更改各项值放在一个form表单,点击开始抽奖收集表单的信息ajax发送到后台计算出具体的旋转信息,再进行转动抽奖。发送ajax的函数以下:
function getPrize() {
var result=null;
var option=$("#myform").serialize();
$.ajax({
url:"03.php",
type:"GET",
data:option,
dataType:"json",
cache:false,
async:false,//同步,不然没法把后台信息信息捕获
error:function(){
alert('出错了');
return false;
},
success:function(data){
result=data;
}
});
return result;}
接下来是关键的根据后台的信息进行转动并控制中止角度,主要是jqueryrotate的用法,详细的能够点击上边高亮的连接查看。下边也有注释:
function rotate() {
$("#start").css("cursor","pointer");
$("#start").rotate({
bind:{
click:function(){
$(this).unbind('click').css("cursor","default");//取消点击事件
var value=getPrize();
var effect=$("#select").val();
$(this).rotate({
duration:value.duration,//多少毫秒内完成转动
angle:0,//起始角度
animateTo:value.n*360+value.angle,//一共转动多少角度
easing:eval(effect),//转动动画扩展
callback:function(){//结束时的回调函数
alert(value.message);
}
})
}
}
})
}
转动动画那里,注意得eval()一下,不然获得的只是一个字符串不是动画函数。这个动画也是用的jQuery Easing这个插件,插件再借用插件,很常见的事,什么都本身写,是很不现实的,童鞋。这些动画效果用在这里有一两个动不了,不知为什么。把这个rotate函数放到页面加载函数中,在页面加载完毕便可进行转动抽奖。点击以后取消点击事件,是为了防止转动过程当中或者抽完一次后继续点击。固然我这里有“再来一发”就是给再绑上。具体看业务须要,怎么搞都行。
至此,一个简单的转盘抽奖就完成了,虽然简陋了点但也能知足通常的业务须要。有什么问题或者改进意见,欢迎各位看官提出。^~^
update:2015/06/17
鉴于有同窗说不懂03.php里边的内容,顺便贴出来吧。按需修改。
<?php
//奖项数据
$prize_arr=array(
'youpan'=>array('angle'=>array('16-40','196-220'),'prize'=>'U盘1个','v'=>10),
'money_2000'=>array('angle'=>array('46-74','170-194'),'prize'=>'2000元代金卷','v'=>5),
'chong_10'=>array('angle'=>array('80-104','226-250'),'prize'=>'10元充值卡','v'=>10),
'money_1000'=>array('angle'=>array('110-134','256-284'),'prize'=>'1000元代金卷','v'=>15),
'flower'=>array('angle'=>array('144-164','286-306'),'prize'=>'鲜花1朵,继续努力','v'=>45),
'chong_50'=>array('angle'=>array('316-340'),'prize'=>'50元充值卡','v'=>5),
'book'=>array('angle'=>array('0-10','346-359'),'prize'=>'书1本','v'=>10),
);
//根据奖项数据得到具体奖项
function getPrize($prize_arr) {
$proSum=0;
foreach($prize_arr as $v){
$proSum+=$v['v'];
}
foreach($prize_arr as $k=>$v){
$randNum=mt_rand(1,$proSum);//随机数
if($randNum<=$v['v']) {
return $v;
}else{
$proSum-=$v['v'];
}
}
}
//得到旋转信息
function getRotate($prize_arr) {
$data=array();
$option=$_GET;
foreach($prize_arr as $k=>&$v) {
$v['v']=$option[$k];
}
$prize=getPrize($prize_arr);
$angle=$prize['angle'];
shuffle($angle);//打乱
$angle=$angle[0];
$angle_arr=explode('-',$angle);
$min=$angle_arr[0];
$max=$angle_arr[1];
$angle=mt_rand($min,$max);
$data['angle']=$angle;
$data['message']=$prize['prize'];
$data['duration']=mt_rand(2,5)*1000;
$data['n']=mt_rand(3,6);
echo json_encode($data);
//echo json_encode($option);
}