一些主要点
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. 可以满足圆盘式指针旋转的抽奖。