requestanimationframe之缓动的应用

leaf930814 leaf930814     2022-08-21     136

关键词:

之前需要使用的定时器的时,立马想到的是setInterval(),用着用着就成为习惯,并没有遇到什么不妥之处。习惯性的操作往往容易让一个人拒绝尝试一些其他的方法。现在的方法用得好好的,没事干啥找其他法子。

摈弃习惯性操作的思想,没事还真得去尝试一些新方法,不然整天敲一样的代码不无聊么?

对于requestAnimationFrame这个东东,其实很早就知道了,但是也就只是局限于‘知道’而已。

直到后面的项目中,在写一个关于榜单滚动的模块,开始当然用的还是setInterval(),榜单列表每秒向上移动1px,很快项目写完了,回头乍看,榜单在滚动的时候,隐隐约约看到跳帧现象,而且页面背景和榜单背景夜色是反色,看起来效果还是不尽如人意。

这时候我开始寻求优化这个问题,捣鼓好久,打算从从滚动动画开刀,查阅资料,动画优化。。。。。。顺藤摸瓜,就找到了requestAnimationFrame。之前也听说过这个,但是就是没有认真捣鼓过,作为一名有态度的前端人员,明明知道这个样子,你竟然不去捣鼓它为什么是这样子,这俨然和你的气质不符合的。

requestAnimationFrame,从我英语专八的角度翻译过来就是:请求动画帧。这也真是太见名知意了。

那么问题来了,为什么会出现这个东西呢?这个东西有什么优越的地方呢?它怎么用呢?

本着‘存在即有道理’的态度。我倒是来会会这厮~~~

每秒60帧,显示频率16.7ms这是现如今大部分浏览器的标配,当显示频率低于16.7ms的时候,就会发现之前所说的跳帧。当你主动使用setInterval()或者setTimeout()时候,如果显示频率为10m或者5ms,这时候就会出现这种情况,这肯定是会降低其他应用的性能的,这也是我们不能容忍的。

为什么会这样子呢?这就关于到资源的问题。浏览器高效的利用资源的方式应该是:让我通知大家开始和结束,我让你的绘制频率是多少就多少,跟着我走就好了,别瞎比比。

requestAnimationFrame这个API正是扮演这种被使唤的角色而应运而生了。浏览器大哥你放心,我来优化动画。如果我的优点该不够明显,让度娘说说吧:

(浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。比如,通过requestAnimationFrame(),JS动画能够和CSS动画/变换或SVG SMIL动画同步发生。另外,如果在一个浏览器标签页里运行一个动画,当这个标签页不可见时,浏览器会暂停它,这会减少CPU,内存的压力,节省电池电量。)

 

怎么用?很简单。懒得打了。。。。

// 当前时间
var start = 0;
var begin = 0;//开始位置
var end = 100;//结束位置
var during = 100;// 持续时间
var step = function() {
    // 当前的运动位置
    var left = Math.tween.Linear(start, begin, end, during);
    // 位移
    eleBall.style.transform = ‘translateX(+ left + ‘px)‘;
    
    // 时间递增
    start++;
    // 如果还没有运动到位,继续
    if (start <= during) {
         requestAnimationFrame(step);
    } else {
        // 动画结束,这里可以插入回调...
        // callback()...
    }
};
// 开始执行动画
step();

新东西兼容性总是不是十全十美,不过没关系,好东西总会有各种大神去使之完美。

Opera浏览器的技术师Erik M?ller 把这个API的兼容性进行封装

