より良いrequestAnimationFrameの/ cancelAnimationFrame--パフォーマンスJSアニメーションの実装

JSアニメーションを実現するために、我々は通常のsetTimeoutかのsetIntervalは、これら2つの機能、CSS3アニメーション、それの後に、私たちはCSS3アニメーションを実現するために使用することができ、ヘルプ、およびパフォーマンスと流暢さも大幅に改善されました。しかし、このようなすべてのプロパティをアニメーションに参加することができないとして、まだ多くの制限のCSS3アニメーションがあり、アニメーション緩和効果は完全にアニメーション処理などを制御するためには小さすぎます。文字の数の両方にいくつかの近代的なブラウザでは、CSS3でなく、いくつかの最適化を行って、まだすることができますがだから、時には我々は、アニメーションを実現するためのsetTimeoutかのsetInterval方法を使用する必要がありますが、のsetTimeoutと、重大なパフォーマンス上の問題を抱えているのsetIntervalアニメーションパーパフォーマンス。今回は、requestAnimationFrameのために実行する時間です。

requestAnimationFrameのは、高性能フレームアニメーションとデザインのために設計されたAPIであるモバイルデバイス上などIE10 +、Firefoxの、クロム、サファリ、オペラ、を含む複数のブラウザでサポートされている、ios6以降とIEモバイルまた、10以上のrequestAnimationFrameのをサポートしている、唯一残念にアンドロイドのネイティブブラウザはrequestAnimationFrameのをサポートしていませんが、requestAnimationFrameのためのサポートは16+もrequestAnimationFrameのをサポートし、一般的な傾向もクロムのAndroidのバージョン必要があります。

ここに画像を挿入説明


setTimeoutよりもrequestAnimationFrameの、のsetInterval 2つの主な利点があります。

図1は、各フレーム内のすべてのDOM操作が一緒にrequestAnimationFrameのか、または再描画完全な逆流及び逆流または再描画時間間隔で直ちに、一般的には、周波数をブラウザのリフレッシュレートを次毎秒60のフレーム。

図2は、要素隠さまたは不可視、requestAnimationFrameの少ないCPU、GPUとメモリ使用量のどのコースの手段、再描画または逆流することはないであろう。


注意:

像setTimeout、setInterval一样,requestAnimationFrame是一个全局函数。调用requestAnimationFrame后,它会要求浏览器根据自己的频率进行一次重绘,它接收一个回调函数作为参数,在即将开始的浏览器重绘时,会调用这个函数,并会给这个函数传入调用回调函数时的时间作为参数。由于requestAnimationFrame的功效只是一次性的,所以若想达到动画效果,则必须连续不断的调用requestAnimationFrame,就像我们使用setTimeout来实现动画所做的那样。requestAnimationFrame函数会返回一个资源标识符,可以把它作为参数传入cancelAnimationFrame函数来取消requestAnimationFrame的回调。怎么样,是不是也跟setTimeout的clearTimeout很相似啊。

所以,可以这么说,requestAnimationFrame就是一个性能优化版、专为动画量身打造的setTimeout,不同的是requestAnimationFrame不是自己指定回调函数运行的时间,而是跟着浏览器内建的刷新频率来执行回调,这当然就能达到浏览器所能实现动画的最佳效果了。

目前,各个支持requestAnimationFrame的浏览器有些还是自己的私有实现,所以必须加前缀,对于不支持requestAnimationFrame的浏览器,我们只能使用setTimeout,因为两者的使用方式几近相同,所以这两者的兼容并不难。对于支持requestAnimationFrame的浏览器,我们使用requestAnimationFrame,而不支持的我们优雅降级使用传统的setTimeout。把它们封装一下,就能得到一个统一兼容各大浏览器的API了。

(function() {
    var lastTime = 0;
    var vendors = ['webkit', 'moz', 'ms', 'o'];
    for( var x=0 ; x<vendors.length ; ++x){
        if ( window.requestAnimationFrame && window.cancelAnimationFrame ) {
            break;
        }
        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); 
        };
    }
}());

//简化版本

window.requestAnimationFrame=window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    function( callback ){
        //为了使setTimteout的尽可能的接近每秒60帧的效果
        window.setTimeout(callback,1000/60);
    }
 
window.cancelAnimationFrame=window.cancelAnimationFrame ||
    Window.webkitCancelAnimationFrame ||
    window.mozCancelAnimationFrame ||
    window.msCancelAnimationFrame ||
    window.oCancelAnimationFrame ||
    function( id ){
        //为了使setTimteout的尽可能的接近每秒60帧的效果
        window.clearTimeout( id );
    }

以下は、アニメーションrequestAnimationFrameの使用、次のコードは、300ピクセルの右にアニメーションが動くのdivのIDをデモする方法を説明するために簡単な例を与えます
<div id="demo" style="position:absolute; width:100px; height:100px; background:#ccc; left:0; top:0;"></div>
<script>
    var demo = document.getElementById('demo');
    function rander(){
        demo.style.left = parseInt(demo.style.left) + 1 + 'px'; //每一帧向右移动1px
    }
    requestAnimationFrame(function(){
        rander();
        //当超过300px后才停止
        if(parseInt(demo.style.left)<=300){         
            requestAnimationFrame(arguments.callee);
        }
    });
</script>

おすすめ

転載: www.cnblogs.com/both-eyes/p/12109522.html