canvas
タグ自体にonClick
付けるサンプルは腐るほど出てきます。
そうじゃないんだ。
canvas
内にdrawImage
したImage
にonClick
付けたいんだ。
<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タグの仕様が悪い。