(function() {
    var lastTime = 0;
    var vendors = [‘webkit‘, ‘moz‘];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+‘RequestAnimationFrame‘];
        window.cancelAnimationFrame =
          window[vendors[x]+‘CancelAnimationFrame‘] || window[vendors[x]+‘CancelRequestAnimationFrame‘];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

OK,这不是就好了吗。

缓动的应用

上面的例子已经用了

Math.tween.Linear(start, begin, end, during);
再来一个直观的例子~~~
// 滚动到顶部缓动实现
var backToTop = function (rate) {
    var doc = document.body.scrollTop? document.body : document.documentElement;
    var scrollTop = doc.scrollTop;
    
    var top = function () {
        scrollTop = scrollTop + (0 - scrollTop) /2;
        if (scrollTop < 1) {
            doc.scrollTop = 0;
            return;
        }
        doc.scrollTop = scrollTop;
        requestAnimationFrame(top);    
    };
    top();
};





带有通用缓动的 jQuery 动画队列

】带有通用缓动的jQuery动画队列【英文标题】:jQueryanimationqueuewithcommoneasing【发布时间】:2013-08-0821:28:32【问题描述】:我有排队等待单个元素的jQuery动画:varel=$(\'.elem\');el.animate(width:120,600,\'easeInOutQuint\').animate(width:90,300,\'easeIn... 查看详情

修复了 jQuery 缓动的加速?

】修复了jQuery缓动的加速?【英文标题】:FixedaccelerationforjQueryeasing?【发布时间】:2013-10-0604:35:56【问题描述】:我正在制作一个非常规的网站,它可以水平滚动很远的距离。我注意到jQuery的缓动函数在滚动距离的长度范围内被... 查看详情

javascript惯性缓动实现

...content‘)varstartY=0;//初始位置varlastY=0;//上一次位置/***用于缓动的变量* 查看详情

h5扇形(代码片段)

使用H5canvas绘制的可交互扇形requestAnimationFrame()现有动画实现方式的不足setTimeout和setInterval都不十分精确。为它们传入的第二个参数,实际上只是指定了把动画代码添加到浏览器UI线程队列中以等待执行的时间。如果队列前面已经... 查看详情

canvas缓动3

这次缓动的是旋转旋转,写完之后才知道原来rotate是绕原点旋转,而且还带着rect本身的X与Y一起,所以我采用了translate达到位移效果,以免旋转到画布外面去,画完之后效果惨不忍睹,原来是忘记还原变形了,最后加上了save和re... 查看详情

Jquery 缓动动画在 iPad 上滞后

】Jquery缓动动画在iPad上滞后【英文标题】:JqueryeasinganimationslagoniPad【发布时间】:2015-01-2115:33:53【问题描述】:我一直在为iOS开发一款网络应用游戏,我注意到iPhone与iPad的性能存在显着差异。当玩家开始关卡时,使用带有jQ​... 查看详情

wpf中listbox滚动时的缓动效果

原文:WPF中ListBox滚动时的缓动效果 上周工作中遇到的问题:常规的ListBox在滚动时总是一格格的移动,感觉上很生硬。所以想要实现类似Flash中的那种缓动的效果,使ListBox滚动时可以很流畅。修改模板里的动画效果是一... 查看详情

弹动的公式和检测矩形边界的公式

重要公式: (1)简单缓动dx=targetX-object.x;dy=targetY-object.y;vx=dx*easing;vy=dy*easing;object.x+=vx;object.y+=vy;可精简:vx=(targetX-object.x)*easing;vy=(targetY-object.y)*easing;object.x+=vx;object.y+=vy;再精 查看详情

js实现滚动条滑动到底部

缓动滑动到底部使用requestAnimationFrame缓动滑动到底部setTimeout(scrollToBottom,100);scrollToBottom=()=>{console.log('scrollToBottom');(functionsmoothscroll(){constcurrentScroll=document.documentElement.scrollTop 查看详情

tweenmax学习整理--特有属性

...:TweenMax(target:Object,duration:Number,vars:Object)target:Object--需要缓动的对象duration:Number--缓动持续时间vars:Object--其它参数(特有属性29个,插件17个,公共属性10个,公共方法20个)TweenMax提供的方法大多都会返回一个TweenMaxObject实例 【... 查看详情

关于缓动动画函数的封装(代码片段)

?缓动动画函数 ·之前我在博客上写过匀速的动画函数:https://www.cnblogs.com/Lzxgg-xl/p/10227127.html·与匀速的相比 有相同的地方也有不同的地方我在这里就简单的写一遍   一.首先还是一样,因为它是个函数体我们要传参... 查看详情

如何控制动画速度(requestAnimationFrame)?

】如何控制动画速度(requestAnimationFrame)?【英文标题】:Howtocontrolanimationspeed(requestAnimationFrame)?【发布时间】:2015-03-1423:16:45【问题描述】:我用requestAnimationFrame(animate);函数改变文字颜色:requestAnimationFrame(animate);functionanimate(t... 查看详情

在我的 wpf 过渡动画中闪烁

...定义过渡动画。我正在使用我制作的用于以图形方式指定缓动贝塞尔函数的系统,并且我在一个名为Spline的类中处理所有样条数据。我正在为发送到样条线的静态方法的时间属性设置动画,以计算用于缓动的贝塞尔数据。然后我... 查看详情

requestanimationframe

requestAnimationFrame是实现如“最优帧速率”、“选择绘制下一帧的最佳时机”的功能,它的兼容性写法:varrAF=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||wind 查看详情

requestanimationframe(代码片段)

前面的话  与setTimeout和setInterval不同,requestAnimationFrame不需要设置时间间隔。这有什么好处呢?为什么requestAnimationFrame被称为神器呢?本文将详细介绍HTML5新增的定时器requestAnimationFrame 转载https://www.cnblogs.com/xiaohuochai/p/57771... 查看详情

requestanimationframe兼容性写法

(function()varlastTime=0;varvendors=[‘webkit‘,‘moz‘];for(varx=0;x<vendors.length&&!window.requestAnimationFrame;++x)window.requestAnimationFrame=window[vendors[x]+‘RequestAnimationFrame‘] 查看详情

requestanimationframe(待整理)(代码片段)

介绍:requestAnimationFrame 是js中除了setTimeout和setInterval之外另外一个可以实现动画的API。语法:window.requestAnimationFrame(callback);requestAnimationFrame方法在浏览器下一次重绘之前告诉浏览器调用指定的函数(callback)来更新动画。如果想... 查看详情

requestanimationframe使用(代码片段)

1、概述参考网址:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFramewindow.requestAnimationFrame() 参数是一个回调函数。回调的次数建议每秒60次。这个回调函数只有一个传参,DOMHighResTimeStamp,指示requestAnimationFram 查看详情