17

onclickonmouseoverおよびonmouseoutイベントをキャンバス要素の個々の形状に追加したいと考えています。

私はさまざまな方法で SVG でこれを実行しようとしましたが、すべての主要なブラウザーで機能する単一の方法はありません。

onclickおそらく、キャンバスの形状にイベントを追加する簡単な方法はありますか?

を追加する方法を教えてくださいonclick

これが私のコードです:

canvas
{
  background:gainsboro;
  border:10px ridge green;
}
<canvas id="Canvas1"></canvas>
var c=document.getElementById("Canvas1");

var ctx=c.getContext("2d");
ctx.fillStyle="blue";
ctx.fillRect(10,10,60,60);

var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(80,60,60,60);

// these need an onclick to fire them up. How do I add the onclick
function blue()
{
  alert("hello from blue square")
}

function red()
{
  alert("hello from red square")
}
4

4 に答える 4

1

つまり、形状はオブジェクトとして公開されていないため、キャンバス内の形状にリスナーを追加することはできません。これを実装する最も簡単な方法は、キャンバスで単一のリスナーを使用し、キャンバスに描画されたすべてのオブジェクトをループして正しいオブジェクトを見つけることです。

This answer は、ライブラリ Raphael を使用してこれを実装する方法を説明しています。これにより、他の多くの利点も得られます。

ライブラリを使用したくない場合、これは非常に短い例です。

rects = [{ color : "blue", origin : { x : 10, y : 10 }, size : { width : 60, height: 60}},
         { color : "red", origin : { x : 80, y : 60 }, size : { width : 60, height: 60}}]

function onClick(event) {
    var length = rects.length;

    for (var i = 0; i < length; ++i) {
        var obj = rects[i];
        if (event.x > obj.x && event.x < obj.origin.x + obj.size.width &&
            event.y > obj.y && event.y < obj.origin.y + obj.size.height) {
            console.log("Object clicked: " + obj);
        }
    }

注:多数のオブジェクトがある場合、このアプローチは少し遅くなる可能性があります。これは、2D 空間データ構造を使用することで対処できます。

于 2013-05-18T19:48:28.367 に答える
0

Canvas と SVG の主な違いは、Canvas は、描画された形状に関する情報を、結果として生じるピクセル配列の変更以外には保持しないことです。

したがって、1 つのオプションは、マウス クリック ハンドラーで対応するピクセルの色の値によって形状を認識することです。

function onClick(event) {
  var data = ctx.getImageData(event.x, event.y, 1, 1);
  var red = data[0];
  var green = data[1];
  var blue = data[2];
  var color = red << 16 | green << 8 | blue;

  if (color == 0x0000ff) {
    blue();
  } else if (color == 0x0ff0000) {
    red();
  }
}

このアプローチを使用して同じ色の複数のオブジェクトのクリックを追跡する場合は、各形状の色をわずかに変更して追跡可能にする必要があります。

このアプローチは、別のホストからイメージを追加する場合には機能しません。この場合、同じオリジン ポリシーによって getImageData が妨げられるためです。

于 2013-05-18T19:48:11.937 に答える