0

我正在尝试用 Canvas 制作一个小型绘图工具。今天我正在研究矩形。这是我的代码:

<body>
    <div id="main">
        <form name="Show">
            X <input type="text" name="MouseX" value="0" size="4"><br>
            Y <input type="text" name="MouseY" value="0" size="4"><br>
       </form>
       <canvas id="canvas" width="300" height="300">
          Your browser does not support Canvas !!
       </canvas>
        <div>
        <select name="color">
        <option value="black" selected>Black</option>
        <option value="red">Red</option>
        <option value="blue">Blue</option>
        <option value="green">Green</option>
        <option value="yellow">Yellow</option>
        <option value="brown">Brown</option>
        </select>
        <img id="rectMode" src="rectMode.png" />
        </div>
        <div>
            <button id="clear">Clear the draw</button>
        </div>
    </div>


<script language="JavaScript">

var color= 'black';
var mode= 0;
/**
 * All functions here
 */
function draw(startX, startY, endX, endY)   {
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(endX, endY);
    ctx.strokeStyle= color;
    ctx.stroke();
}
function drawRect(startX, startY, width, height)   {
    ctx.beginPath();
    ctx.rect(startX, startY, width, height);
    ctx.strokeStyle= color;
    ctx.stroke();
}
/**
 * Change draw color
 */
$("select[name=color]").change(function(){
    color= $(this).val();
})

/**
 * Draw Mode
 * 0: normal
 * 1: draw Rectangle
 */
$("#rectMode").click(function(){
    if(mode!= 1) {
        mode= 1;
        $(this).attr('src','rectMode1.png');
    }
    else  {
        mode= 0;
        $(this).attr('src','rectMode.png');
    }
})

/**
 * Get Cursor Coordinates
 */
ctx= $("#canvas")[0].getContext('2d');

var IE = document.all?true:false;
if (!IE) document.captureEvents(Event.MOUSEMOVE)
document.onmousemove = getMouseXY;
var tempX = 0;
var tempY = 0;
var pos= new Array();

function getMouseXY(e) {
if (IE) {
    tempX = event.clientX + document.body.scrollLeft;
    tempY = event.clientY + document.body.scrollTop;
}
else {  
    tempX = e.pageX;
    tempY = e.pageY;
    tempX -= $("#canvas").offset().left;
    tempY -= $("#canvas").offset().top;
}  
if (tempX < 0) {
    tempX = 0;
}
if (tempY < 0) {
    tempY = 0;
}  
document.Show.MouseX.value = tempX;
document.Show.MouseY.value = tempY;

pos[0]= tempX;
pos[1]= tempY;
return true;
}

/**
 * On mouse down get cursor coordinates to start drawing
 */
$("#canvas").mousedown(function(){
    getMouseXY;
    startY= pos[1];
    // On mouse move keep drawing with mode
    $("#canvas").mousemove(function(){
        getMouseXY;
        endX= pos[0];
        endY= pos[1];
        if(mode==1) {
            width= endX - startX;
            height= endY- startY;
            ctx.clearRect(startX, startY, width, height);
            drawRect(startX, startY, width, height);
        }
        else  {
            draw(startX, startY, endX, endY);
            startX= pos[0];
            startY= pos[1];
        }
    })
})

/**
 *  On mouse up stop drawing
 */
$(document).mouseup(function(){
    $("canvas").unbind("mousemove");
})

/**
 * Clear Canvas Content
 */
$("#clear").click(function(){
    ctx.clearRect(0,0,300,300);
})
</script>
</body>

好吧,我的问题是: Exp:当我在坐标 (10,10) 处鼠标按下并鼠标移动到 (100,100) 时,正确绘制了一个矩形。但是当我继续将鼠标移回(90,90)时,从(100,100)到(90,90)的所有矩形都不像我预期的那样清晰。

当我将鼠标移动到某个地方而不是将其移回到起点附近时,总是会发生这种情况。

