基于JQuery和ES6的前端轮转抽奖

基于JQuery和ES6的前端轮转抽奖_第1张图片

设计思路: 先匀速转动三圈,之后在礼物前五个开始减速,最后停在礼物上即选中预设的礼物。如此循环,直至抽中三个礼物。

基于JQuery和ES6的前端轮转抽奖_第2张图片

先将前端设计好:

<div id="luckyActivity">
    <div id="choujiang">
        <div id="luck">
            <div class="luckList1">
                <div class="luckItem">class="i1" data-intro="礼物1">div>
                <div class="luckItem">class="i2" data-intro="礼物2">div>
                <div class="luckItem">class="i3" data-intro="礼物3">div>
                <div class="luckItem">class="i4" data-intro="礼物4">div>
            div>
            <div class="luckList2">
                <div class="luckGroup">
                    <div class="luckItem">class="i12" data-intro="礼物12">div>
                    <div class="luckItem">class="i11" data-intro="礼物11">div>
                div>
                <div id="luckBtn">
                    id="iwanna">我要抽奖
                    

class="luckInfo">随机抽取3样奖品

div> <div class="luckGroup"> <div class="luckItem">class="i5" data-intro="礼物5">div> <div class="luckItem">class="i6" data-intro="礼物6">div> div> div> <div class="luckList3"> <div class="luckItem">class="i10" data-intro="礼物10">div> <div class="luckItem">class="i9" data-intro="礼物9">div> <div class="luckItem">class="i8" data-intro="礼物8">div> <div class="luckItem">class="i7" data-intro="礼物7">div> div> div> div>

这里要注意的是礼物的顺序以及编号,左上角为1号礼物,以此顺时针推算,最后一个礼物为12号。
data-intro用来为礼物的描述做铺垫,我们可以为每一个礼物添加hover效果:
基于JQuery和ES6的前端轮转抽奖_第3张图片
代码如下:

$('.luckItem a').hover(function() {
            $(this).addClass('prizeIntro');
        }, function() {
            $(this).removeClass('prizeIntro');
        })
.prizeIntro:after {
        content: attr(data-intro);
        display: block;
        position: absolute;
        top: 48px;
        height: 29px;
        width: 75px;
        font-size: 14px;
        color: #fff;
        line-height: 29px;
        text-align: center;
        background-color: rgba(0, 0, 0, 0.7);
    }

其次,就是轮转的核心部分了。

var prizeIndex = 1;    // 礼物序号
var liwu = [7, 5, 11];   // 后端值(将要选取的三个礼物)
var l = 0;    // liwu[l]
var distance = 5;   //距离多少格前开始减速

function roundPrize() {
            //此方法的作用是使我们的选中框先匀速转三圈
            return new Promise(function(resolve) {
                var timeStep = 45;    // 转动速度(毫秒)
                var round = 0;    // 用于记录转了多少下

                setTimeout(function(){
                    $('.luckItem a').removeClass('onPrize');
                    $('.i'+ prizeIndex++ ).addClass('onPrize');

                    if(prizeIndex > 12) {    //转12次一循环
                        prizeIndex = 1;
                    }
                    //算法中最复杂的往往是数学部分
                    //转动次数是确定于一个值的,譬如我们要选取的第一个礼物是5号,那么我们应该转动36次(在被选取礼物前五格开始减速)
                    //其次我们在实际测试中会发现,如果后一个礼物值小于前一个(liwu[l] - liwu[l-1] < 0)的情况下,选中框只转两圈就开始减速了,因此我们需要做一个判断,在 小于0 的情况下加上12(即加一圈)
                    if( round++ < ( ( liwu[l] - (liwu[l-1] || 0) ) > 0 ? 36 : 48 ) 
                        + liwu[l] - (distance + 1) - ( (liwu[l-1]) || 0 ) ) {
                        setTimeout(arguments.callee, timeStep);
                    } else {
                        resolve();
                    }
                },timeStep)
            })
        }

至此,我们完成了匀速转动的效果,接着就是减速的部分:

$('#iwanna').click(function() {

            $('.i'+ prizeIndex).addClass('onPrize');
            $('.luckInfo').hide();
            $('#iwanna').text('抽奖中...');

            var call = arguments.callee;

            roundPrize().then(function() {
                let timeStep = 200;    // 初速度
                var ratio = 1.5;   // 速率变化系数
                var endline = Math.floor( timeStep * Math.pow(ratio, distance-1) );

                setTimeout(function() {
                    $('.luckItem a').removeClass('onPrize');
                    $('.i'+ prizeIndex++ ).addClass('onPrize');
                    //'.onPrize'即滚动中的选中效果

                    if(prizeIndex > 12) {
                        prizeIndex = 1;
                    }

                    if(timeStep < endline) {
                        timeStep *= ratio;
                        setTimeout(arguments.callee, timeStep);
                    } else {
                        $('.onPrize').parent().addClass('prizeMe').end().removeClass('onPrize');
                        //'.prizeMe'即礼物选中的CSS样式
                        l++;    // 下一份礼物
                        if(l < 3) {    //循环三次即选三次礼物
                            setTimeout(call, 1000)
                        } else {    
                            $('.luckItem a').removeClass('onPrize');
                            //此处可以添加结束事件
                        }
                    }
                }, timeStep)
            })
        })

在部分老版本编辑环境中 ES6 语法可能会报错,但这并不影响在浏览器中的运行。

你可能感兴趣的:(前端,设计,ecmascript6,jquery)