2012-02-14 9 views
2

キャンバスにフリーハンドのストロークを以下のようなコードでペイントします。私はどのくらいのキャンバスがストロークで覆われているか確認する必要があります。それを確認する良い方法は何ですか?私が考えることができる唯一のことは、マウスアップイベントで特定の色を持つピクセルの数を数えることです。しかし、それは遅いために不自由です...塗りつぶし領域の面積を計算する方法は?

助けてください?

$(document).ready(function(){ 
    var draw = false; 
    var x_prev = null, y_prev = null; 
    var canvas = document.getElementById("canvas"); 
    var context = canvas.getContext("2d"); 
    canvas.mousedown(function(e){ 
     draw = true; 
     x_prev = e.pageX - this.offsetLeft; 
     y_prev = e.pageY - this.offsetTop; 
    }); 
    window.mouseup(function(){draw=false}); 
    canvas.mousemove(function(e){ 
     if(draw){ 
      context.beginPath(); 
      context.moveTo(e.pageX - this.offsetLeft, e.pageY - this.offsetTop); 
      context.lineTo(x_prev, y_prev); 
      context.stroke(); 
      context.closePath(); 
      x_prev = e.pageX - this.offsetLeft; 
      y_prev = e.pageY - this.offsetTop; 
     } 
    }); 
+0

どのくらい太い線ですか?また、アンチエイリアスを考慮していますか? – Blender

+0

は任意に厚い。厚さはハードコードされています。私はアンチエイリアスについてあまり気にしない、私は良い近似を与える何かが必要です。これはゲームのためであり、私は高精度を必要としません。 – akonsu

+0

ラインオーバーラップはどうやって処理しますか?あなたは 'area + = thickness * sqrt((e.pageX - this.offsetLeft - x_prev)^ 2 +(e.pageY - this.offsetTop - y_prev)^ 2);'を使うことができますが、交差する線。 – Blender

答えて

1

コンピュータが速いをしている総正方形の数でカバー正方形を分割することによりパーセントでエリアを描画されることができます。描画するときに、各フレームの特定のアルファのピクセル数を再カウントするのはかなり速いです。ここではそれを自分でテストします。http://jsfiddle.net/ZC8cB/3/

関連するコード:

var w = canvas.attr('width'), 
    h = canvas.attr('height'), 
    area = w * h; 

function updateArea() { 
    var data = context.getImageData(0, 0, w, h).data; 
    for (var ct=0, i=3, len=data.length; i<len; i+=4) if (data[i]>50) ct++; 
    $fill.html(ct); 
    $pct.html((100 * ct/area).toFixed(2)); 
} 

これは本当に遅すぎる場合は、地域になど、他のすべてののMouseMove、すべての第三のMouseMoveを、更新したり、インターバルタイマーにすることを選択することができます。例えば、ここでの唯一の10回に1回のMouseMoveを更新し、非常-やや修正したバージョンです:

そしてカウントの単一のフレームが遅すぎる場合は、その後、遅いコンピュータや巨大なキャンバスまたは両方—を持っているので—することができますhttp://jsfiddle.net/ZC8cB/4/ 1つのフレームにImageDataをフェッチし、各更新フレームはピクセルの特定の部分をカウントします。

+0

「マウスアップ」イベントでキャンバスをスキャンすることを除いて、私は同じことをしました。 – akonsu

1

面積を線幅の四角形に数え、描画中に遭遇する一意の四角形の数を数えます。

var thickness = 4 
var height = .. 
var width = .. 
var drawn = [] 
var covered = 0; 

canvas.mousemove(function(e) { 

    var x = e.pageX - this.ofsetLeft; 
    var y = e.pageY - this.offsetTop; 
    x = parseInt(x/width) * (width/thickness) 
    y = parseInt(y/height) * (height/thickness) 
    id = x + y * parseInt(thickness/width) 
    if (!drawn[ id ]) { 
     drawn[ id ] = 1; 
     covered++; 
    } 

} 

あなたは

var a = covered/((width/thickness) * (height/thickness)) 
+0

あなたの答えをありがとう、このコードを説明していただけますか? – akonsu

+0

非常にシンプルで、描画中にマウスが移動した数(四角形のサイズを定義する)を追跡するグリッドを維持します。覆われたカウンターは塗りつぶされた四角の数を数えます。ありがとう。 –

+0

マウスがあまりにも速く動いて、イベントハンドラが軌道のすべてのポイントに対して呼び出されない場合(つまり、なぜ私は自分のコードでmoveTo()とlineTo()を使用するのかを除いて、私にとってはうまくいく可能性があります)。 – akonsu

関連する問題