html 绘制圆的起始位置错误

3ks5zfa0  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(389)

我写了一个函数,它允许我在画布上画圆。一切都很好,但我的画布的开始位置和我的鼠标位置不一样。

const stopDrawingCircle = () => {
    setIsDrawing(false);
    console.log(currentImage);
}
//Setting start position
const startDrawingCircle = (event:any) => {
    currentImage.circle.x = event.clientX;
    currentImage.circle.y = event.clientY;
    currentImage.circle.radius = 0;
    setIsDrawing(true);
};
const drawCircle = function(event:any){
    if(!isDrawing)
      return;
    let canvas = canvasRef.current as HTMLCanvasElement | null; 
    let ctx = canvas?.getContext('2d')
    //seems to be the problem console log at start says the result of this is zero
    var currentX = currentImage.circle.x - event.clientX;
    var currentY = currentImage.circle.y - event.clientY;
    currentImage.circle.radius = Math.sqrt(currentX * currentX + currentY * currentY)
    if(canvas != null && ctx != null){
        ctx.beginPath();
        ctx.arc(currentImage.circle.x, currentImage.circle.y, currentImage.circle.radius, 0, Math.PI*2);
        ctx.fill();
    }
}
return(
  <div className="main">
    <div id="imageSection">
      <canvas id="canvas" 
        onMouseDown={startDrawingCircle}
        onMouseUp={stopDrawingCircle}
        onMouseMove={drawCircle}
        ref={canvasRef}> </canvas>       
    </div>
  </div>
)

画圆的结果是这样的:

我开始用我的鼠标在图像的中心,他画在“右下角”

rbl8hiat

rbl8hiat1#

event.clientXevent.clientY相对于当前屏幕,而不是被单击的元素。
MDN MouseEvent.clientX文档:
客户端X
一个数字,默认为0,表示鼠标事件在用户屏幕客户端窗口上的水平位置;
使用event.offsetXevent.offsetY取得鼠标器相对于事件目的的位置。
但是,由于使用的是React,因此需要使用event.nativeEvent.offsetXevent.nativeEvent.offsetY,因为react不会将offset属性复制到它们的事件代理对象上。
完整代码示例:

import {useState, useRef} from "react";

const currentImage = {
  circle: {
    x: 0,
    y: 0,
    radius: 10,
  }
};

export default function App() {
  const [isDrawing, setIsDrawing] = useState(false);
  const canvasRef = useRef<HTMLCanvasElement>(null);

  const stopDrawingCircle = () => {
      setIsDrawing(false);
      // console.log(currentImage);
  }
  //Setting start position
  const startDrawingCircle = (event:any) => {
      currentImage.circle.x = event.nativeEvent.offsetX;
      currentImage.circle.y = event.nativeEvent.offsetY;
      currentImage.circle.radius = 0;
      setIsDrawing(true);
  };
  const drawCircle = function(event:any){
      if(!isDrawing)
        return;
      let canvas = canvasRef.current as HTMLCanvasElement | null; 
      let ctx = canvas?.getContext('2d')
      //seems to be the problem console log at start says the result of this is zero
      var currentX = currentImage.circle.x - event.nativeEvent.offsetX;
      var currentY = currentImage.circle.y - event.nativeEvent.offsetY;

      currentImage.circle.radius = Math.sqrt(currentX * currentX + currentY * currentY)
      if(canvas != null && ctx != null){
          ctx.beginPath();
          ctx.arc(currentImage.circle.x, currentImage.circle.y, currentImage.circle.radius, 0, Math.PI*2);
          ctx.fill();
      }
  }
  return(
    <div className="main">
      <div id="imageSection">
        <canvas id="canvas" 
          onMouseDown={startDrawingCircle}
          onMouseUp={stopDrawingCircle}
          onMouseMove={drawCircle}
          ref={canvasRef}> </canvas>       
      </div>
    </div>
  )
}
f0ofjuux

f0ofjuux2#

很难运行您的示例,因为它似乎不是一个完整的示例。
我怀疑你的错误是什么,我认为这个简单的例子将足以让你解决你的问题。
第一个
因此,如您所见,仅获得单击的X和Y坐标是不够的,它与画布元素不相关,要在画布上绘制,您需要它的相对坐标。
如果你的画布从页面的左上角开始,这并不重要,但如果它不在那里,那么获得画布坐标就很重要,这样你就可以正确地计算点击位置。
假设你的画布从顶部开始50px,从左边开始100px。每次点击画布,你需要减去50px的X坐标和100px的Y坐标。有了这些相对值,你就可以在画布上画圆,每次圆都会在光标的中间。

相关问题