滚动抽奖点名JS实现

滚动抽奖纯JS实现

最近老师让我用html+css+js实现一个课堂抽奖点名问答问题的一个功能,

因为之前用过轮播图的代码,所以就想到用类似轮播的方式来实现。

通过设置容器left定位负数容器会向左移动

效果如下:

请添加图片描述

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    .lucky-draw {
        padding-top: 20px;
        overflow: hidden;
        position: relative;
        height: 320px;
        left: 50%;
        transform: translateX(-50%);
        top: 120px;

    }
    .lucky-draw-item {
        float: left;
        width: 200px;
        height: 200px;
        position: relative;
        /*background: red;*/
        text-align: center;
        line-height: 120px;
    }
    .lucky-draw-item img {
        width: 200px;
        height: 200px;
    }
    .lucky-element-wrap {
        position: absolute;
    }
    #btn {
        position: absolute;
        width: 100px;
        height: 25px;
        background: beige;
        bottom: 10px;
        left: calc(50% - 50px);
    }

    .lucky-draw-name {
        position: absolute;
        font-size: 15px;
        font-weight: bold;
        color: black;
        width: 50px;
        height: 30px;
        bottom: -5px;
        left: 50%;
        transform: translateX(-50%);
    }
    .lucky-draw-results {
        display: none;
        padding-top: 25px;
        width: 250px;
        height: 290px;
        background: beige;
        position: absolute;
        left: 50%;
        top: -30px;
        transform: translateX(-50%);
    }
    .lucky-draw-results p {
        padding-left: 35px;
        text-indent: 1em;
    }
    .lucky-draw-results img {
        width: 130px;
        height: 130px;
        border-radius: 50%;
        margin-left: calc(50% - 65px);
        margin-top: 30px;
    }
    .lucky-draw-results>input {
        width: 60px;
        margin-left: calc(50% - 30px);
        background: beige;
    }


    /* 图片放大放小 */
    .ballon{
        -webkit-animation-name: likes; /*关键帧名称*/
        -webkit-animation-timing-function: linear; /*动画的速度曲线*/
        -webkit-animation-iteration-count: infinite;  /*动画播放的次数*/
        -webkit-animation-duration: 1s; /*动画所花费的时间*/
    }

    @keyframes likes {
        0%{
            transform: scale(1.2);
        }
        25%{
            transform: scale(1.1);
        }
        50%{
            transform: scale(1.05);
        }
        75%{
            transform: scale(1.1);
        }
        100%{
            transform: scale(1.2);
        }
    }

</style>
<body>
<!-- 外层容器 -->
<div class="lucky-draw">
    <!--  抽奖元素容器通过 -left 移动 -->
    <div class="lucky-element-wrap">
        <div class="lucky-draw-item">
            <img src="../luckImg/aiHuanZhi.jpg" alt="">
            <p class="lucky-draw-name">0</p>
        </div>
    </div>
    <!-- 抽奖结果 -->
    <div class="lucky-draw-results">
        <img src="../luckImg/aiHuanZhi.jpg" alt="" class="ballon">
        <p class="">中奖啦!!请XXX同学
            </br>起立问答问题</p>
        <input type="button" value="确认">
    </div>
    <input type="button" value="抽奖" id="btn">
</div>

