私は経験豊富なJavaプログラマーですが、約10年ぶりにJavaScript/HTML5の一部を見ています。私はこれまでで最も単純なものであるべきことに完全に困惑しています。
例として、何かを描き、イベントハンドラーを追加したかっただけです。私は愚かなことをしていると確信していますが、私はすべてを検索しましたが、提案されたものは何もありません(例えば、この質問に対する答え: JavaScriptで入力にonclickプロパティを追加 )。 Firefox 10.0.1を使用しています。私のコードが続きます。いくつかのコメント行が表示され、各行の最後には何が起こるか(何が起こらないか)の説明があります。
ここで正しい構文は何ですか?私はおかしくなりそうだ!
<html>
<body>
<canvas id="myCanvas" width="300" height="150"/>
<script language="JavaScript">
var elem = document.getElementById('myCanvas');
// elem.onClick = alert("hello world"); - displays alert without clicking
// elem.onClick = alert('hello world'); - displays alert without clicking
// elem.onClick = "alert('hello world!')"; - does nothing, even with clicking
// elem.onClick = function() { alert('hello world!'); }; - does nothing
// elem.onClick = function() { alert("hello world!"); }; - does nothing
var context = elem.getContext('2d');
context.fillStyle = '#05EFFF';
context.fillRect(0, 0, 150, 100);
</script>
</body>
canvas
要素に描画するときは、単にビットマップを イミディエートモード で描画します。
描画されるelements(形状、線、画像)は、使用するピクセルと色以外の表現を持ちません。
したがって、canvas
element(shape)でclickイベントを取得するには、canvas
HTML要素でクリックイベントをキャプチャし、数学を使用する必要があります要素の幅/高さとx/yオフセットを保存している場合、クリックされた要素を特定します。
click
イベントをcanvas
要素に追加するには、...を使用します.
canvas.addEventListener('click', function() { }, false);
どのelementがクリックされたかを判断するには...
var elem = document.getElementById('myCanvas'),
elemLeft = elem.offsetLeft,
elemTop = elem.offsetTop,
context = elem.getContext('2d'),
elements = [];
// Add event listener for `click` events.
elem.addEventListener('click', function(event) {
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
// Collision detection between clicked offset and element.
elements.forEach(function(element) {
if (y > element.top && y < element.top + element.height
&& x > element.left && x < element.left + element.width) {
alert('clicked an element');
}
});
}, false);
// Add element.
elements.Push({
colour: '#05EFFF',
width: 150,
height: 100,
top: 20,
left: 15
});
// Render elements.
elements.forEach(function(element) {
context.fillStyle = element.colour;
context.fillRect(element.left, element.top, element.width, element.height);
});
jsFiddle 。
このコードは、click
イベントをcanvas
要素にアタッチし、1つの図形(コードではelement
と呼ばれます)をelements
配列にプッシュします。ここに好きなだけ追加できます。
オブジェクトの配列を作成する目的は、後でプロパティをクエリできるようにすることです。すべての要素が配列にプッシュされた後、ループしてプロパティに基づいて各要素をレンダリングします。
click
イベントがトリガーされると、コードは要素をループし、elements
配列の要素のいずれかをクリックしたかどうかを判断します。その場合、alert()
を起動します。これは、配列項目を削除するなどの簡単な変更が可能です。この場合、canvas
を更新するために別のrender関数が必要になります。
完全を期すため、あなたの試みがうまくいかなかった理由...
elem.onClick = alert("hello world"); // displays alert without clicking
これは、alert()
の戻り値をonClick
のelem
プロパティに割り当てています。すぐにalert()
を呼び出しています。
elem.onClick = alert('hello world'); // displays alert without clicking
JavaScriptでは、'
と"
は意味的に同一であり、レクサーはおそらく引用符に['"]
を使用します。
elem.onClick = "alert('hello world!')"; // does nothing, even with clicking
onClick
のelem
プロパティに文字列を割り当てています。
elem.onClick = function() { alert('hello world!'); }; // does nothing
JavaScriptは大文字と小文字を区別します。 onclick
プロパティは、イベントハンドラーをアタッチする古風な方法です。プロパティに関連付けられるイベントは1つのみであり、HTMLのシリアル化時にイベントが失われる可能性があります。
elem.onClick = function() { alert("hello world!"); }; // does nothing
繰り返しますが、' === "
。
次の記事をお勧めします: HTML5キャンバスのヒット領域検出と、キャンバスシェイプのクリックイベントをリッスンする方法 これはさまざまな状況を通過します。
ただし、addHitRegion
APIはカバーしていません。これは最良の方法でなければなりません(数学関数や比較を使用するとエラーが発生しやすくなります)。このアプローチは詳細です developer.mozilla
おそらく答えに非常に遅れましたが、私は70-480
試験の準備中にこれを読んだところ、これが機能することがわかりました-
var elem = document.getElementById('myCanvas');
elem.onclick = function() { alert("hello world"); }
イベントがonclick
ではなくonClick
であることに注意してください。
JS Bin 例。
キャンバスの最上部にdiv
などのDOM要素を配置して、キャンバス要素を表し、同じように配置することもできます。
これで、これらのdivにイベントリスナーをアタッチして、必要なアクションを実行できます。
アレックスの答えの代替として:
Canvas描画の代わりにSVG描画を使用できます。そこで、描画されたDOMオブジェクトにイベントを直接追加できます。
例を参照してください:
やや静的なキャンバスでの別の安価な代替手段として、usemap定義でimg要素をオーバーレイすることは迅速で汚れています。円グラフのようなポリゴンベースのキャンバス要素で特にうまく機能します。
Alex Answer はかなりきれいですが、コンテキストの回転を使用する場合、x、y座標をトレースするのが難しい場合があるため、 Demo を追跡する方法を示しました。
基本的に、私はこの関数を使用して、オブジェクトを描画する前にその天使に移動した角度と距離を与えます。
function rotCor(angle, length){
var cos = Math.cos(angle);
var sin = Math.sin(angle);
var newx = length*cos;
var newy = length*sin;
return {
x : newx,
y : newy
};
}