2017-01-17 65 views
1

我正在使用HTML5画布编码一个简单的图像处理/绘图工具。它目前正常工作与一个单一的画布层。HTML5帆布层显示器

我想添加一个“预览”的功能,这样,而不是在画布上移动时显示的光标,会显示在该位置点击鼠标的效果。例如,如果您在主画布中加载了图像,并且选定的globalCompositeOperation为饱和,则可以通过将鼠标移至不同部分来预览图像的外观。预览是当前工具的大小,所以如果它是一个圆形工具,半径5,则会看到该圆形覆盖的任何效果。如果你不点击,你只能看到预览。如果单击,则该效果将应用于预览中显示区域的画布。

我在主画布上为mousemove,mouseup和mousedown提供了一个事件监听器。这是我目前的代码(JS和CSS)。有两个画布标签(未在下面的代码中显示)。一个是我的主要画布,上下文ctx,另一个是鼠标预览画布,上下文为mouseCtx。 CS指的是全局“画布状态”对象。

现在,代码正常运行,除了鼠标预览出现在主画布上的任何元素后面(我期望得到较低的z-index)。当我点击放置一个元素时,它会弹出所有内容。但是,如果我给鼠标悬停一个更高的Z-index,主画布上根本没有显示。

我是否错过了一些愚蠢的东西,或者是我实施这种功能方式的策略?非常感谢任何向正确方向提示的提示。

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事件正在被解雇?如果确实没有被触发,请尝试将pointer-events:none;添加到您的canvas.mouseOver css中(z-index更高)。

注意:这可能是一个不好的解决方案,如果您需要支持旧版本的IE

+0

谢谢!哇,出于某种原因,我忘记了我的画布元素被堆叠,而不是在DOM中嵌套,所以没有事件捕获,而是事件“阻塞”,我猜是由于z-index。应该着眼于听众。你的CSS解决方案工作得很好,就像下面的重构一样,只是查询选择器提供了每个画布和监听: let canvases = document.querySelectorAll('canvas'); ((c)=> c.addEventListener('mousemove',mouseTrack)); ((c)=> c.addEventListener('mousedown',mouseTrack)); ((c)=> c.addEventListener('mouseup',mouseTrack)); – thmsdnnr