HTML画布使用透明png底基进行绘图和擦除 [英] HTML canvas drawing and erasing with transparent png base
问题描述
这是一个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屋!