【javascript】九宫格抽奖组件设计

一些主要点

1. 转圈的顺序(顺时针或者逆时针);

2. 转圈的速率(从慢到快再到慢);

3. 位置的问题(下一次抽奖的起始位置是上一次抽奖的结束位置);

4. 转圈的圈数或者移动的次数。

基本原理

1. 抽奖的过程其实就是通过不断的改变 dom(通常为 li)的索引值,来达到移动的效果(比如 8 个奖项,索引值的变化如下 0 -> 1, 1 -> 2, ... , 6 -> 7 , 7 -> 0),所以 dom 的排版(绝对定位)就显得很重要了;

2. 对于移动的速度其实就是 dom 切换的快慢,在 js 中,我们可以通过定时器 setTimeout 的执行时间来控制移动的速度;

3. 移动速度的增减;

4. 什么时候移动结束。

如何写代码

外部如何使用

1. 首先通过构造函数实例化,并且在实例化时传入相关参数(一般都为 object)(比如 var lottery = new Lottery(opts)),来实现该组件的初始化;

2. 组件初始化后,还需要有个方法来执行抽奖的过程(比如 lottery.start());

3. 当然我们还需要告诉组件中的是什么奖励(一般都是接口调用返回给前端),即中奖的位置在哪里,相当于奖励的索引(比如 lottery.prize = 1)。

实例化参数 opts

  • opts.index 当前移动到哪个位置,起点位置,默认第一个(即容器的第一个子元素)
  • opts.length 奖励个数,默认 8 个
  • opts.speed 初始移动速度
  • opts.maxSpeed 移动最大速度,数值越小,移动越快
  • opts.minSpeed 移动最小速度,数值越大,移动越慢
  • opts.base 基本移动次数,即小于基本转动次数时,速度递增,大于该数值,速度递减
  • opts.totals 总移动次数,即大于该数值时,转动即将结束
  • opts.moveTo 移动的过程,有两个参数(before 和 after),before 是移动前的索引值,after 是移动后的索引值,可以在这个方法中自己设置动画效果,比如 css3
  • opts.callback 移动结束之后的回调

内部实现

'use strict';
module.exports = function Lottery(opts) {
    this.index = opts.index || 0;
    this.speed = opts.speed || 60;
    this.maxSpeed = opts.maxSpeed || 40;
    this.minSpeed = opts.minSpeed || 250;
    this.base = opts.base || 3;
    this.totals = opts.totals || 12;
    this.length = opts.length || 8;
    this.prize = -1; // 中奖位置,需要外部来更新
    var self = this;
    var speed = self.speed;
    var timer = null; // 定时器 ID
    var counts = 0; // 移动次数计数
    // 在移动的过程中,其实就是索引值的改变,比如 0 -> 1, 1 -> 2, ... , 6 -> 7 , 7 -> 0
    var move = function() {
        var index = self.index;
        var len = self.length;
        var before = self.index; // 当前
        index += 1; // 下一个
        // 当索引到最后一个时,下一个索引就是第一个
        if (index > len - 1) {
            index = 0;
        }
        opts.moveTo && opts.moveTo(before, index);
        self.index = index;
    };
    // 外部调用抽奖方法
    this.start = function() {
        move();
        counts += 1;
        if (counts > this.totals && this.prize === this.index) {
            clearTimeout(timer);
            counts = 0;
            speed = this.speed;
            this.prize = -1;
            opts.callback && opts.callback();
        } else {
            if (counts < this.base) {
                speed -= 10;
            } else {
                if (counts > this.totals) {
                    speed += 60;
                } else {
                    speed += 30;
                }
            }
            speed = speed < this.maxSpeed ? this.maxSpeed : (speed > this.minSpeed ? this.minSpeed : speed);
            timer = setTimeout(function() {
                self.start();
            }, speed);
        }
    };
};

扩展

1. 不限九宫格排列的抽奖;

2. 可以满足圆盘式指针旋转的抽奖。

posted @ 2018-03-29 10:54  朱羽佳  阅读(955)  评论(0编辑  收藏  举报
回顶部