2

HTML キャンバス上に任意の形状のオブジェクトを描画する JavaScript アプリケーションを作成しています。ユーザーは、オブジェクトをクリックして選択できる必要があります。

これを O(1) 操作にするために、シャドウ キャンバスを使用しています。つまり、まったく同じサイズの非表示キャンバスです。通常のキャンバスに描画される各オブジェクトもそこに描画されますが、それを表す色を使用しIDます。
したがって、単純なghostContex.getImageData()マウス クリック座標と一緒にすると、そのピクセルの色、つまりIDクリックされたオブジェクトの色がわかります。

オブジェクトの正確な境界線をクリックした場合を除いて、すべて正常に機能しています。

ゴーストキャンバスでアンチエイリアスを使用して描画すると、間違った色になります(その色は、以前に描画されたその下のオブジェクトの正しい色と の混合物です...)IDIDこの間違った色は間違っているIDことを表しているので、まったく別のオブジェクトを選択しています:(

どうすればその問題を解決できますか?

注 #1: ほとんどのアンチエイリアシングを防ぐために、translate(0.5, 0.5) トリックを既に使用してい
ます。衝突検出にはオブジェクトが多すぎます。それが、今 O(1) アプローチが必要な主な理由です...ああ、この方法で、通常のキャンバスに描かれる線よりもはるかに大きな線をゴーストキャンバスに簡単に描くことができ、ピッキングがはるかに簡単になります。
注 3: 関連するブラウザは、Firefox、Chrome、Android 2.3 以降のネイティブおよび iOS ネイティブです。

4

3 に答える 3

1

ここで答えを受け入れることができなかった理由は、非常に簡単で非常に悲しいことです。それは存在しません... :(

アンチエイリアシングを切り替えることはできません。標準にはそのための方法がありません。しかし、標準にはヒット テスト機能 ( http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/#hit-regions ) があり、ここで必要なことを正確に実行します。開発者にとって厄介な詳細を隠す良い方法でも - しかし、現在どのブラウザーにも実装されていません。
そして、実装は不可能になるまで遠く離れているように見えました (たとえば、https://code.google.com/p/chromium/issues/detail?id=328961のコメント #6 を参照)。しかし、どうやら先月の間に勢いが増したようです...

では、その間に何ができるでしょうか?私は何をしましたか?

私のコードでは、シェイプごとにisPointInShape()メソッドを実装できます。そこで、ゴースト キャンバス トリックを使用して形状を取得し、isPointInShape()実際に正しい形状を選択したことを で確認します。これは、アンチエイリアス処理されたピクセルが間違った形状を選択しないようにするのに役立ちます (50% のアンチエイリアス透明度があった形状 #2 の境界をクリックすることを考えてみてください。これは形状 #1 の選択を間違って伝えます...)。

ジェネリックの実装isPointInShape()があなたの形状にとって非常に難しい場合は、私がどこかで読んでいたトリックを試すことができます (私はそれを難し​​く試していないので、テストしていません...):
サイズの追加のゴーストキャンバスを作成しますマウスの位置に正確に配置された 1x1 ピクセル。次に、対象の形状を描画します。RGBA の A が変更されると、この形状はそのピクセルに属します。

于 2014-06-08T20:40:08.330 に答える