2010-12-27 12 views
2

フルスクリーンのキャンバスに3枚の画像が描画されています。ウィンドウのサイズを変更すると、これらの画像の位置が変わります。しかし、それは非常にglitchy、Firefoxでもっとそうであるように見えます。HTMLキャンバスダブルバッファリングのフレームレート問題

私はこのダブルバッファリングがこの問題を解決するはずだと読んできましたが、次の位置が不明なときにバッファを二重にする方法は不思議です。つまり、私は将来どのようなものをバッファリングすべきかを判断することができないので、これはどのように可能でしょうか?

ここでは実行可能なソースがありますが、私は完全に理解できません。

Does HTML5/Canvas Support Double Buffering?

これまでのところ、私が持っている、

$canvas = $('#myclouds')[0]; 
    $canvas_buffer = $('canvas')[0].insertAfter($canvas).css('visibility', 'hidden'); 
    context = $canvas.getContext('2d'); 
    context_buffer = $canvas_buffer.getContext('2d'); 
    clouds_arr = [$canvas, $canvas_buffer]; 

$(window).resize(function() { 
    drawCanvas(); 
}; 

function initCanvas() { 

    // Sources for cloud images 
    var cloud1 = '/js/application/home/images/cloud1.png', 
     cloud2 = '/js/application/home/images/cloud2.png', 
     cloud3 = '/js/application/home/images/cloud3.png'; 

    // add clouds to be drawn 
    // parameters are as follows: 
    // image source, x, y, ratio, adjustment) 
    addCloud(cloud1, null, 125, .03); 
    addCloud(cloud2, null, 75, .15); 
    addCloud(cloud3, null, 50, .55); 
    addCloud(cloud1, null, 125, .97, 300); 
    addCloud(cloud2, null, 70, .85, 300); 
    addCloud(cloud3, null, 45, .5, 300); 

    // Draw the canvas 
    drawCanvas(); 
} 

function drawCanvas() { 
    // Reset 
    $canvas.attr('height', $window.height()).attr('width', $window.width()); 

    // draw the clouds 
    var l = clouds.length; 
    for (var i = 0; i < l; i++) { 
     clouds[i].x = ($window.width() * clouds[i].ratio) - clouds[i].offset; 
     drawimage(context, clouds[i]); 
    } 
} 

function Cloud() { 
    this.x = 0; 
    this.y = 0; 
} 

function addCloud(path, x, y, ratio, offset) { 
    var c = new Cloud; 
    c.x = x; 
    c.y = y; 
    c.path = path; 
    c.ratio = ratio || 0; 
    c.offset = offset || 0; 
    clouds.push(c); 
} 

function drawimage(ctx, image) { 
    var clouds_obj = new Image(); 
    clouds_obj.src = image.path; 

    clouds_obj.onload = function() { 
     ctx.drawImage(clouds_obj, image.x, image.y); 
    }; 
} 

答えて

8

私は多分あなたはダブルバッファリングとは何か誤解されていると思います。ディスプレイ上でのグラフィックスのスムーズなリアルタイムレンダリングのテクニックです。

概念には2つのバッファがあります。一度に1つしか表示されません。フレームを構成する要素を描画する場合は、それらを不可視バッファに描画します。あなたの場合は雲。次に、隠されたものを見えるようにバッファを反転し、目に見えるものを隠します。次のフレームで、今新たに隠されたバッファに描画します。その後、描画の最後に戻ります。

これは、フレームが完了する前に要素の部分的なレンダリングが表示されないようにすることです。ゲームシステムでは、ディスプレイの垂直リフレッシュと同期して、滑らかになり、引き裂きなどのアーチファクトを止めることができます。

上記のコードを見ると、2つのキャンバス要素が作成されているように見えますが、最初のContextオブジェクトのみを使用しているようです。私は反転が起こっていないのでこれが不完全であると仮定します。

また、ウィンドウのサイズ変更イベントが激しいレンダリングを引き起こす可能性があるドラッグ時に連続的に発生する可能性があります。私は通常、実際に再レンダリングするためにresizeイベントにタイマーを作成します。このようにして、ユーザーが数ミリ秒間リサイズを停止すると、再レンダリングが行われます。

また、描画ルーチンは、毎回新しいImageオブジェクトを作成する必要がありません。 1つのイメージオブジェクトを使用してキャンバスに複数回レンダリングすることができます。これによりレンダリングが大幅にスピードアップします。

これが役に立ちます。