被黑心商家坑了N次,探究抽奖背后的秘密 —— H5转盘小游戏完整实现(源码直接拿走)

简介: 笔记

1. 基础的页面布局(index.html)


  • 这里不做过多解释了,就是一些页面布局
  • 大家直接复制粘贴过去用就行(是不是很贴心~)

1.1 html布局

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="./css/style.css">
    <title>九宫格抽奖</title>
</head>
<body>
    <div class="container">
        <p>H5转盘抽奖(可自由设置概率)</p>
        <ul class="lottery">
            <li class="item lottery-item-0">华为手机</li>
            <li class="item lottery-item-1">iPhone 手机</li>
            <li class="item lottery-item-2">谢谢惠顾</li>
            <li class="item lottery-item-7">小熊抱枕</li>
            <li class="item start" οnclick="start(event)" data-able="1">开始</li>
            <li class="item lottery-item-3">小度音响</li>
            <li class="item lottery-item-6">电风扇</li>
            <li class="item lottery-item-5">格力冰箱</li>
            <li class="item lottery-item-4">小米手环</li>
        </ul>
    </div>
  </body>
</html>

1.2 css布局(style.css)

@charset "UTF-8";
html{
  height: 100%;
  font-size: 16px;
}
body{
    font-family:-apple-system-font, "Helvetica Neue", sans-serif;    
    -webkit-font-smoothing: subpixel-antialiased;
}
body, a, h1, h2, h3, h4, h5, h6, ul, li, dl, dt, article, section, div, p, header, footer, menu, input, img{
  margin: 0;
  padding: 0;
}
img{
    vertical-align: middle;
}
p, h1, h2, h3, h4, h5, h6,ul{
  -webkit-margin-before: 0;
    -webkit-margin-after: 0;
    -webkit-padding-start: 0;
    -moz-margin-before: 0;
    -moz-margin-after: 0;
    -moz-padding-start: 0;
    -moz-padding-end: 0;
}
/* clear float */
.clearfix:after {
    content:""; 
    display: block; 
    clear:both;
}
  /* Responsive Layout */
li{
  list-style: none;
}
a{
  text-decoration: none;
}
input{
  -webkit-appearance: none;
}
input:focus{
    outline: none;
}
header{
    height: .88rem;
    border-bottom: 1px solid #ccc;
    background-color: #fff;
}
.header-back{
    width: .36rem;
    height: .36rem;
    float: left;
    margin-top: .27rem;
    margin-left: .28rem;
}
.header-title{
    float: left;
    font-weight: 600;
    width: 90%;
    font-size: .36rem;
    color: #333;
    text-align: center;
    line-height: .88rem;
}
.container{
    font-size: 24px;
    text-align: center;
    padding-top: 50px;
}
.lottery{
    font-size: .32rem;
    width: 6rem;
    height: 6rem;
    margin: .2rem auto;
    display: flex;
    display: -webkit-flex;
    flex-wrap: wrap;
    border: 1px solid #000;
}
.item{
    width: 2rem;
    height: 2rem;
    line-height: 2rem;
    color: orangered;
    font-weight: bold;
    text-align: center;
    border: 1px solid orangered;
    box-sizing: border-box;
    background-size: 100%;
}
.active{
    background: #ffe6cc;
}
button:focus{
    outline: none;
}
.lottery-item-0{
    background-image: url('../img/huawei.png');
}
.lottery-item-1{
    background-image: url('../img/iphone.jpg');
}
.lottery-item-4{
    background-image: url('../img/xiaomi.jpg');
}
.lottery-item-7{
    background-image: url('../img/xiaoxiong.jpg');
}
.lottery-item-3{
    background-image: url('../img/xiaodu.jpg');
}
.lottery-item-6{
    background-image: url('../img/dfs.jpg');
}
.lottery-item-5{
    background-image: url('../img/bingxiang.jpg');
}

2. 工具函数(用于调整概率)


  • 此工具函数传入一个二维数组,用于调整概率
  • 默认商品概率相同,调用的时候 randomNum() 时候不传参数即可
  • 也可以自由设置概率
function randomNum(arr){
    // 1. 容错处理
    arr = arr || [];
    // ES6 Map对象: 键与值的集合 方便访问其键与值
    let m = new Map(arr);
    // 计算概率
    let probability = 0;
    // console.log(m.values())
    for (const i of m.values()) {
        probability += i;
    }
   if(probability > 1){
        // 给一个友好的提示
        alert("概率总和不能大于1,小学数学是体育老师教的???");
        return false;
   }
    // 剩下没有定义的各自能占多少概率。
    // size 返回映射中的元素数
    let remainProbability = (1 - probability) / (8 - m.size);
    console.log(remainProbability)
     // 生成随机值,跟i对应的概率比较,
     let res = 0, r = Math.random();
     for (let i = 0; i < 8; i++) {
         // 有就取值 没有就随机取
         m.has(i) ? res += m.get(i) : res += remainProbability;
        //  console.log("res= "+ res);
        //  console.log("r= "+ r);
         if (res > r) {
             return i;
         }
     }
}

13.png

