私は通常、グーグルで答えを見つけるので、これは私の最初のスタックオーバーフローの質問です。
キャンバス要素を大量に操作するプロジェクトに取り組んでいます。これを行うために、jQuery と jCanvas をインポートして使用しました。また、ECMAScript 6 でコードを書いています。より簡単なロギング方法のために、ログレベルを使用しています (したがって、「console.log」の代わりに「log.debug」や「log.info」など)。
現在、私の問題は、各キャンバスに関するデータを保存するために使用するオブジェクトと奇妙なやり取りをするイベントハンドラーにあります。基本的に、私の mousedown および mousemove ハンドラーでは、getCanvasData 関数を使用して特定のキャンバスのデータ オブジェクトを取得しています。これは明らかに正常に取得されていますが、「ドラッグされた」パラメーターにアクセスすると、常に null になります。コードの他の部分では、その値をオブジェクトに正常に変更しますが、イベント ハンドラーがアクセスするたびに、何があっても null のままです。プロパティの変更時に状態を出力する getter と setter を作成して、本当に null かどうかをテストしました (最後にコードのスニペットを提供しました。これは、getCanvasData 関数の「データ」割り当ての代わりです)。
完全なコードを現在の形式で見たい場合は、現在ホストしているプロジェクトを表示できます。これはライブ バージョンです。つまり、私の作業環境と同期しています。私が自宅で何かを変更すると、Web サイトが更新されます (したがって、未来から来た場合は、おそらくダウンしているか、完全に異なっている可能性があります)。
Web サイトでは、移動ハンドラーは、(入力または出力の 1 つをクリックして) ワイヤ/コネクタをスポーンするときに、ワイヤ/コネクタの一方の端を移動する責任があると想定されています。ハンドラーは「ドラッグ」を取得できないため、ワイヤーがマウスに追従することはありません。ただし、別の入力/出力をクリックすると (入力は出力にのみ接続され、その逆も同様であることに注意してください)、それらの間のワイヤが接続されます。そのアクションは、「ドラッグ」プロパティにアクセスすることによって実行されます (「ドラッグ」はワイヤ自体への参照) とそれに対するアクションの実行。ワイヤーを接続できるため、「ドラッグ」はハンドラーの外部では正常に参照されますが、ハンドラーの内部では参照されません。
getCanvasData() 関数:
var canvasData = []; // (among other declarations)
function getCanvasData(canvas) {
var data, i, tmp;
// Retrieve the stored data
for (i = 0; i < canvasData.length; i++) {
tmp = canvasData[i];
if (canvas === tmp.canvas) {
// We got the data for our canvas!
data = tmp;
// We no longer need to go through the rest of the list, let's break out of the loop
break;
}
}
// Check if we got anything back
if (!data) {
// No data for this canvas is stored yet. We need to initialize it!
log.info("New canvas data set is being created. Index: " + canvasData.length);
data = {
canvas: canvas, // The canvas this data belongs to
gates: [], // An array of all the logic gates on the canvas
wires: [], // An array of all the wires on the canvas
spawners: [], // An array of all the spawners on the canvas
dragged: null, // Currently dragged wire which should follow our mouse
gateWidth: GATE_WIDTH, // Width of all logic gates on this canvas
gateHeight: GATE_HEIGHT // Height of all logic gates on this canvas
};
// Store the data in our storage.
canvasData.push(data);
}
return data;
}
コードの一部では、特定のクラスのすべてのキャンバスにさまざまなハンドラーを割り当てています。
var canvasList = $('.logicExercise'), canvas;
/* some code */
// Initialize each canvas
canvasList.each(function (i, obj) {
canvas = $(this);
// Initialize the data stored for the canvas
getCanvasData(canvas);
// Draw the UI for the canvas
drawUI(canvas);
// Assign mouse handlers (for spawning new wires)
canvas.mousemove(function(event) {
mouseMoveHandler(event, canvas);
});
canvas.mousedown(function(event) {
mouseDownHandler(event, canvas);
});
// Prevent right-click from firing up the context menu when over the canvas
canvas.bind('contextmenu', function(e){
e.preventDefault();
return false;
});
});
mousedown および mousemove ハンドラー:
function mouseMoveHandler(event, canvas) {
var x = event.pageX - canvas.offset().left,
y = event.pageY - canvas.offset().top,
data = getCanvasData(canvas);
if (data.dragged) { // <--- ALWAYS NULL, AND THEREFORE FAILS
if (data.dragged.inputs[0].type) {
data.dragged.outputs[0].x = x;
data.dragged.outputs[0].y = y;
data.dragged.updateCoords();
} else {
data.dragged.inputs[0].x = x;
data.dragged.inputs[0].y = y;
data.dragged.updateCoords();
}
}
}
function mouseDownHandler(event, canvas) {
var data = getCanvasData(canvas);
if (event.which === 3) {
// Right click detected!
if (data.dragged) { // <--- ALWAYS NULL, AND THEREFORE FAILS
// We are dragging something! Right click means we need to remove it.
data.dragged.remove();
data.dragged = null;
}
}
}
「ドラッグ」の状態が変化するのを確認するために使用したコードのスニペット:
data = {
canvas: canvas, // The canvas this data belongs to
gates: [], // An array of all the logic gates on the canvas
wires: [], // An array of all the wires on the canvas
spawners: [], // An array of all the spawners on the canvas
gateWidth: GATE_WIDTH, // Width of all logic gates on this canvas
gateHeight: GATE_HEIGHT,// Height of all logic gates on this canvas
_dragged: null,
set dragged(obj) {
log.info("'dragged' is changing to '" + obj + "'.");
this._dragged = obj;
},
get dragged() {
log.info("'dragged' is being retrieved when it's '" + this._dragged + "'.");
return this._dragged;
}
};
上記のコードが有効な場合、「ドラッグ」が「オブジェクトオブジェクト」に変更されたことを通知する出力が表示されますが、(mousemove イベントをトリガーするために) マウスを動かすと、「null」であることを示す出力が表示されます (そうではありません)。未定義でも)。私のプロジェクトの他の部分がそれを使用すると、それが正常に使用され、実際にオブジェクトが取得されます。