为什么 ctx.strokeRect() 的行为不同于顺序 ctx.rect() ctx.stroke() 调用
Why is ctx.strokeRect() behaving differently than sequential ctx.rect() ctx.stroke() calls
我使用 create-react-app 创建了一个 React 应用程序。在此应用中,用户上传一张绘制到 canvas 的图片。这个应用程序允许用户裁剪图像,我试图在用户鼠标拖动到图像上时绘制裁剪区域的矩形预览。
这里是绘制动态裁剪区域预览的函数。这个效果很好,因为它使用 ctx.strokeRect()
。每次用户移动鼠标时,rectXY
都会更新,并调用 drawCropRect
清除之前的矩形并创建一个新矩形。
// draw rectangle preview of cropped area
const drawCropRect = (
canvasRef,
rectXY,
croppedCanvasData
) => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.putImageData(croppedCanvasData,0,0, 0,0,canvas.width,canvas.height);
ctx.strokeStyle = "#f6dd43";
// calling strokeRect() - this works
ctx.strokeRect(
rectXY.xStart,
rectXY.yStart,
rectXY.xCurrent - rectXY.xStart,
rectXY.yCurrent - rectXY.yStart
);
};
// calls drawCropRect when the user is dragging the mouse to crop image
useEffect(() => {
if (props.step === "crop") {
drawCropRect(canvasRef, cropRect, croppedCanvasData[0]);
}
}, [cropRect]);
// cropRect is a state hook containing starting and current mouse positions
// drawCropRect will get called every time cropRect updates.. so whenever the user moves the mouse during a crop event.
但是,如果我不调用 ctx.strokeRect()
,而是调用 ctx.rect()
,然后调用 ctx.stroke()
,矩形不会被清除,我会看到图像上生成的所有矩形。
这是相同的函数,但调用了单独的 ctx.rect()
和 ctx.stroke()
。
// draw rectangle preview of cropped area
const drawCropRect = (canvasRef, rectXY, croppedCanvasData) => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.putImageData(
croppedCanvasData,
0,
0,
0,
0,
canvas.width,
canvas.height
);
ctx.strokeStyle = "#f6dd43";
// calling rect() and then stroke()- this does not work
ctx.rect(
rectXY.xStart,
rectXY.yStart,
rectXY.xCurrent - rectXY.xStart,
rectXY.yCurrent - rectXY.yStart
);
ctx.stroke();
};
为什么会这样?单独调用ctx.rect()
和ctx.stroke()
如何防止用户移动鼠标时清除它们?
尝试在 drawCropRect()
的 rect()
部分的开头使用 ctx.beginPath()
。
如果您不使用 ctx.beginPath()
,它会抛出 canvas。
希望对您有所帮助!
我使用 create-react-app 创建了一个 React 应用程序。在此应用中,用户上传一张绘制到 canvas 的图片。这个应用程序允许用户裁剪图像,我试图在用户鼠标拖动到图像上时绘制裁剪区域的矩形预览。
这里是绘制动态裁剪区域预览的函数。这个效果很好,因为它使用 ctx.strokeRect()
。每次用户移动鼠标时,rectXY
都会更新,并调用 drawCropRect
清除之前的矩形并创建一个新矩形。
// draw rectangle preview of cropped area
const drawCropRect = (
canvasRef,
rectXY,
croppedCanvasData
) => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.putImageData(croppedCanvasData,0,0, 0,0,canvas.width,canvas.height);
ctx.strokeStyle = "#f6dd43";
// calling strokeRect() - this works
ctx.strokeRect(
rectXY.xStart,
rectXY.yStart,
rectXY.xCurrent - rectXY.xStart,
rectXY.yCurrent - rectXY.yStart
);
};
// calls drawCropRect when the user is dragging the mouse to crop image
useEffect(() => {
if (props.step === "crop") {
drawCropRect(canvasRef, cropRect, croppedCanvasData[0]);
}
}, [cropRect]);
// cropRect is a state hook containing starting and current mouse positions
// drawCropRect will get called every time cropRect updates.. so whenever the user moves the mouse during a crop event.
但是,如果我不调用 ctx.strokeRect()
,而是调用 ctx.rect()
,然后调用 ctx.stroke()
,矩形不会被清除,我会看到图像上生成的所有矩形。
这是相同的函数,但调用了单独的 ctx.rect()
和 ctx.stroke()
。
// draw rectangle preview of cropped area
const drawCropRect = (canvasRef, rectXY, croppedCanvasData) => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.putImageData(
croppedCanvasData,
0,
0,
0,
0,
canvas.width,
canvas.height
);
ctx.strokeStyle = "#f6dd43";
// calling rect() and then stroke()- this does not work
ctx.rect(
rectXY.xStart,
rectXY.yStart,
rectXY.xCurrent - rectXY.xStart,
rectXY.yCurrent - rectXY.yStart
);
ctx.stroke();
};
为什么会这样?单独调用ctx.rect()
和ctx.stroke()
如何防止用户移动鼠标时清除它们?
尝试在 drawCropRect()
的 rect()
部分的开头使用 ctx.beginPath()
。
如果您不使用 ctx.beginPath()
,它会抛出 canvas。
希望对您有所帮助!