gpt4 book ai didi

javascript - HTML 5 canvas globalCompositeOperation(橡皮擦)问题

转载 作者:搜寻专家 更新时间:2023-10-31 23:28:19 27 4
gpt4 key购买 nike

好的,几个月前我构建了一个绘图系统,基本上可以让用户在 Canvas 上绘图。我包含的一些功能包括使用用户定义的颜色和笔触大小、橡皮擦和撤消/重做进行绘图。

我刚刚检查了一些项目以查看它们仍然如何运作,并注意到一个新问题,该问题在我构建和发布此草图工具时并未发生。

我的问题是,在用户画完所有内容然后使用橡皮擦删除草图的一部分后,整个 Canvas 在鼠标按下时被清除。这在以前没有发生过。橡皮擦应该跟随光标并清除鼠标所采用的笔划路径。所以我想知道 Canvas 如何读取全局复合操作或其他内容是否有任何更改。我搜索了堆栈和谷歌,但找不到任何明确的答案,所以我希望其他人可能遇到过这个问题。

我还注意到,当我在橡皮擦清除 Canvas 后切换回钢笔工具时,不再绘制任何东西。即使我撤消,它也会显示上一个被删除的笔划,但绘图工具不再执行任何操作。

如果我尝试删除,所有内容都会被清除,但如果我撤消,它将恢复尝试删除之前存储的内容。

这是我用来绘图和删除的脚本。对这个问题的任何帮助将不胜感激。谢谢。

我还想指出,这个问题出现在最新版本的 chrome、firefox 和 IE 11 中。

编辑:我忘了说。发现这个问题后,我尝试将 globalCompositeOperation 切换为“destination-out”,但它并没有像我希望的那样留下坚实的笔触。它只是制作了一系列点(正在删除),但并不像应有的那样光滑/干净。

编辑: fiddle 链接 http://jsfiddle.net/p889d/

function Draw(x, y, isDown) {
if (isDown) {
ctx.beginPath();
ctx.globalCompositeOperation="source-over";
ctx.strokeStyle = gd.color;
ctx.lineWidth = gd.toolSize;
ctx.lineJoin = "round";
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.closePath();
ctx.stroke();
}
lastX = x;
lastY = y;
}

function Erase(x, y, isDown) {
if (isDown) {
ctx.beginPath();
ctx.globalCompositeOperation="copy";
ctx.strokeStyle = "rgba(0,0,0,0)";
ctx.lineWidth = gd.toolSize;
ctx.lineJoin = "round";
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.closePath();
ctx.stroke();
}
lastX = x;
lastY = y;
}

$canvas.bind("mousedown touchstart", function (e) {
mousePressed = true;

lastX = e.pageX - $(this).offset().left;
lastY = e.pageY - $(this).offset().top;

if (gd.pushIt == true) {
if (gd.tool == 'marker') {
Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
}
if (gd.tool == 'eraser') {
Erase(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
}
}
if (gd.pushIt == false) {
invisibleCanvas(e, $(this));
}
if ($(".multi-item-menu").is(":visible")) {
$(".multi-item-menu").fadeOut(400);
}
if ($("#draw-colors-pallet").is(":visible")) {
$("#draw-colors-pallet").fadeOut(400);
}

// for text area tool
if (gd.tool == 'text') {
mouse.x = typeof e.offsetX !== 'undefined' ? e.offsetX : e.layerX;
mouse.y = typeof e.offsetY !== 'undefined' ? e.offsetY : e.layerY;

start_mouse.x = mouse.x;
start_mouse.y = mouse.y;
}
});

$canvas.bind("mousemove touchmove", function (e) {
if (mousePressed == true && gd.pushIt == true) {
if (gd.tool == 'marker') {
Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
}
if (gd.tool == 'eraser') {
Erase(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
}

if (gd.tool == 'text') {
mouse.x = typeof e.offsetX !== 'undefined' ? e.offsetX : e.layerX;
mouse.y = typeof e.offsetY !== 'undefined' ? e.offsetY : e.layerY;

adjustTextArea();
}
}
if (gd.pushIt == false) {
var x = e.pageX,
y = e.pageY;

mousePressed = false;

if (x !== lastX || y !== lastY) {
invisibleCanvas(e, $(this));
}

lastX = x;
lastY = y;
}
});

最佳答案

要让您的橡皮擦再次工作,您需要在删除函数中更改这些行:

ctx.globalCompositeOperation="copy";
ctx.strokeStyle = "rgba(0,0,0,0)";

对这些:

ctx.globalCompositeOperation="destination-out";
ctx.strokeStyle = "rgba(0,0,0,1)";

正如您在 this article 中看到的那样,曾经有一段时间 Firefox、Chrome 和 Webkit 不支持值 copy。我猜想当浏览器实现此功能时您的程序中断。

编辑:出于某种原因,toDataUrl 似乎没有正确反射(reflect)橡皮擦的变化。如果您将存储在 cPushArray 中的值更改为来自 ctx.getImageData 的图像数据,并使用 ctx.putImageData 将数据放回 Canvas 上,它就可以正常工作。

Updated Demo

关于javascript - HTML 5 canvas globalCompositeOperation(橡皮擦)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24858293/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com