有人可以看看我的代码并告诉我出了什么问题,我在绘制新矩形之前清除了前一个矩形,所以这个错误应该不会发生。

请帮帮我,非常感谢你:)

4

1 回答 1

2

您需要跟踪上一次绘制操作的坐标。实际上,您只是清除了要为每一帧绘制的区域,这意味着随着矩形的缩小,您不会清除先前绘制的区域,而只是清除其中的一部分。

为了确定这一点,我在某些地方对您的代码进行了相当大的重构,所以请询问我是否做了任何您不理解的事情。

http://jsfiddle.net/DaveRandom/YUtpH/1/

var color = 'black',
    rectMode = 0,
    IE = document.all ? true : false,
    $canvas = $("#canvas"),
    ctx = $canvas[0].getContext('2d');

/**
 * All functions here
 */
function getMouseXY(e, $canvas) {
    var pos = {};

    if (IE) {
        pos.x = event.clientX + document.body.scrollLeft;
        pos.y = event.clientY + document.body.scrollTop;
    } else {
        pos.x = e.pageX - $canvas.offset().left;
        pos.y = e.pageY - $canvas.offset().top;
    }

    document.Show.MouseX.value = pos.x = Math.min(300, Math.max(0, pos.x));
    document.Show.MouseY.value = pos.y = Math.min(300, Math.max(0, pos.y));

    return pos;
}

function draw(action, startPos, endPos) {
    action.ctx.beginPath();
    if (action.rectMode) {
        drawRect(action);
    } else {
        drawLine(action);
    }
    action.ctx.strokeStyle = action.color;
    action.ctx.stroke();
}

function drawLine(action) {
    action.ctx.moveTo(action.start.x, action.start.y);
    action.ctx.lineTo(action.end.x, action.end.y);
    action.start = action.end;
}

function drawRect(action) {
    var clearX = action.last.x + (action.last.w < 0 ? 1 : -1),
        clearY = action.last.y + (action.last.h < 0 ? 1 : -1),
        clearW = action.last.w + (action.last.w < 0 ? -2 : 2),
        clearH = action.last.h + (action.last.h < 0 ? -2 : 2),
        drawX = action.start.x,
        drawY = action.start.y,
        drawW = action.end.x - action.start.x,
        drawH = action.end.y - action.start.y;

    action.ctx.clearRect(clearX, clearY, clearW, clearH);
    action.ctx.rect(drawX, drawY, drawW, drawH);

    action.last = {
        x: drawX,
        y: drawY,
        w: drawW,
        h: drawH
    };
}

/**
 * Get Cursor Coordinates
 */
if (!IE) {
    document.captureEvents(Event.MOUSEMOVE);
}

/**
 * Change draw color
 */
$("select[name=color]").change(function(){
    color = $(this).val();
});

/**
 * Draw Mode
 * 0: normal
 * 1: draw Rectangle
 */
$("#rectMode").click(function() {
    if (rectMode) {
        rectMode = 0;
        $(this).attr('src','rectMode.png');
    } else {
        rectMode = 1;
        $(this).attr('src','rectMode1.png');
    }
});

/**
 * On mouse down get cursor coordinates to start drawing
 */
$canvas.mousedown(function(e) {
    var startPos = getMouseXY(e, $canvas),
        action = {
            ctx: ctx,
            color: color,
            rectMode: rectMode,
            start: startPos,
            last: {
                x: startPos.x,
                y: startPos.y,
                w: 0,
                y: 0
            }
        };

    // On mouse move keep drawing with mode
    $canvas.mousemove(function(e){
        action.end = getMouseXY(e, $canvas);
        draw(action);
    });
});

/**
 * On mouse up stop drawing
 */
$(document).mouseup(function(){
    $canvas.unbind("mousemove");
});

/**
 * Clear Canvas Content
 */
$("#clear").click(function() {
    ctx.clearRect(0, 0, 300, 300);
});
于 2013-04-15T10:52:38.663 回答