2

HTML5のキャンバスを使用してスムーズなJavaScriptアニメーションを作成する方法を学ぼうとしています。どういうわけか、アニメーションはスムーズではありませんが、一種の「スパッタ」です。

このjsFiddleで構築したフレームワークを見ることができます。このフレームワークは、現時点ではWebkitプロパティのみを使用しています。

別の開発者は、Ext.jsに基づくWebViewsソースコードを使用して同じ概念を作成することができました。学習目的で、JavaScriptをよりよく理解するためにライブラリを使用することは避けたかったのです。WebViewsの概念は、このjsFiddleで表示できます。これは、はるかにスムーズなアニメーションを示しています。

updaterequestAnimationFrameからの呼び出しを独自のループにプルすることから、コンテキストを描画位置に変換すること、バックバッファーコンテキストに描画してビューポートにコピーすることまで、さまざまなシナリオを読んで試しました。次のコードは、これまでの私の最善の努力を表しています。

外部ライブラリのすべてのオーバーヘッドなしでオブジェクトをスムーズに移動させるためにパフォーマンスを改善する方法についての提案はありますか?

前もって感謝します。

var app;
var now = then = delta = 0;
var viewport = document.createElement( 'canvas' );
var viewportContext = viewport.getContext( '2d' );

function App( )
{
    this.circle = {
        position : viewport.width / 2,
        radius : 10
    };
}

App.prototype.initialize = function( )
{
    app = this;
    document.body.appendChild( viewport );
    viewport.width = 320;
    viewport.height = 200;

    webkitRequestAnimationFrame( app.render, viewport );
};

App.prototype.render = function( )
{
    now = performance.webkitNow( );
    delta = ( now - then ) / 1000.0;
    then = now;

    app.update( delta );
    viewportContext.clearRect( 0, 0, viewport.width, viewport.height );
    app.draw( viewportContext );

    webkitRequestAnimationFrame( app.render, viewport );
};

App.prototype.draw = function( context )
{
    context.fillStyle = "white";
    context.beginPath( );
    context.arc( this.circle.position | 0, viewport.height / 2 | 0, this.circle.radius | 0, 0, Math.PI * 2, true );
    context.closePath( );
    context.fill( );
};

App.prototype.update = function( deltaTime )
{
    this.circle.position += viewport.width / 5 * deltaTime;

    if( this.circle.position >= viewport.width )
    {
        this.circle.position = 0;
    }
};

window.onload = function( )
{
    new App( ).initialize( );
};​
4

2 に答える 2

4

多くの一般的な最適化と、それらがパフォーマンスを向上させる理由と方法についての優れた説明については、このページを参照してください。

また、何らかの理由で、より「中サイズ」のキャンバスでパフォーマンスが向上するようです。これがなぜなのかは完全にはわかりませんが、ブラウザの最適化に関係していると思います。

ここでいくつかの小さな調整を行うことで、パフォーマンスが向上することに注意してください: http://jsfiddle.net/3TAVu/1/

具体的には、ここで fillStyle への余分な割り当てを削除しました。

App.prototype.draw = function( context )
{
    context.beginPath( );
    context.arc( this.circle.position | 0, viewport.height / 2 | 0, this.circle.radius | 0, 0, Math.PI * 2, true );
    context.closePath( );
    context.fill( );
};

また、レンダリング メソッドを変更して、キャンバス全体ではなく関連部分のみをクリアしました。

App.prototype.render = function( )
{
    now = performance.webkitNow( );
    delta = ( now - then ) / 1000.0;
    then = now;

    var cX = app.circle ? (app.circle.position - app.circle.radius) : 0;
    var cY = Math.round(viewport.height/2) - app.circle.radius;
    var w = app.circle ? app.circle.radius * 2 : 0;

    viewportContext.clearRect(cX - 1, cY - 1, w + 2, w + 2);

    app.update( delta );
    app.draw( viewportContext );

    webkitRequestAnimationFrame( app.render, viewport );
};
于 2012-09-25T20:09:54.157 に答える
3

ねえ、よりスムーズなアニメーションを扱う requestAnimationFrame について、この非常によく説明されたページを見つけました。あなたまたはこの質問の将来の閲覧者がこれを役に立つと思うかもしれません..

于 2013-06-06T15:30:58.917 に答える