【发布时间】:2014-09-11 13:21:42
【问题描述】:
好的,几个月前我建立了一个绘图系统,基本上可以让用户在画布上绘图。我包含的一些功能是使用用户定义的笔画颜色和大小、橡皮擦和撤消/重做进行绘制。
我刚刚检查了一些项目,以查看它们是如何运作的,并注意到在我构建和发布此草图工具时没有发生的一个新问题。
我的问题是,在用户绘制完任何内容然后使用橡皮擦擦除草图的一部分后,鼠标按下时整个画布都将被清除。这在以前没有发生过。橡皮擦应该跟随光标并清除鼠标的笔划路径。所以我想知道画布如何读取全局复合操作或其他内容是否有任何变化。我搜索了堆栈和谷歌,找不到任何明确的答案,所以我希望也许其他人遇到了这个问题。
我还注意到,当我在橡皮擦清除画布后切换回钢笔工具时,不再绘制任何东西。即使我撤消,它也会显示上一个被擦除的笔画,但绘图工具不再做任何事情。
如果我尝试擦除所有内容都会被清除,但如果我撤消它会恢复在尝试擦除之前存储的内容。
这是我用于绘图和擦除的脚本。任何有关该主题的帮助将不胜感激。谢谢。
我还想指出,这个问题发生在最新版本的 chrome、firefox 和 IE 11 中。
编辑:我忘了提。发现此问题后,我尝试将 globalCompositeOperation 切换为“destination-out”,但并没有像我想要的那样留下坚实的笔触。它只是制作了一系列点(正在擦除),但并不像应有的那样光滑/干净。
编辑:小提琴链接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;
}
});
【问题讨论】:
-
您的 strokeStyle 的不透明度为空,因此几乎没有机会绘制任何内容。
-
@GameAlchemist 它怎么是空的?我认为 rgba(0,0,0,0) 是定义它的正确方法吗?关于我应该尝试将其更改为的任何输入?
-
rgba() 颜色的最后一个组成部分是 alpha,范围为 0.0-1.0。如果为 0,则不会绘制任何内容(除非您使用特定的混合模式,但您使用的是复合模式,而不是此处的混合模式)。修复很简单:使用 rgb(,,) 或 rgba(,,,1)。
-
@GameAlchemist 我尝试了您的建议,但仍然面临同样的问题:(。尝试 rgba(0,0,0) 和 rgba(0,0,0,0.0) 现在唯一的区别是光标显示一个黑点,但仍清除整个画布
-
如果您可以设置一个非常适合理解/调试您的问题的小提琴。
标签: javascript jquery html canvas html5-canvas