<script src="../js/jquery-1.7.2.js"></script>
<script>
    let random;              // 随机数
    let perWidth = 200;     // 一张图片的宽度
    let luckyDrawWrapper = document.querySelector('.lucky-draw'); // 最外层容器
    let index = 0;          // 当前是第几张图片
    let timer;              // 定时器标识
    let turnsNumber = 2;    // 空转圈数,空转圈数要比总圈数数少,总圈数 = 填充数组数
    let btn = document.querySelector('#btn');
    let luckyResult = document.querySelector('.lucky-draw-results'); // 中奖结果
    // 生成空转元素两个空转数组data1、data2,抽奖数组data3、data4补位数组data5
    let data1 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24];
    let dataName = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24];
    let dataImg = [
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
        "../luckImg/ai.jpg",
         "../luckImg/ai.jpg"
    ]

    function appendItem(data,count) {
        for (let j = 0; j < count; j++) {
            for (let i = 0; i < data.length; i++) {
                let item = $("<div class='lucky-draw-item'" +
                    " data-index='"+ i +"'></div>");
                let img = $("<img src='" + dataImg[i] + "'>");
                let pName = $("<p class=\"lucky-draw-name\">" + dataName[i] + "</p>");
                $(item).append(img);
                $(item).append(pName);
                $(".lucky-element-wrap").append(item);
            }
        }
    }
    appendItem(data1,5); // 填充抽奖数组
   	let luckyElementWrapper = document.querySelector('.lucky-element-wrap');  // 抽奖元素容器
	let itemWrapper = document.querySelectorAll('.lucky-draw-item');          // 抽奖元素项容器
	luckyDrawWrapper.style.width = perWidth * 7 + 'px';                       // 一行显示7个
	luckyElementWrapper.style.width = perWidth * itemWrapper.length + 'px';   // 设置抽奖元素容器总宽度
    //封装生成随机数函数
    function getRandom(n, m) {
        return Math.floor(Math.random() * (m - n + 1) + n);
    }
    // wrapper 初始化
    function swiperInit() {
        luckyElementWrapper.style.left = '-' + perWidth * index + 'px';
    }
    // 移动
    function leftMove() {
        index++;
        luckyElementWrapper.style.left = '-' + perWidth * index + 'px';
        luckyElementWrapper.style.transition = 'left 0.5s ease-out';
    }
    // 自动滚动
    function autoplay() {
        timer = setInterval(() => {
            leftMove();
            if (index >= data1.length * turnsNumber - 4) { // 空转之后开始减慢
                clearInterval(timer);
                timer = setInterval(() => {
                    luckyElementWrapper.style.transition = 'left 0.5s ease-in-out';
                    leftMove();
                    console.log(index)
                    if (index === random - 3) {  // 中奖图片要停留到中间,如果刚刚好它中奖图片会停留在第一个位置,所以要减少移动三个图片的位置
                        var luckNode = $(itemWrapper).get(random);
                        setTimeout(function () {
                            // 显示中奖结果
                            let index = luckNode.getAttribute("data-index");
                            $(luckyResult).find("img").attr("src",dataImg[index]);
                            let text = "中奖啦!!请" + dataName[index] +"同学</br>起立问答问题"
                            $(luckyResult).find("p").html(text);
                            $(luckyResult).slideDown();
                        },550)
                        clearInterval(timer);
                    }
                },100)
            }
        }, 50);
    }

    // 抽奖点击
    $(btn).click(function () {
        $(".lucky-draw-results").slideUp();
        clearInterval(timer);
        luckyElementWrapper.style.transition = '';
        index = 1;
        random = getRandom(data1.length * turnsNumber, data1.length * 4 - 1);
        swiperInit();
        autoplay();
    })

    // 确认点击
    $(".lucky-draw-results input").click(function () {
        $(".lucky-draw-results").slideUp();
    })

    // 初始化设置
    function init() {

        swiperInit();
    }
    init();

</script>
</body>
</html>

具体实现:

设置抽奖元素容器总宽度

let luckyElementWrapper = document.querySelector('.lucky-element-wrap');  // 抽奖元素容器
let itemWrapper = document.querySelectorAll('.lucky-draw-item');          // 抽奖元素项容器
luckyDrawWrapper.style.width = perWidth * 7 + 'px';                       // 一行显示7个
luckyElementWrapper.style.width = perWidth * itemWrapper.length + 'px';   // 设置抽奖元素容器总宽度

每次左移 = luckElementWrapper.style.left = - perWidth * index px
填充抽奖元素数组,我这填充了五次就有五组相同的数据左移实现了轮滚的效果

appendItem(data1,5); // 填充抽奖数组

一二数组用来空滚,三四用来抽奖,五用来补位,假如随机到最后一个下标,

就会出现留白的情况所以需要补位填充

img

随机的下标范围数组2-4,这个下标是相对于抽奖容器的所有元素

random = getRandom(data1.length * turnsNumber, data1.length * 4 - 1); // 随机下标

空转之后减慢滚动速度寻找中奖的下标

if (index >= data1.length * turnsNumber - 4) // 空转之后减慢滚动速度寻找中奖的下标

