React - 如何正确获取 canvas 上的客户端坐标? (用鼠标画一条直线)
React - How to get client coordinates on canvas properly? (drawing a straight line with mouse)
我必须让“画一条线”起作用,但是这条线不会从我的鼠标开始的地方开始,而是从最开始的 {x: 0, y:0} 开始。如何从我鼠标点击的地方画一条线?
我已经使用 e.nativeEvent.offsetX 和 e.nativeEvent.offsetY 来获取客户端 X 和 Y,这仅用于绘图功能,但我不知道如何利用它来绘制线条,或者更改我的画线代码以使其工作。先谢谢你了!
const canvasRef = useRef(null);
const ctxRef = useRef(null);
const [isDrawing, setIsDrawing] = useState(false);
const [lineWidth, setLineWidth] = useState(5);
const [lineColor, setLineColor] = useState("black");
let startPosition = {x: 0, y: 0};
let lineCoordinates = {x: 0, y: 0};
const getClientOffset = (e) => {
const {pageX, pageY} = e.touches ? e.touches[0] : e;
const x = pageX - canvasRef.offsetLeft;
const y = pageY - canvasRef.offsetTop;
return {
x,
y
}
}
const drawLine = () => {
ctxRef.current.beginPath();
ctxRef.current.moveTo(startPosition.x, startPosition.y);
ctxRef.current.lineTo(lineCoordinates.x, lineCoordinates.y);
ctxRef.current.stroke();
}
useLayoutEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.strokeStyle = lineColor;
ctx.lineWidth = lineWidth;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctxRef.current = ctx;
}, [lineColor, lineWidth]);
const handleMouseDown = (e) => {
setIsDrawing(true);
// const posX = e.nativeEvent.offsetX;
// const posY = e.nativeEvent.offsetY;
// ctxRef.current.beginPath();
// ctxRef.current.moveTo(
// posX,
// posY
// );
startPosition = getClientOffset(e);
}
const handleMouseMove = (e) => {
if (!isDrawing) {
return;
}
ctxRef.current.lineTo(
e.nativeEvent.offsetX,
e.nativeEvent.offsetY
);
ctxRef.current.stroke();
lineCoordinates = getClientOffset(e);
drawLine();
}
const handleMouseUp = () => {
ctxRef.current.closePath();
setIsDrawing(false);
}
问题是 let startPosition
和 let lineCoordinates
– 在每次渲染更新时,React 将使用 {x: 0, y:0}
重新初始化这些变量。为了记住任何值,您必须使用 useState()
.
我在演示中试过了
https://codesandbox.io/s/crazy-breeze-xj26c?file=/src/App.js
我必须让“画一条线”起作用,但是这条线不会从我的鼠标开始的地方开始,而是从最开始的 {x: 0, y:0} 开始。如何从我鼠标点击的地方画一条线?
我已经使用 e.nativeEvent.offsetX 和 e.nativeEvent.offsetY 来获取客户端 X 和 Y,这仅用于绘图功能,但我不知道如何利用它来绘制线条,或者更改我的画线代码以使其工作。先谢谢你了!
const canvasRef = useRef(null);
const ctxRef = useRef(null);
const [isDrawing, setIsDrawing] = useState(false);
const [lineWidth, setLineWidth] = useState(5);
const [lineColor, setLineColor] = useState("black");
let startPosition = {x: 0, y: 0};
let lineCoordinates = {x: 0, y: 0};
const getClientOffset = (e) => {
const {pageX, pageY} = e.touches ? e.touches[0] : e;
const x = pageX - canvasRef.offsetLeft;
const y = pageY - canvasRef.offsetTop;
return {
x,
y
}
}
const drawLine = () => {
ctxRef.current.beginPath();
ctxRef.current.moveTo(startPosition.x, startPosition.y);
ctxRef.current.lineTo(lineCoordinates.x, lineCoordinates.y);
ctxRef.current.stroke();
}
useLayoutEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.strokeStyle = lineColor;
ctx.lineWidth = lineWidth;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctxRef.current = ctx;
}, [lineColor, lineWidth]);
const handleMouseDown = (e) => {
setIsDrawing(true);
// const posX = e.nativeEvent.offsetX;
// const posY = e.nativeEvent.offsetY;
// ctxRef.current.beginPath();
// ctxRef.current.moveTo(
// posX,
// posY
// );
startPosition = getClientOffset(e);
}
const handleMouseMove = (e) => {
if (!isDrawing) {
return;
}
ctxRef.current.lineTo(
e.nativeEvent.offsetX,
e.nativeEvent.offsetY
);
ctxRef.current.stroke();
lineCoordinates = getClientOffset(e);
drawLine();
}
const handleMouseUp = () => {
ctxRef.current.closePath();
setIsDrawing(false);
}
问题是 let startPosition
和 let lineCoordinates
– 在每次渲染更新时,React 将使用 {x: 0, y:0}
重新初始化这些变量。为了记住任何值,您必须使用 useState()
.
我在演示中试过了 https://codesandbox.io/s/crazy-breeze-xj26c?file=/src/App.js