我正在尝试绘制一个矩形,就像您在 Paint 中所做的那样。 但目前,当我尝试绘制一个矩形时,这就是我的画布的样子——双重绘图,凌乱的矩形。
这是我的整个代码的样子:
(删除代码)
如何绘制一个看起来像这样的矩形:像一个矩形?
我正在尝试绘制一个矩形,就像您在 Paint 中所做的那样。 但目前,当我尝试绘制一个矩形时,这就是我的画布的样子——双重绘图,凌乱的矩形。
这是我的整个代码的样子:
(删除代码)
如何绘制一个看起来像这样的矩形:像一个矩形?
你发布的代码有数组:
ctx.rect(x[x1],y[y1]
但我猜你画的不仅仅是矩形......
这是一个示例:
ctx = document.getElementById('c').getContext('2d');
ctx.lineWidth = 2;
x = [5, 30, 90]
y = [5, 50, 30]
for (i = 0; i < x.length; i++) {
ctx.rect(x[i], y[i], 50, 20)
}
ctx.stroke();
<canvas height="100" width="300" id="c">
只是矩形而已,没有双重绘图或混乱,您提供的代码不应导致任何问题,例如您在图片中显示的内容。
这是基于您的新代码的更新...
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
ctx.lineWidth = 2;
var x = 0;
var y = 0;
draw = false;
function down() {
x = event.clientX;
y = event.clientY;
draw = true;
}
function move() {
if (draw) {
var a = event.clientX;
var b = event.clientY;
ctx.clearRect(0, 0, canvas.width, canvas.height)
addCircles()
ctx.beginPath()
ctx.rect(x, y, a - x, b - y);
ctx.stroke();
}
}
function up() {
draw = false
}
function addCircles() {
ctx.beginPath()
ctx.fillStyle = '#F00';
ctx.arc(50, 50, 30, 0, Math.PI * 2)
ctx.fill();
ctx.beginPath()
ctx.fillStyle = '#0F0';
ctx.arc(100, 100, 30, 0, Math.PI * 2)
ctx.fill();
ctx.beginPath()
ctx.fillStyle = '#00F';
ctx.arc(200, 80, 30, 0, Math.PI * 2)
ctx.fill();
}
addCircles()
<canvas id="myCanvas" width="300" height="160" style="border:1px solid #000000;" onmousedown="down()" onmousemove="move()" onmouseup="up()"> </canvas>
你有一堆变量,我删除了绘制矩形并非绝对需要的所有内容,以后无论如何你都可以复杂化你喜欢绘制多个对象,但我建议你经常测试你的代码,小的增量更改确保它做了什么你要。
首先,我认为将坐标存储在分隔变量而不是数组(startX,startY,lastX,lastY)中会更清楚。
此外,您应该从鼠标位置中减去画布位置以获得画布内的坐标,现在它可以工作,因为画布位于页面顶部。
我看到您想保留旧内容,我使用画布存储以前绘制的内容,然后在绘制当前矩形之前必须重新绘制旧内容(使用 ctx.drawImage)。
您应该在坐标上添加 0.5,这样线条就不会变得模糊,只有当您绘制一条奇数宽度(1、3、5)的线条时才会发生这种情况。这是因为如果您尝试在坐标 x=1 上绘制 1px 线,则必须在两侧(0.5 到 1.5)绘制半个像素,因此看起来很模糊。
但是如果你在 x=0.5 处绘制它,你会绘制从 0 到 1 的线,这正好是一个像素。
var isDown = false;
var startX, startY;
var lastX, lastY;
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var canvasRect = canvas.getBoundingClientRect();
var backBuffer = canvas.cloneNode(true);
var backBufferCtx = backBuffer.getContext('2d');
canvas.addEventListener('mousedown', function down() {
startX = event.clientX - canvasRect.left;
startY = event.clientY - canvasRect.top;
isDown = true;
});
canvas.addEventListener('mouseup', function up() {
isDown = false;
// Draw Current Canvas Content
updateCanvas();
// Save current content
backBufferCtx.clearRect(0, 0, backBuffer.width, backBuffer.height);
backBufferCtx.drawImage(canvas, 0, 0);
});
canvas.addEventListener('mousemove', function move() {
if (! isDown) return;
lastX = event.clientX - canvasRect.left;
lastY = event.clientY - canvasRect.top;
updateCanvas();
});
function updateCanvas() {
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw Current Canvas Content
ctx.drawImage(backBuffer, 0, 0);
// Draw New Rectangle
ctx.beginPath();
// add 0.5 so the line do not get blurry
ctx.rect(startX + 0.5, startY + 0.5, lastX - startX, lastY - startY);
ctx.stroke();
}
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000; margin-top: 100px"></canvas>
画布的上下文是一个非常强大的东西,我建议你在https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D上查看它的所有属性、方法
特别是对于您的用例:上下文提供了直接读写画布数据的方法,getImageData()
-putImageData()
是该方法对。使用它们,您可以在用户开始绘制新矩形时存储画布包含的任何内容,并在调整当前矩形大小时恢复它。存储的数据甚至可以提供一步“撤消”功能作为副产品:
var cnv=document.getElementById("cnv"),
ctx=cnv.getContext("2d"),
col=document.getElementById("color"),
ubtn=document.getElementById("undo"),
copy,
pick=false;
function mdown(event){
copy=ctx.getImageData(0,0,cnv.width,cnv.height);
pick={
x:event.offsetX,
y:event.offsetY
};
}
function mup(event){
pick=false;
ubtn.disabled=false;
}
function mmove(event){
if(pick){
ctx.putImageData(copy,0,0);
ctx.strokeStyle=col.value;
ctx.lineWidth=2;
ctx.strokeRect(pick.x,pick.y,event.offsetX-pick.x,event.offsetY-pick.y);
}
}
function undo(){
ctx.putImageData(copy,0,0);
ubtn.disabled=true;
}
<input type="color" id="color"><button id="undo" disabled onclick="undo()">Undo</button><br>
<canvas id="cnv" width="300" height="140" style="border:1px solid black;cursor:crosshair" onmousedown="mdown(event)" onmousemove="mmove(event)" onmouseup="mup(event)"></canvas>