滚动两圈之后变慢,虽然实现了滚动减慢的效果但不是很好,不是慢慢减慢我使用的是定时器只是固定一个大

间隔也设置过间隔变量让间隔持续变大但是行不通,欢迎指正。

最后:

通过这个抽奖的小Demo,发现因为很久没敲js很多前端的东西都记不清了,当时的作的笔记也不详细

笔记很重要呀,我得找个时间复习补补笔记了bye。

11-26补充:
距离中奖的下标还有七张图片的距离减慢,定时器间隔为250

if (index >= random - 7) { // 空转之后开始减慢,random空转两次的下标

11-27更新:带停止的抽奖

效果:

请添加图片描述

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
<!-- 外层容器 -->
<div class="lucky-draw">
    <!--    &lt;!&ndash; 中间标识箭头 &ndash;&gt;-->
    <!--    <div class="lucky-draw-line"></div>-->
    <!--  抽奖元素容器通过 -left 移动 -->
    <div class="lucky-element-wrap">
      <div class="lucky-draw-item">
         <img src="../luckImg/aiHuanZhi.jpg" alt="">
       	 <p class="lucky-draw-name">0</p
       </div>
    </div>
    <!-- 抽奖结果 -->
    <div class="lucky-draw-results">
        <img src="../luckImg/aiHuanZhi.jpg" alt="" class="ballon">
        <p class="">中奖啦!!请XXX同学
            </br>起立问答问题</p>
        <input type="button" value="确认">
    </div>
    <input type="button" value="抽奖" id="btn">
</div>

<script src="../js/jquery-1.7.2.js"></script>
<script>
    let random;              // 随机数
    let perWidth = 200;     // 一张图片的宽度
    let luckyDrawWrapper = document.querySelector('.lucky-draw'); // 最外层容器
    let index = 0;          // 当前是第几张图片
    let timer;              // 定时器标识
    let btn = document.querySelector('#btn');
    let luckyResult = document.querySelector('.lucky-draw-results'); // 中奖结果
    let dataObject = [
        {"name": "1","imgSrc": "../luckImg/aiHuanZhi.jpg", "weight": 4},
        {"name": "2","imgSrc": "../luckImg/duanJunTao.jpg", "weight": 2},
        {"name": "3","imgSrc": "../luckImg/gaoJiaFu.jpg", "weight": 3},
        {"name": "4","imgSrc": "../luckImg/gouYaoKun.jpg", "weight": 3},
        {"name": "5","imgSrc": "../luckImg/heLiang.jpg", "weight": 2},
        {"name": "6","imgSrc": "../luckImg/huangShang.jpg", "weight": 4},
        {"name": "7","imgSrc": "../luckImg/huangYing.jpg", "weight": 4},
        {"name": "8","imgSrc": "../luckImg/kuangLiPing.jpg", "weight": 4},
        {"name": "9","imgSrc": "../luckImg/leiChenYu.jpg", "weight": 4},
        {"name": "11","imgSrc": "../luckImg/leiKang.jpg", "weight": 4},
        {"name": "12","imgSrc": "../luckImg/liuJinXiang.jpg", "weight": 4},
        {"name": "李12","imgSrc": "../luckImg/liYuQing.jpg", "weight": 4},
        {"name":  "唐12","imgSrc": "../luckImg/tangCaiQing.jpg", "weight": 4},
        {"name": "唐23","imgSrc": "../luckImg/tangErHuang.jpg", "weight": 4},
        {"name": "唐213","imgSrc": "../luckImg/tangJiaYing.jpg", "weight": 4},
        {"name": "唐12","imgSrc": "../luckImg/tangZhiJiang.jpg", "weight": 4},
        {"name": "王12","imgSrc": "../luckImg/wangDong.jpg", "weight": 4},
        {"name": "王123","imgSrc":  "../luckImg/wangPeng.jpg", "weight": 4},
        {"name": "文213","imgSrc": "../luckImg/tangZhiJiang.jpg", "weight": 4},
        {"name": "文123","imgSrc":  "../luckImg/wenYiHui.jpg", "weight": 4},
        {"name": "曾123","imgSrc": "../luckImg/zengBinYan.jpg", "weight": 4},
        {"name": "李123","imgSrc": "../luckImg/liYiLi.jpg","weight": 4},
        {"name": "孙123","imgSrc": "../luckImg/sunJieSong.jpg", "weight": 4},
    ];


    function fillItem(data, count) {
        let wrap = $("<div class='lucky-element-wrap'></div>>");
        for (let j = 0; j < count; j++) {
            for (let i = 0; i < data.length; i++) {
                let item = $("<div class='lucky-draw-item'" +
                    " data-index='"+ i +"'></div>");
                let img = $("<img src='" + dataObject[i].imgSrc + "'>");
                let pName = $("<p class=\"lucky-draw-name\">" + dataObject[i].name + "</p>");
                $(item).append(img);
                $(item).append(pName);
                $(wrap).append(item);
            }
        }
        $(".lucky-element-wrap").replaceWith(wrap);
    }
    fillItem(dataObject,2); // 填充抽奖数组
    // wrapper 初始化
    let luckyElementWrapper = document.querySelector('.lucky-element-wrap');  // 抽奖元素容器
    let itemWrapper = document.querySelectorAll('.lucky-draw-item');
    function swiperInit() {
        luckyDrawWrapper.style.width = perWidth * 7 + 'px';                       // 一行显示7个
        luckyElementWrapper.style.width = perWidth * (itemWrapper.length) + 'px';   // 设置抽奖元素容器总宽度,空填6实测减7
        luckyElementWrapper.style.left = '-' + perWidth * index + 'px';
    }

    // 向右移动一张图片的距离
    let iSpeed = -200;
    function fnMove() {
        //图片向左移动时的条件,即在div里的抽奖容器的offsetLeft小于一个抽奖容器的宽度
        if (luckyElementWrapper.offsetLeft < -luckyElementWrapper.offsetWidth / 2) {
            //将整个复制的抽奖容器向右拖拽直至整个抽奖容器中的第一张图归位到起点
            luckyElementWrapper.style.left = 0;
        }
        //图片向右移动时的条件,即在div里的抽奖容器的offsetLeft大于等于0
        else if (luckyElementWrapper.offsetLeft >= 0) {
            //将整个复制的抽奖容器向左拖拽直至整个抽奖容器中的第一张图归位到起点
            luckyElementWrapper.style.left = -luckyElementWrapper.offsetWidth / 2 + "px";
            // alert(luckyElementWrapper.offsetLeft)
        }
        //给抽奖容器一个速度让整个抽奖容器的offsetLeft增加或减少,速度为正则向右移动,速度为负则向左移动
        luckyElementWrapper.style.left = luckyElementWrapper.offsetLeft + iSpeed + "px";
        let index =  Math.abs(parseInt(luckyElementWrapper.style.left ) / 200);
        console.log(index);
    }

    function showResult() {
        setTimeout(function () {
            let index =  Math.abs(parseInt(luckyElementWrapper.style.left ) / 200);

        // 加三超出数组范围的下标
             if (index === dataObject.length + 1) {
                index = 4
            } else if (index === dataObject.length) {
                index = 3;
            } else if (index === dataObject.length - 3) {
                index = 0;
            } else if (index === dataObject.length - 2) {
                index = 1;
            } else if (index === dataObject.length - 1) {
                 index = 2;
             }
             else {
                index += 3;
            }
            console.log("index" + index);
            $(luckyResult).find("img").attr("src",dataObject[index].imgSrc);
            let text = "中奖啦!!请" + dataObject[index].name +"同学</br>起立问答问题"
            $(luckyResult).find("p").html(text);
            $(luckyResult).slideDown();
        },100);
    }


    let flag = true;
    // 抽奖点击
    $(btn).click(function () {
        if (flag) {
            $(luckyResult).slideUp();
            timer = setInterval(fnMove, 20);
            $(this).val("停止")
            flag = false;
        } else  {
            showResult();
            clearInterval(timer);
            $(this).val("开始")
            flag = true;
        }
    })

    // 确认能点击
    $(".lucky-draw-results input").click(function () {
        $(".lucky-draw-results").slideUp();
    })

    // 初始化设置
    function init() {
        swiperInit();
    }
    init();


</script>
</body>
</html>

参考https://blog.csdn.net/m0_62617719/article/details/128087076