JS抽奖特效练习之四:平滑加减速旋转
我们进行js抽奖点击开始的时候会不停的绕着圈跑,然后停下来,这期间会先变快,然后变慢,然后停下来。
所以这里会涉及到先变快然后在变慢的方法。
为了让速度平滑的过度,可以让速度每次变化的间隔相同就行了,比如最开始的速度是100,下一次98,然后96,94,92...这样就是一次变快2,
我们最开始绕圈跑的算法是借助的setInterval,开始是匀速跑没有问题,现在我们要变速跑就不能使用它了,因为我们速度每一步都要变,如果用它的话每次都要清除停掉又重新开始浪费效率。
所以我们把run方法修改一下,变成往前走一步,也就是把那个setInterval去掉,仅仅让他往前走一步就好:
//往前面走一步 var run = function (speed) { $(".mainbox >div").eq(points[poi]).addClass("cur").siblings().removeClass("cur"); if (points.length - 1 == poi) poi = 0; else { poi++; } }
这里说一下,这个边界值的判断我们先放增加选中效果的前面去更好一点,可以简化一点代码,而且可以让我们后面计算中奖的时候也不需要处理这个边界值
var run = function (speed) { if (poi == points.length) poi = 0; $(".mainbox >div").eq(points[poi]).addClass("cur").siblings().removeClass("cur"); poi++; }
为了方便测试我们可以用个按钮试试,点一次按钮移动一步的效果:
$("#begin").click(function () { run(); });
如图,我每点一次按钮他就移动一步
然后我们分析实现怎么让速度每次加快2,其实很简单,使用setTimeout即可,让执行间隔每次变短2就ok。上面分析了变速不能在用setInterval了,因为setInterval还要每次都去清除一下,因为它是一直执行而不像setTimeout只执行一次
//平滑变速 var changespeed = function () { var speed = 100;//初始速度100 setTimeout(function () { run(); }, speed); speed = speed + 98 setTimeout(function () { run(); }, speed); speed = speed + 96 setTimeout(function () { run(); }, speed); speed = speed + 94 setTimeout(function () { run(); }, speed); }
这样的效果就是平滑的变快移动4格
然后找到规律了,就可以用循环写了。
//平滑变速 var changespeed = function () { var speed = 0; //随机变快步数 var skipnumber = 5 + Math.floor(Math.random() * 25); //变快 for (var jq = 100; jq > skipnumber; jq--) { setTimeout(function () { run(); }, speed); speed += jq; jq--;//在减去1为了速度每次变化2 } //随机变慢到停下来的步数 var slownumber = 110 + Math.floor(Math.random() * 96); //变慢 for (var i = jq; i < slownumber; i++) { setTimeout(function () { run(); }, speed); speed += i; i = i + 2; } }
也可以使用下面的方式好理解一点,上面那个变化的频率使用了循环变量杂到一起可能不是那么好理解(2020-12-18添加):
var changeSpeed = function () { //初始速度 var speed = 100; //变化频率初始值 var rate = 98; //变快的步数 var sikpnumber = 10 + Math.random() * 25; //速度依次递增,速度变快 for (var i = 0; i < sikpnumber; i++) { speed = speed + rate; setTimeout(function () { run(); }, speed); //速度间隔变小 rate = rate - 2; } //速度依次递减,速度变慢 var slownumber = 20 + Math.random() * 56; //变慢 for (var i = 0; i < slownumber; i++) { speed = speed + rate; setTimeout(function () { run(); }, speed); //速度间隔变大 rate = rate + 4; } }
完整一点的类:
//游戏类 var Game = function (map) { var poi = 0; var points = map.points; var mapobj = map.mapobj; //往前面走一步 var run = function (speed) { if (poi == points.length) poi = 0; $(".mainbox >div").eq(points[poi]).addClass("cur").siblings().removeClass("cur"); poi++; } this.begin = function () { changespeed(); } //平滑变速 var changespeed = function () { var speed = 0; //随机变快步数 var skipnumber = 5 + Math.floor(Math.random() * 25); //变快 for (var jq = 100; jq > skipnumber; jq--) { setTimeout(function () { run(); }, speed); speed += jq; jq--; } //随机变慢到停下来的步数 var slownumber = 110 + Math.floor(Math.random() * 96); //变慢 for (var i = jq; i < slownumber; i++) { setTimeout(function () { run(); }, speed); speed += i; i = i + 2; } } }
调用代码片段:
//操作者 var Operator = function () { this.init = function () { //地图类 var map = new Map(); map.createMap(7); //游戏类 var game = new Game(map); game.begin(); } }
当时我们这里的做法暂时是随机来的,后期我们会根据上分下分的数量来计算这一次应该停到什么位置,根据停的位置计算好步数即可。比如王者荣耀抽水晶,根据当前停止的位置就可以判断抽到水晶需要的步骤,要满足什么条件才能生成到达水晶需要的步骤即可,需要再你点击那一刻已经知道你中奖的是什么了
完全随机是没办法做到想赢钱就赢钱的