LoginSignup
14
15

More than 5 years have passed since last update.

canvasにdrawImageした画像にonClick付けたい

Posted at

canvasタグ自体にonClick付けるサンプルは腐るほど出てきます。

そうじゃないんだ。
canvas内にdrawImageしたImageonClick付けたいんだ。

<script>
$(document).ready(function(){
    var context=document.getElementById("canvas").getContext("2d");

    var image=new Image();
    image.id="hoge";
    image.onload=function(){
        context.drawImage(image, 0, 0);
        $("#hoge").click(function(){ alert("hoge"); });
    }
    image.src="gazou.png";
});
</script>
<canvas id="canvas"></canvas>

動きません。
それどころかdocument.getElementById("hoge")の時点でnullです。
なんで?

http://www.inazumatv.com/contents/archives/7281
http://www.inazumatv.com/contents/archives/9620

どうやらdrawImageした時点でcanvas全体が一枚の画像のような扱いになってしまうらしく、特定の画像にリスナーセットといった芸当はできないみたい。
どうにかするためには、canvas上の座標を取得して、そこに重なってるはずの画像を探して、とか自力でやんないといけないらしい。
はー何それふざけてんの?

そんなわけで素のJavaScriptでcanvasを扱うのは無謀なようです。
となればライブラリの出番だ。
同サイトで紹介されてたライブラリのうち、一番上にあったCreateJSを試してみることにする。

<script type="text/javascript" src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="//code.createjs.com/easeljs-0.8.1.min.js"></script>
<script type="text/javascript" src="//code.createjs.com/preloadjs-0.6.1.min.js"></script>
<script>

$(document).ready(function(){
    // 画像を読み込み
    var loader = new createjs.LoadQueue();
    loader.on("complete", completePreload, this);
    loader.loadManifest([{id:"gazou", src:"hoge.png"}]);
});

// 画像読み込み完了
 var completePreload = function(event) {
    // 画像インスタンス
    var image = event.target.getResult("gazou");

    // canvasを取得
    var stage = new createjs.Stage("canvas");

    // 画像をセット
    var bitmap = new createjs.Bitmap(image);
    bitmap.foo = 'bar';
    bitmap.addEventListener("click", function(event){alert(event.target.foo);});
    stage.addChild(bitmap);

    // canvas更新
    stage.update();
}
</script>
<canvas id="canvas"></canvas>

画像にクリックイベントを登録することができました。

createjs.Bitmapは画像を扱うクラスです。
で、一応new createjs.Bitmap("hoge.png");みたいにファイルパスを与えることもできるみたいなのですが、stage.update()したときにまだ画像のロードが終わってなかったら画像が全く表示されない、みたいなことになります。

延々update()を繰り返しておけばそのうち表示されますが、
ここではcreatejs.LoadQueueで先に画像を取得し、読み込みが完了した後にupdate()するようにしました。

createjs.BitmapにはaddEventListenerリスナーを設定できます。
他にも渡したい値なんかを適当に送りつけることもできます。
これで、canvasに描いた画像に個別にクリックリスナーを設定することができるようになりました。
めでたし。
つうかcanvasタグの仕様が悪い。

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15