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 startPositionlet lineCoordinates – 在每次渲染更新时,React 将使用 {x: 0, y:0} 重新初始化这些变量。为了记住任何值,您必须使用 useState().

我在演示中试过了 https://codesandbox.io/s/crazy-breeze-xj26c?file=/src/App.js