3. 传参及接收值配置


     let step = 0, //计数器
         timeInterval = 2, //速度控制器
         final, //最终位置
         looperFun, // setTimeout的返回值
         prizeList = ['华为', 'iPhone X', '谢谢惠顾', '小度音响', '手环', '格力冰箱', '电风扇', '小熊抱枕'];
        // 开始游戏
        function start(e){
            if(e.target.dataset.able === "1"){
                // 随机0-7 
                // 设置抽奖概率 不传参的话这几个商品几率相等
                // let arr = [[0,0],[1,0.5],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0]];
                // final = randomNum(arr);
                final = randomNum();  // 这里不传参 概率均等
                console.log(final);
                if(final === false){
                    console.log("出错了");
                    return false;
                }
                e.target.setAttribute('data-able', 0);
                looperFun = setTimeout(looper, 100);
            }else{
                console.log("什么垃圾玩意,点不了");
                return false;
            }
        }
  • 传参的二维数组第一个值代表商品id,第二个值为分配的概率
// 设置抽奖概率 不传参的话这几个商品几率相等
// let arr = [[0,0],[1,0.5],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0]];

4. dom 操作方法及具体逻辑处理


// 获取元素
function $my(classes){
    return document.querySelector(classes);
}
// 旋转九宫格
function looper(){
    // 移除上一个被选中的样式
    $my(".active") && $my(".active").classList.remove("active");
    // 转了超过3圈后才能停止。
    if (step >= 24 + final) {
        $my('.lottery-item-' + final).classList.add('active');
        step = final;
        setTimeout(() => {
            $my('.start').setAttribute('data-able', 1);
            alert('恭喜你,抽中了' + prizeList[final]);
        }, 100);
        clearTimeout(looperFun);
        return;
    }
    //当前转圈到的位置。
    let index = step % 8;
    $my('.lottery-item-' + index).classList.add('active');
    step++;
    // 下次变色的时间。
    let duration;
    if (step >= (16 + final)) { //在剩余一圈时候开始减速
        timeInterval += 1;
    } else {
        if (timeInterval <= 2) {
            timeInterval = 2; //时间缩短不能太小。
        }
        // 越来越快
        timeInterval--;
    }
    duration = timeInterval * 50;
    looperFun = setTimeout(looper, duration);
}

image.png

5. FAQ(注意事项)


  • 手机端和PC端都可以操作
  • 商品图需要自己引入一下
  • 注意引入路径问题
  • js文件可以只写一个(第三步和第四步放一起就行)
  • 一下子看不完,可以收藏一波,一步步来就行,有问题可以直接私聊我
目录
相关文章
|
域名解析 小程序 Linux
朋友圈超火的盲盒交友小程序,完整搭建教程及源码分享~(多图)
朋友圈超火的盲盒交友小程序,完整搭建教程及源码分享~(多图)
朋友圈超火的盲盒交友小程序,完整搭建教程及源码分享~(多图)
|
2月前
|
Python
【分享代码】国庆氛围不能少,快来给头像加个国旗
【分享代码】国庆氛围不能少,快来给头像加个国旗
29 0
|
11月前
DFM分析~好工具分享(抽奖送书!)
DFM分析~好工具分享(抽奖送书!)
|
Java 应用服务中间件 数据库
电商促销后台设计,写得太好了!
电商促销后台设计,写得太好了!
266 0
电商促销后台设计,写得太好了!
|
小程序 JavaScript
小程序实现大转盘仿天猫抽奖 跑马灯效果(有图有源码)---微信小程序源码大集004
小程序实现大转盘仿天猫抽奖 跑马灯效果(有图有源码)---微信小程序源码大集004
233 0
|
IDE 小程序 数据可视化
关于我用iVX沉浸式体验了一把0代码创建电影院购票小程序这件事
Hello !~大家好,之前已经在专栏中写过4篇iVX文章了,欢迎大家去我的文章中找! 相信大家都在手机上购买过电影票,进行购票的座位选择等等,那么今天给大家带来的是使用iVX零代码开发私人影院购票小程序,话不多说,我们直接开始~
关于我用iVX沉浸式体验了一把0代码创建电影院购票小程序这件事
|
存储 SQL NoSQL
社交软件红包技术解密(十二):解密抖音春节红包背后的技术设计与实践
本文将要分享的是春节期间海量红包社交活动为抖音所带来的各种技术挑战,以及抖音技术团队是如何在实践中一一解决这些问题的。
321 0
社交软件红包技术解密(十二):解密抖音春节红包背后的技术设计与实践
|
存储 JavaScript 程序员
五分钟学会做一个在线抽奖系统,手把手教你抽奖还学不会嘛?
五分钟学会做一个在线抽奖系统,手把手教你抽奖还学不会嘛?
441 0
五分钟学会做一个在线抽奖系统,手把手教你抽奖还学不会嘛?
|
iOS开发 MacOS Python
抽奖过程公布,我用了一款有故事的抽奖工具
之前学委发表了一篇文末抽奖的文章:Python中处理字符串的常用函数汇总【文末送书】
181 0
抽奖过程公布,我用了一款有故事的抽奖工具