HTML画布使用透明png底基进行绘图和擦除 [英] HTML canvas drawing and erasing with transparent png base

查看:34
本文介绍了HTML画布使用透明png底基进行绘图和擦除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个jsfiddle https://jsfiddle.net/g10qgefy/46/

Here is a jsfiddle https://jsfiddle.net/g10qgefy/46/

if (drawingMode === 'brush') {
      ctx.globalCompositeOperation = "source-atop";

    } else { //erase
      ctx.globalCompositeOperation = "destination-out";
      ctx.strokeStyle = 'rgba(1,0,0,0)';
    }

我正在尝试创建此简单的绘图功能.我有一个canvas元素,我使用 drawImage()向其绘制图像.然后,您可以使用画布方法 globalCompositeOperation ="source-atop" 涂刷非透明像素.

I am trying to create this simple drawing feature. I have a canvas element, I draw an image to it using drawImage(). Then, you can brush on the non-transparent pixels using canvas method globalCompositeOperation = "source-atop".

这一切都能满足我的要求.但是我还需要能够擦除一些绘制的线条而不会影响透明图像.因此,我只想选择擦除"按钮并开始擦除我绘制的黑线.

That all does what I want. But I also need to be able to erase some of the drawn lines without affecting the transparent image. So I just want to select the erase button and start erasing away the black lines I have drawn.

我一直在使用globalCompositionOperation并更改画布渲染|MDN ,但这些大多只是删除所有内容.

I have been playing with globalCompositionOperation and changing the values from Canvas Rendering | MDN but these mostly just delete everything.

我确定有解决方案-很想听听您的想法!

I'm sure there is a solution - would love to hear your thoughts!

推荐答案

保留两层:用户在其中进行绘制的图层,以及在进行渲染的图层.

Keep two layers: the one the user is drawing to, and the rendering one.

在第一层(屏幕外画布)上绘制用户的图形,然后在第二层画布(渲染一个)的第二层画布上使用该层顶部的png图像进行合成.

Draw the user's drawings on the first layer (offscreen canvas) and then do your compositing with the png image on top of this layer on a second canvas, the rendering one.

这样,您可以安全地执行擦除调用,而不必关心png层.

This way you can perform your erase calls safely, without having to care about the png layer.

let renderingElement = document.getElementById("myCanvas");
// create an offscreen canvas only for the drawings
let drawingElement = renderingElement.cloneNode();
let drawingCtx = drawingElement.getContext('2d');
let renderingCtx = renderingElement.getContext('2d');


let img = new Image();
let brushSize = 25;
let brushColor = "#000000"
let drawingMode = 'brush';

let lastX;
let lastY;
let moving = false;

img.src = 'https://i.pinimg.com/originals/49/af/b1/49afb1d21ae594cb7ac3534a15383711.png';
img.onload = () => {
  renderingCtx.drawImage(img, 0, 0);
}

let eraseButton = document.getElementById('erase');
let brushButton = document.getElementById('brush');
let exportButton = document.getElementById('export');

eraseButton.addEventListener('click', () => {
  drawingMode = 'erase';
})

brushButton.addEventListener('click', () => {
  drawingMode = 'brush';
})

renderingElement.addEventListener('mousedown', (ev) => {
  moving = true;
  lastX = ev.pageX - renderingElement.offsetLeft;
  lastY = ev.pageY - renderingElement.offsetTop;
})

renderingElement.addEventListener('mouseup', (ev) => {
  moving = false;
  lastX = ev.pageX - renderingElement.offsetLeft;
  lastY = ev.pageY - renderingElement.offsetTop;
})

renderingElement.addEventListener('mousemove', (ev) => {
  if (moving) {
    if (drawingMode === 'brush') {
      drawingCtx.globalCompositeOperation = "source-over";
    } else {
      drawingCtx.globalCompositeOperation = "destination-out";
    }
    let currentX = ev.pageX - renderingElement.offsetLeft;
    let currentY = ev.pageY - renderingElement.offsetTop;

    drawingCtx.beginPath();
    drawingCtx.lineJoin = "round";
    drawingCtx.moveTo(lastX, lastY);
    drawingCtx.lineTo(currentX, currentY);
    drawingCtx.closePath();
    drawingCtx.strokeStyle = brushColor;
    drawingCtx.lineWidth = brushSize;
    drawingCtx.stroke();

    lastX = currentX;
    lastY = currentY;

    // draw to visible canvas
    renderingCtx.clearRect(0, 0, renderingElement.width, renderingElement.height);
    renderingCtx.drawImage(img, 0, 0);
    renderingCtx.globalCompositeOperation = 'source-atop';
    renderingCtx.drawImage(drawingElement, 0, 0);
    
    // reset
    renderingCtx.globalCompositeOperation = 'source-over';
  }

});

canvas {
  border: 5px solid red;
}

<button id="brush">brush</button>
<button id="erase">erase</button>
<canvas id="myCanvas" width="500" height="500"></canvas>

这篇关于HTML画布使用透明png底基进行绘图和擦除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