我试图用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)的所有矩形都不像我预期的那样清晰。
当我将鼠标移动到某个地方而不是将其移回接近起点时,总会发生这种情况。
有人可以查看我的代码并告诉我出了什么问题,我在绘制新的矩形之前清除了前一个矩形,所以这个错误应该不会发生。
请帮助我,非常感谢你。)
答案 0 :(得分: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);
});