Javascript绘制弹性矩形带

Javascript绘制弹性矩形带,javascript,canvas,xor,Javascript,Canvas,Xor,我试图在Javascript中创建一个拖动矩形,它允许用户通过拖动来绘制矩形,以便在画布上选择一个区域 我正在尝试使用“xor”操作在鼠标移动处理程序上重复绘制。但我无法做到这一点 我的代码是一个html文件,如下所示 <!DOCTYPE html> <html> <head> <style> /*body, html { width: 100% }*/ #canvas

我试图在Javascript中创建一个拖动矩形,它允许用户通过拖动来绘制矩形,以便在画布上选择一个区域

我正在尝试使用“xor”操作在鼠标移动处理程序上重复绘制。但我无法做到这一点

我的代码是一个html文件,如下所示

<!DOCTYPE html>
<html>
<head>
    <style>
        /*body, html {
            width: 100%
        }*/
        #canvas {
            background-color: #EFEFEF;
            width: 100%;
        }
    </style>
</head>
<body>
    <canvas id="canvas">
        canvas
    </canvas>
    <script src="jquery-1.11.1.js"></script>
    <script>
        var ctx = document.getElementById("canvas").getContext('2d');
        ctx.lineWidth = 1;

        var canvasOffset, offsetX, offsetY;
        var isDrawing = false;
        var prevX, prevY;
        canvasOffset = $("#canvas").offset();
        offsetX = canvasOffset.left;
        offsetY = canvasOffset.top;

        $("#canvas").on('mousedown', function(e) {
            handleMouseDown(e);
        }).on('mouseup', function(e) {
            handleMouseUp();
        }).on('mousemove', function(e) {
            handleMouseMove(e);
        });

        function handleMouseUp() {
            isDrawing = false;
            canvas.style.cursor = "default";
        }

        function handleMouseMove(e) {
            if (isDrawing) {
                var mouseX = e.clientX - offsetX;
                var mouseY = e.clientY - offsetY;
                ctx.globalCompositeOperation = "xor";
                ctx.strokeStyle = "red";
                ctx.beginPath();
                console.log("Erasing rect @ ", start_X, start_Y, prevX - start_X, prevY - start_Y);
                ctx.rect(start_X, start_Y, prevX - start_X, prevY - start_Y);

                console.log("Drawing rect @ ", start_X, start_Y, mouseX - start_X, mouseY - start_Y);
                ctx.rect(start_X, start_Y, mouseX - start_X, mouseY - start_Y);
                prevX = mouseX, prevY = mouseY;
                ctx.stroke();
            }
        }

        function handleMouseDown(e) {
            canvas.style.cursor = "crosshair";
            isDrawing = true;
            start_X = e.clientX - offsetX;
            start_Y = e.clientY - offsetY;
            prevX = start_X, prevY = start_Y;
        }
    </script>
    </body>
</html>

/*正文,html{
宽度:100%
}*/
#帆布{
背景色:#EFEF;
宽度:100%;
}
帆布
var ctx=document.getElementById(“画布”).getContext(“2d”);
ctx.lineWidth=1;
var canvasOffset、offsetX、offsetY;
var isDrawing=错误;
var-prevX,prevY;
canvasOffset=$(“#画布”).offset();
offsetX=canvasOffset.left;
offsetY=canvasOffset.top;
$(“#画布”)。在('mousedown',函数(e)上{
把手向下(e);
}).on('mouseup',函数(e){
handleMouseUp();
}).on('mousemove',函数(e){
手推车(e);
});
函数handleMouseUp(){
isDrawing=false;
canvas.style.cursor=“默认”;
}
功能手柄移动(e){
if(isDrawing){
var mouseX=e.clientX-offsetX;
var mouseY=e.clientY-offsetY;
ctx.globalCompositeOperation=“xor”;
ctx.strokeStyle=“红色”;
ctx.beginPath();
log(“擦除rect@”、开始\u X、开始\u Y、prevX-start\u X、prevY-start\u Y);
ctx.rect(start_X,start_Y,prevX-start_X,prevY-start_Y);
log(“Drawing rect@”、start_X、start_Y、mouseX-start_X、mouseY-start_Y);
ctx.rect(start_X,start_Y,mouseX-start_X,mouseY-start_Y);
prevX=mouseX,prevY=mouseY;
ctx.stroke();
}
}
功能手柄向下(e){
canvas.style.cursor=“十字线”;
isDrawing=true;
start_X=e.clientX-offsetX;
start_Y=e.clientY-offsetY;
prevX=开始,prevY=开始;
}
下面是我的代码的JSFIDLE链接

问题是: i) 它不会从单击鼠标的点开始绘制。 ii)它不会擦除以前的矩形笔划

非常感谢您的帮助

更新 根据Derek的建议,更新了JSFIDLE,对画布宽度拉伸进行了修正:100%,像素偏移量为0.5,用于模糊补偿

更新的JSFIDLE在这里()。这几乎奏效了。但在拖动时,我仍然可以看到一些零散的残留线碎片

谢谢你的帮助

第二次更新:
这在Google chrome中似乎很有效,但在IE或Firefox中却不行。这可能是这些浏览器的一个实现问题

问题是您在CSS中使用了
width:100%
。这将导致画布拉伸。使用
width
属性而不是
width
属性将解决第一个问题。Thanx,它解决了问题#1。然而,xor并没有发生。这里有一个固定的问题:我不知道你提到的“xor”部分,但是我相信你必须用
clearRect
.Thanx来清除canvase以快速修复。如果我应用clearRect,它可能会删除画布上的任何背景图形。y xor不起作用的原因是什么?
xor
不会也删除背景图形吗?我相信,xor和其他组合类型是用于在现有像素(如)上绘制形状,而不是类似动画的。