javascript HTML 5画布全局合成操作(橡皮擦)问题

vwkv1x7d  于 2023-02-21  发布在  Java
关注(0)|答案(1)|浏览(76)

好的,几个月前我建立了一个绘图系统,基本上可以让用户在画布上绘图。我包括的一些功能是用用户定义的颜色和笔画大小,橡皮擦和撤销/重做来绘图。
我刚刚检查了一些项目,看看它们仍然是如何工作的,并注意到一个新的问题,这是没有发生时,我建立和发布这个草图工具。
我的问题是,在用户画完任何东西然后去擦除器擦除草图的一部分之后,整个画布在鼠标按下时被清除。这以前没有发生过。橡皮擦应该跟随光标并清除鼠标所采用的笔划路径。所以我想知道画布读取全局复合操作或其他操作的方式是否有任何变化。我'我在stack和google上搜索过了,但是没有找到任何明确的答案,所以我希望也许其他人也遇到过这个问题。
我还注意到,当我在橡皮擦清除画布后切换回钢笔工具时,什么也画不出来。即使我撤销,它也会显示上一个被擦除的笔划,但绘图工具不再做任何事情。
如果我尝试擦除所有内容,则会清除所有内容,但如果我撤消,则会带回尝试擦除之前存储的内容。
这是我用来画图和擦除的脚本。任何关于这个主题的帮助都将不胜感激。谢谢。
我还想指出的是,这个问题正在发生在最新版本的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;
    } 
});
hgtggwj0

hgtggwj01#

若要使橡皮擦重新工作,您需要在“橡皮擦”功能中更改以下行:

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似乎不能正确地反映橡皮擦的变化。如果你把cPushArray中存储的值改为ctx.getImageData中的图像数据,然后用ctx.putImageData把数据放回画布,它就能正常工作。
Updated Demo

相关问题