HTML5キャンバスを使用した簡単な画像操作/描画ユーティリティをコーディングしています。現在、単一のキャンバスレイヤーでうまく動作しています。HTML5キャンバスレイヤーディスプレイ
「プレビュー」の機能を追加しようとしています。キャンバス上を移動するときにカーソルを表示するのではなく、その位置でマウスをクリックしたときの効果が表示されます。たとえば、メインキャンバスにイメージがロードされ、選択されたglobalCompositeOperationが飽和状態になっている場合、マウスを別のパーツに移動することによって、イメージがどのように見えるかをプレビューできます。プレビューは現在のツールのサイズです。したがって、サークルツールであれば半径5で、サークルがカバーしているものにレンダリングされたエフェクトが表示されます。クリックしないと、プレビューのみが表示されます。クリックすると、プレビューに表示された領域のキャンバスにエフェクトが適用されます。
私はメインのキャンバスにmousemove、mouseup、mousedownのイベントリスナーを持っています。ここに私の現在のコード(JSとCSS)があります。 2つのキャンバスタグがあります(下のコードには表示されていません)。一つはコンテキストctxを持つ私のメインキャンバスであり、もう一つはコンテキストmouseCtxを持つマウスプレビューキャンバスです。 CSは、グローバルな「Canvas State」オブジェクトを参照します。
コードは正しく機能しますが、主なキャンバス上の要素の後ろにはマウスプレビューが表示されます(z-インデックスが低いと考えられます)。要素を配置するためにクリックすると、すべてのコンテンツの前にポップアップします。しかし、私がマウスオーバーで高いZ-インデックスを与えると、メインのキャンバスに何も表示されません。
私は何か愚かなことが見つからないのですか、この機能を実装するための私の戦略ですか?正しい方向へのヒントがありがとうございました。
canvas.addEventListener('mousemove', mouseTrack);
canvas.addEventListener('mousedown', mouseTrack);
canvas.addEventListener('mouseup', mouseTrack);
function mouseTrack(e) {
(e.type === 'mousedown') ? CS.isDrawing = true: 0;
(e.type === 'mouseup') ? CS.isDrawing = false: 0;
let mouseParams = {
x: e.layerX,
y: e.layerY,
movArr: [e.movementX, e.movementY],
windowArr: [e.clientX, e.clientY]
};
if (CS.isDrawing === false) {
mouseCtx.clearRect(0, 0, mouseLayer.width, mouseLayer.height);
mouseCtx.drawImage(canvas, 0, 0); //copy the current canvas
console.log((CS.isDrawing === true) + " is drawing");
mouseCtx.strokeStyle = CS.strokeS || randomRGBA();
mouseCtx.fillStyle = CS.fillS || randomRGBA();
mouseCtx.globalAlpha = CS.lOpacity;
mouseCtx.beginPath(); //draw the thing on the current canvas
switch (CS.tool) {
case 'tBrush':
drawBrush(mouseParams, mouseCtx, CS.brush, CS.brushSize);
break;
case 'tLine':
drawLine(mouseParams, mouseCtx);
break;
case 'tCurve':
drawBezier(mouseParams, mouseCtx);
break;
case 'tCircle':
drawCircle(mouseParams, mouseCtx);
break;
case 'tSquare':
drawSquare(mouseParams, mouseCtx);
break;
}
} else {
ctx.drawImage(mouseLayer, 0, 0);
}
}
canvas {
position: absolute;
left: 0px;
top: 0px;
border: 2px solid green;
outline: none;
-webkit-user-select: none;
/* Chrome all/Safari all */
-moz-user-select: none;
/* Firefox all */
-ms-user-select: none;
/* IE 10+ */
user-select: none;
cursor: none;
z-index: 1;
}
canvas.mouseOverlay {
position: absolute;
left: 0px;
top: 0px;
border: 2px solid green;
outline: none;
-webkit-user-select: none;
/* Chrome all/Safari all */
-moz-user-select: none;
/* Firefox all */
-ms-user-select: none;
/* IE 10+ */
user-select: none;
cursor: none;
z-index: 0;
}
の古いバージョンをサポートする必要がある場合、これは悪い解決策になるかもしれません!うわー、何らかの理由で私のキャンバス要素が積み重ねられDOMに入れ子にされていないことを忘れてしまったので、イベントキャプチャはなく、代わりにイベント「ブロッキング」、私はZ-インデックスのために推測します。リスナーを見ることが知られているはずです。あなたのCSSソリューションは、以下のリファクタリングと同様に素晴らしい結果を出しました。単にqueryselectorキャンバスをすべて取り込み、それぞれをリスニングしてください: let canvases = document.querySelectorAll( 'canvas'); canvases.forEach((c)=> c.addEventListener( 'mousemove'、mouseTrack)); canvases.forEach((c)=> c.addEventListener( 'mousedown'、mouseTrack)); canvases.forEach((c)=> c.addEventListener( 'mouseup'、mouseTrack)); – thmsdnnr