最近在做一个抽奖转盘,在这做个小结,好记性不如写博客~~

本文介绍了四种常见的抽奖程序设计方法,包括纯前端操作、客户端加服务端的不同实现方式,并探讨了每种方法的特点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


未经允许,不得转载!!

水平有限,不周之处欢迎指正、交流。

博客原文:http://blog.youkuaiyun.com/ime33


现在市面上很多商家为了促进交易,采取各种各样的营销方案,转盘抽奖就是里面比较经典的一种!但是商家真正的随机中奖,基本那是不可能的!

在市面上看到的抽奖90%以上的中奖概率都是商家程序内定的,中奖概率极低。


要做抽奖主要有几下几种方法:

第一种:纯前端操作(不建议项目使用,纯属研究):

var data = '[{"id":1,"prize":"590大洋","v":20.0},{"id":2,"prize":"100RMB","v":10.0},{"id":3,"prize":"安慰奖","v":10.0}]';// 奖项json 
设置好奖项概率,比如第一个590大洋的概率是20%(其余是谢谢的概率60%),如果在1-100中随机出的,则指针指入到20%的500大洋的绘制角度区域范围,视为中奖。

假设我们在1-100之间randomnum随机产生一个数X,X大于100-20且X小于等于100则视为该项中奖,依次类推。

这时候我们已经知道中的奖项是多少了,接下来就是在转盘上指针指到该奖项的角度范围,该奖项角度var angle0 = [ 344, 373 ]区间,js控制在该角度区间随机产生一个角度加上旋转的基础角度,最终效果就是随机停留在该中奖区域内!

var angle0 = [ 344, 373 ];//一等奖
      var angle1 = [ 226, 256 ];//二等奖
      var angle2 = [ 109, 136 ];//三等奖
      switch (index) {
      case 0:// 一等奖
        var r0 = randomnum(angle0[0], angle0[1]);//在一等奖中奖概率区间取随机角度数
        angle = r0;
        break;
      case 1:// 二等奖
        var r1 = randomnum(angle1[0], angle1[1]);
        angle = r1;
        break;
      case 2:// 三等奖
        var r2 = randomnum(angle2[0], angle2[1]);
        angle = r2;
        break;
      }


最后一步就中奖信息展示,表单,入库,发放等等。


第二种:客户端+服务端方式,这是比较科学的。

在用户进行点击的时候,向服务端发送请求中奖信息:

概率:

$prize_arr = array(
    '0' => array('id' => 1, 'prize' => '一等奖', 'v' => 5),
    '1' => array('id' => 2, 'prize' => '二等奖', 'v' => 5),
    '2' => array('id' => 3, 'prize' => '三等奖', 'v' => 5),
    '3' => array('id' => 4, 'prize' => '四等奖', 'v' => 5),
    '4' => array('id' => 5, 'prize' => '五等奖', 'v' => 5),
    '5' => array('id' => 6, 'prize' => '六等奖', 'v' => 5),
    '6' => array('id' => 7, 'prize' => '七等奖', 'v' => 5),
    '7' => array('id' => 8, 'prize' => '八等奖', 'v' => 5),
    '8' => array('id' => 9, 'prize' => '九等奖', 'v' => 5),
    '9' => array('id' => 10, 'prize' => '十等奖', 'v' => 5),
    '10' => array('id' => 11, 'prize' => '十一等奖', 'v' => 25),
    '11' => array('id' => 12, 'prize' => '十二等奖', 'v' => 25),
);


function getRand($proArr) {
    $data = '';
    $proSum = array_sum($proArr); //概率数组的总概率精度 

    foreach ($proArr as $k => $v) { //概率数组循环
        $randNum = mt_rand(1, $proSum);
        if ($randNum <= $v) {
            $data = $k;
            break;
        } else {
            $proSum -= $v;
        }
    }
    unset($proArr);

    return $data;
}
后端根据用户、奖项、时间等信息综合计算出该用户中奖信息再返回给前台,前台趁着旋转的空挡进行处理中奖信息以及转盘的转动、停止位置!


第三种:也是客户端+服务端

区别在于当用户一开始进入的时候,服务端就已经计算出是否中奖以及奖项信息,返回到前台,这时候前台处理只要转动,停止转盘即可!不容易发现作弊,卡壳!


第四种:服务端高大上的中奖处理

1、绝对概率,名额递减。
服务器会设置10个奖励组对应10个奖励,给每个组1个绝对概率,让服务器随机。
即假设,我们设置:
奖励1:80%概率 奖励2:10%概率 奖励3:5%概率 奖励4:3%概率 奖励5:1%概率 奖励6:0.5%概率 奖励7:0.25%概率 奖励8:0.1%概率 奖励9:0.1%概率 奖励10:0.05%概率
比如奖励10的名额为1。奖励9的名额为2。奖励1的名额为100。
每次进入到该档次被人抽中后,名额会-1。
这种后台随机的时候是绝对随机,80%概率会获得“再接再厉”。当用户进入到某档次后如果名额为0,那么判断进入到再接再厉档次。

2、权重分配,名额递减。
服务器会设置10个奖励组对应10个奖励,给每个组设立1个权重值。
假设,我们设置:
奖励1:500,奖励2:200,奖励3:100,奖励4:50,奖励5:40,奖励6:30,奖励7:20,奖励8:10,奖励9:5,奖励10:1
然后假设奖励10名额为1,奖励9的名额为2。奖励1的名额需要策划预先预估会参与此次活动的总人数。
那么,假若要抽到奖励5的概率为:
(奖励5权重*奖励5剩余名额)/(奖励1权重*奖励1剩余名额+奖励2权重*奖励2剩余名额+奖励3权重*奖励3剩余名额+…………奖励10权重*奖励10剩余名额)
每次这个档次被人抽中后,名额会-1。
这种后台随机的时候是相对随机,概率会跟随名额变化不停变动。当奖励组5的名额为0的时候,也不会落入”再接再厉“,而是可能落到奖励组4里。



个人建议一般的抽奖项目,采用第三种方式,处理方式、安全性、用户体验也比较好!

在前端制作一个抽奖转盘通常涉及到HTML、CSS和JavaScript的结合,这里是一个简单的步骤概述: 1. **HTML结构**: - 创建一个圆形区域作为转盘容器,添加几个“奖品”项,每个奖品可以是一段文字、图片或者链接。 ```html <div class="spin-wheel"> <div class="wheel" id="turningWheel"> <!-- 奖品项 --> <div class="slice prize" data-prize="一等奖"></div> <!-- 更多奖品项... --> </div> </div> ``` 2. **CSS样式**: - 设置转盘的样式,包括圆角、大小、背景颜色等,并将奖品项设为绝对定位以覆盖整个圆环。 ```css .spin-wheel { position: relative; width: 400px; height: 400px; } .wheel { width: 100%; height: 100%; border-radius: 50%; background-color: #f8f9fa; } .prize { position: absolute; /* 根据实际需求调整位置 */ } ``` 3. **JavaScript动画及交互**: - 使用JavaScript创建事件监听器,当用户点击开始按钮时,计算随机选择的奖品并旋转转盘到对应的位置。 - 可以利用`requestAnimationFrame`函数来实现平滑的旋转效果。 ```javascript const wheel = document.getElementById('turningWheel'); const prizes = wheel.querySelectorAll('.prize'); function spin() { // 计算旋转角度 const randomAngle = Math.random() * (360 - 180) + 180; // 避免直接正中间 requestAnimationFrame(spin); wheel.style.transform = `rotate(${randomAngle}deg)`; } // 添加开始按钮点击事件,触发旋转 document.getElementById('startButton').addEventListener('click', spin);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值