怎么实现一个九宫格抽奖?

3,832 阅读2分钟

效果预览

九宫格抽奖.gif

image.png

实现思路

将高亮的方块盒子的执行顺序定义好,利用定时器将速度调节为由快到慢,等速度降到某个区间就判断高亮的下标是否匹配最终的奖品下标,匹配则开奖,不匹配则继续降速。

正文

每到特殊的节日或者搞活动的时候就需要开发配合运营,搞一些抽奖的活动,比较常用的抽奖方式有:大转盘,九宫格,老虎机等。这次我们来实现一个九宫格抽奖。

页面结构

<ul>
    <li id="draw_{{id}}">
        {{ name }}
    </li>
    <li id="draw_{{id}}">
        {{ name }}
    </li>
    <li id="draw_{{id}}">
        {{ name }}
    </li>
</ul>

处理数据

由于九宫格中间需要放一个点击按钮,并且滚动的时候是围绕中间的按钮按顺时针滚动。

image.png image.png

蓝色字是未排序的, 红色字是排序后的, 现在按照此图的顺序对数据进行排序

handleValue( obj ) {
    const _action = {
        'draw_3': _ => {
            this.Swap( obj, 3, obj.length - 1);
        },
        'draw_4': _ => {
            this.Swap( obj, 4, obj.length - 1);
        },
        'draw_5': _ => {
            this.Swap( obj, 5, obj.length - 2);
        }
    }

    for( let i in _action ) {
        const branch = _action[`${i}`];
        branch.call(this);
    }
    return obj
            .slice(0,4)
            .concat({ id: 77, text: '开始抽奖' })
            .concat(obj.slice(4));
},

Swap( obj, begin, end) {
    let temp = obj[begin];
    obj[begin] = obj[end];
    obj[end] = temp;
}

  • 当下标为3的时候实际上是最后一个奖品手表调用Swap将下标3以及下标7两个奖品调换位置;
  • 当下标为4的时候,这个位置应该是放下标为3的数据,经历第一轮的替换下标3的位置此刻放在下标7的位置上所以我们这次调用Swap将下标4以及下标3两个奖品调换位置;
  • 当下标为5的时候应当和下标6互换,完成这一步后就排序完成了;
  • 最后是插入抽奖按钮,先切割前4条数据在接上按钮最后在接上后4条数据就形成了一个九宫格;

转动实现

定时器开启后下标快速叠加并且添加高亮样式。

run( vm, num ) {
    if ( num != 'draw_77' ) return;
    setTimeout( _ => {
        prize = Math.floor( Math.random() * 8 );
    },1000);
    // 存储li的dom
    gather = vm.find('li')
    this.lottery( 10 );
},

lottery( time ) {
    if ( time < 600 ) {
        this.dilution( time, 0.1 );
        return false;
    }
    // 如果time超过600 此刻当前的下标不等于最终的奖品的下标的话 则再次进行降速
    if ( activeIndex != prize ) {
        this.dilution( time, 0.05 );
    } else {
        setTimeout( _ => {
            // 如果抽中的是-1就转成最后一个 -1代表的是最后一个奖项
            const tips = coordinate[activeIndex] == -1 ? 8 : coordinate[activeIndex];
            alert(`恭喜抽中${_obj[tips].text}`);
            Alltime = null;
        },10);
    }

},
// coordinate = [0,1,2,5,-1,8,7,6,3];
dilution( time, second ) {
    Alltime = setTimeout( _ => {
        let ask = activeIndex + 1;              // 累计累加下标
        activeIndex = ask % 9;
        gather.eq(coordinate[activeIndex])      // 获取此刻该添加高亮样式的元素
                .addClass('active')             // 添加高亮样式
                .siblings('.active')            // 筛选出active所有的同级元素
                .removeClass('active');         // 删除同级元素的高亮样式
        this.lottery( time + time * second );
    }, time )
}
  • 只有点击到按钮时才会进行滚动, prize是最终的奖品的下标,gather存储所有的li元素;
  • 如果是根据滚动的下标添加高亮样式,一旦滚起来是不规律的因为在处理数据的时候进行了位置交换,你看到的位置是下标3但实际上他是下标7,所以我们需要制定一个滚动顺序coordinate,快速滚动对应的下标应该是哪一个高亮。

最后

以上的代码稍微改动就可以套用到Vue Reatc上,工作上开发这种营销组件的需求不少,我们也应当多写多练。 源码在这 感谢大家的阅读,希望看完大家能有所收获! 觉得有用就点个赞吧,你的点赞是我创作的最大动力~