2017-01-17 6 views
1

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; 
 
}

答えて

1

何が起こっかもしれないことはあなたのプレビューキャンバスが邪魔になって、メインキャンバスの上に発射されるからイベントを妨げているということです。メインキャンバスのmousedownイベントが発生していることを確認しましたか?実際に解雇されない場合は、canvas.mouseOver css(Z-インデックスが高い)にpointer-events:none;を追加してみてください。

注:ありがとうIE

+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