123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- function RaffleRotate(option) {
- this.prizeNums = option.prizeNums; // 奖项个数
- this.prizeDeg = 360 / option.prizeNums; // 每个奖项所占的角度
- this.activePrize = 0; // 抽中的奖项序号 0角度的奖项对应最后一个序号: 比如6个奖项,0角度时的奖项序号是6
- this.rotateDom = null;
- if(option.rotateDom) {
- this.rotateDom = option.rotateDom;
- }
- this.endCallback = option.endCallback || function() {}; // 转动结束时的回调函数
- this.preTimestamp = 0; //前一次requestAnimationFrame调用的时刻
- this.originalStartTimes = 0; // 转动动画最开始的时间点
- this.easeOutSatrtDeg = 0; // 开始减速时rotateDom转动的角度
- this.easeOutTimer = 0; // 减速转动开始的时刻
- this.easeOutEndDeg = 0; // 减速转动结束时rotateDom应该停留的角度
- this.deg = 0; // rotateDom的实时角度
- this.maxSpeed = 20; // 转动的最大速度
- this.isRotating = false; // 是否正在旋转中
- this.forceStop = false;
- }
- RaffleRotate.prototype = {
- constructor: RaffleRotate,
- raffleRotaing: function() {
- var self = this;
- function rotating(timestamp) {
- if(self.forceStop) {
- self.forceStop = false;
- return;
- }
- if (self.preTimestamp === undefined) {
- self.preTimestamp = timestamp; // 初始化
- }
- var totalElapsed = timestamp - self.originalStartTimes; // 从动画开始到此刻的时间间隔
- var fps = timestamp - self.preTimestamp; // 两次requestAnimationFrame调用的时间间隔 屏幕刷新帧率
- // 从0速度开始加速直到maxSpeed
- self.deg = self.deg + self.easeIn(totalElapsed,0,self.maxSpeed,2000);
- self.deg = self.deg % 360; // 防止角度值过大
- // console.log(deg);
- if(self.rotateDom) {
- self.rotateDom.style.transform = 'rotate(' + self.deg + 'deg)';
- }
- self.preTimestamp = timestamp;
- if(self.activePrize > 0) {
- self.easeOutTimer = timestamp;// Date.now();
- // 开始减速时rotateDom转动的角度
- self.easeOutSatrtDeg = self.deg;
- let i = 0;
- while(++i) {
- // 结合开始减速时所处的位置和结束时所处的位置计算旋转总路程
- const endDeg = 360 * i - (self.activePrize * self.prizeDeg) - self.easeOutSatrtDeg;
- // 计算刚开始第一帧旋转的角度,也就是初始速度
- const curSpeed = self.easeOut(fps, self.easeOutSatrtDeg, endDeg, 2000) - self.easeOutSatrtDeg;
- // 当初始速度与当前旋转最大速度相等,即可获取总共需要旋转的角度
- if (curSpeed >= self.maxSpeed) {
- self.easeOutEndDeg = endDeg;
- break;
- }
- }
- // 开始减速
- return self.slowDown();
- }
- window.requestAnimationFrame(rotating);
- }
- window.requestAnimationFrame(function(timestamp) {
- self.originalStartTimes = timestamp;
- rotating(timestamp);
- });
- },
- slowDown: function () {
- var self = this;
- window.requestAnimationFrame(function(timestamp) {
- // 开始减速时刻到此时刻的时间间隔
- const timeInterval = timestamp - self.easeOutTimer;
- // 减速完成
- if (timeInterval >= 2000) {
- self.isRotating = false;
- self.endCallback({
- index: self.activePrize,
- deg: self.deg
- });
- self.resetInit();
- return;
- }
- // 缓出减速
- self.deg = self.easeOut(timeInterval, self.easeOutSatrtDeg, self.easeOutEndDeg, 2000) % 360;
- if(self.rotateDom) {
- self.rotateDom.style.transform = 'rotate('+ self.deg+ 'deg)';
- }
- self.slowDown();
- });
- },
- forceStopRotating: function() {
- this.forceStop = true;
- },
- setActivePrizeIndex: function(index) {
- this.activePrize = index;
- },
- resetInit: function() {
- this.forceStop = false;
- this.activePrize = 0;
- },
- // t:缓动开始时间 ms
- // b:缓动开始位置 deg
- // c:缓动移动的距离 deg
- // d:缓动持续的时间 ms
- // 结果值为当前位置值 deg
- // 缓入函数
- easeIn: function (t, b, c, d) {
- if (t >= d) t = d;
- // 除法赋值(/=)运算符将变量除以右操作数的值,并将结果赋值给该变量。
- return c * (t /= d) * t + b;
- },
- // 缓出函数
- easeOut: function (t, b, c, d) {
- if (t >= d) t = d;
- return -c * (t /= d) * (t - 2) + b;
- }
- };
- export { RaffleRotate }
|