故如虹,知恩;故如月,知明
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
欢迎加群交流技术

JS抽奖特效练习之四:平滑加减速旋转

5806人阅读 2019/8/21 15:33 总访问:3837924 评论:0 收藏:0 手机
分类: 前端

我们进行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();
    }
}

当时我们这里的做法暂时是随机来的,后期我们会根据上分下分的数量来计算这一次应该停到什么位置,根据停的位置计算好步数即可。比如王者荣耀抽水晶,根据当前停止的位置就可以判断抽到水晶需要的步骤,要满足什么条件才能生成到达水晶需要的步骤即可,需要再你点击那一刻已经知道你中奖的是什么了

完全随机是没办法做到想赢钱就赢钱的



欢迎加群讨论技术,群:677373950(满了,可以加,但通过不了),2群:656732739

评价