我正在使用画布和js制作带有橡皮筋的绘画工具。当前,它绘制椭圆形,但是每次我开始拖动以绘制新形状时-由于rubberBand功能的特定性,先前的形状会擦除,导致每次清除画布。有什么办法可以解决这个问题?
这是jsfiddle链接:https://jsfiddle.net/ThePanda/bspf5v40/
HTML(index.html):
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./style.css" />
<script src="index.js"></script>
</head>
<body>
<div style="position:absolute; top:4px; left:4px;"><canvas id="canvas"></canvas></div>
<script>
canvasEngine();
</script>
</body>
</html>
CSS(style.css):
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#canvas {
border: 2px solid black;
}
JavaScript(index.js):
function canvasEngine() {
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
canvas.height = window.innerHeight - 12;
canvas.width = window.innerWidth - 12;
//letiables
let canvasStartX = 4;
let canvasStartY = 4;
let lastMouseY, lastMouseX;
let mouseX, mouseY;
let width, height;
let mousedown = false;
//Mousedown
function startPosition(e) {
lastMouseX = parseInt(e.clientX - canvasStartX);
lastMouseY = parseInt(e.clientY - canvasStartY);
mousedown = true;
};
//Mousemove
function rubberBand(e) {
if (!mousedown) return;
mouseX = parseInt(e.clientX - canvasStartX);
mouseY = parseInt(e.clientY - canvasStartY);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
width = mouseX-lastMouseX;
height = mouseY-lastMouseY;
ctx.rect(lastMouseX,lastMouseY,width,height);
ctx.strokeStyle = 'blue';
ctx.lineWidth = 2;
ctx.stroke();
};
//Mouseup
function finishedPosition(e) {
mousedown = false;
mouseX = parseInt(e.clientX - canvasStartX);
mouseY = parseInt(e.clientY - canvasStartY);
width = mouseX - lastMouseX;
height = mouseY - lastMouseY;
const rw = Math.abs(width/2);
const rh = Math.abs(height/2);
let centerX = mouseX - width/2;
let centerY = mouseY - height/2;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.ellipse(centerX,centerY,rw,rh,0,0,2 * Math.PI);
ctx.strokeStyle = color;
ctx.lineWidth = 5;
ctx.stroke();
};
canvas.addEventListener("mousedown", startPosition);
canvas.addEventListener("mousemove", rubberBand);
canvas.addEventListener("mouseup", finishedPosition);
};
答案 0 :(得分:1)
您的代码对于您要实现的目标基本上是正确的。
主要问题是,每次绘制新内容时,您都会呼叫ctx.clearRect
。这样,整个画布就被清除了,旧的椭圆也消失了。
我已尝试对您的代码进行最小的更改以解决此问题:
function canvasEngine() {
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
canvas.height = window.innerHeight - 12;
canvas.width = window.innerWidth - 12;
//letiables
let canvasStartX = 4;
let canvasStartY = 4;
let lastMouseY, lastMouseX;
let mouseX, mouseY;
let width, height;
let mousedown = false;
let ellipses = [];
function drawEllipse(ellipse) {
ctx.beginPath();
ctx.ellipse(
ellipse.centerX,
ellipse.centerY,
ellipse.rw,
ellipse.rh,
0,
0,
2 * Math.PI
);
ctx.stroke();
}
function drawEllipses() {
ctx.strokeStyle = 'black';
ctx.lineWidth = 5;
ellipses.forEach(drawEllipse)
}
//Mousedown
function startPosition(e) {
lastMouseX = parseInt(e.clientX - canvasStartX);
lastMouseY = parseInt(e.clientY - canvasStartY);
mousedown = true;
};
//Mousemove
function rubberBand(e) {
if (!mousedown) return;
mouseX = parseInt(e.clientX - canvasStartX);
mouseY = parseInt(e.clientY - canvasStartY);
ctx.clearRect(0,0,canvas.width,canvas.height);
drawEllipses();
ctx.beginPath();
width = mouseX-lastMouseX;
height = mouseY-lastMouseY;
ctx.rect(lastMouseX,lastMouseY,width,height);
ctx.strokeStyle = 'blue';
ctx.lineWidth = 2;
ctx.stroke();
};
//Mouseup
function finishedPosition(e) {
mousedown = false;
mouseX = parseInt(e.clientX - canvasStartX);
mouseY = parseInt(e.clientY - canvasStartY);
width = mouseX - lastMouseX;
height = mouseY - lastMouseY;
const rw = Math.abs(width/2);
const rh = Math.abs(height/2);
let centerX = mouseX - width/2;
let centerY = mouseY - height/2;
// Add the ellipse to the list of ellipses
ellipses.push({ centerX, centerY, rw, rh })
ctx.clearRect(0,0,canvas.width,canvas.height);
drawEllipses();
};
canvas.addEventListener("mousedown", startPosition);
canvas.addEventListener("mousemove", rubberBand);
canvas.addEventListener("mouseup", finishedPosition);
};
canvasEngine();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#canvas {
border: 2px solid black;
}
<div style="position:absolute; top:4px; left:4px;"><canvas id="canvas"></canvas></div>