试着在这里做一个互动的平面图.继续,一些答案已经被看到了.js-如果问题无法解决,我们也会这样做.

这给了我一些开始写作的建议

我现在的代码是:

const Scheme1 = function (){
  const svg = useRef(null);
  const [isPanning, setIsPanning] = useState(false);
  const [cursorPos, setCursorPos] = useState({ x:0, y:0 });
  const [newSVGPos, setNewSVGPos] = useState({ x:0, y:0 });
  const [SVGViewbox, setSVGViewbox] = useState({ x:0, y:0, width:2472.3, height: 1467.24 });

  let startPanSVG = (e) => {
    setIsPanning(true);
    setCursorPos({ x:e.clientX, y:e.clientY });
  }

  let panSVG = (e) => {
    if(!isPanning) {
      return;
    }

    e.stopPropagation();
    e.preventDefault();
    let SVGDimensions = e.target.getBoundingClientRect();
    let ratio = SVGViewbox.width/SVGDimensions.width;
    let newX = SVGViewbox.x - ((e.clientX - cursorPos.x) * ratio);
    let newY = SVGViewbox.y - ((e.clientY - cursorPos.y) * ratio);
    setNewSVGPos({ x:newX, y:newY });
  }

  let stopPanSVG = () => {
    setIsPanning(false);
    setSVGViewbox({ ...SVGViewbox, x:newSVGPos.x, y:newSVGPos.y });
  }

  return (
    <svg ref={svg} viewBox={Object.values(SVGViewbox).join(" ")} onPointerDown={startPanSVG} onPointerMove={panSVG} onPointerLeave={stopPanSVG} onPointerUp={stopPanSVG} version="1.1" id="svg1003">
    ...
    </svg>
)}

主要的问题是SVG在平移过程中不会被鼠标拖动,只有在完成stopPanSVG次后才会执行相当苛刻的移动.可能是因为useState分别是异步和触发的,或者对重新渲染有限制?try 用useEffect替换它并不顺利——理想情况下,我希望它在startPanSVG内,所以它只在事件发生时触发,但这违反了钩子的规则.用钩子包装所述函数会导致e.clientX未定义,即使前缀为"?"s或跳过初始装载.

也许有更好的 Select ?应该补充一点,window/document/global由于项目设置而被禁用——例如,不能addEventListener.

推荐答案

我相信这会解决你的问题:

let panSVG = (e) => {
  if(!isPanning) {
    return;
  }

  e.stopPropagation();
  e.preventDefault();

  let SVGDimensions = e.target.getBoundingClientRect();
  let ratio = SVGViewbox.width/SVGDimensions.width;
  let newX = SVGViewbox.x - ((e.clientX - cursorPos.x) * ratio);
  let newY = SVGViewbox.y - ((e.clientY - cursorPos.y) * ratio);

  // change the viewport here
  setSVGViewbox({ ...SVGViewbox, x: newX, y: newY });
}

let stopPanSVG = () => {
  setIsPanning(false);
  // don't change viewport here
}

Reactjs相关问答推荐

优化、自定义登录页面、使用用户ID而不是邮箱

react 导致不必要的回归

如何实现黑暗模式 map ?

在 React 中是否有任何理由要记住 Redux 操作创建者?

无法通过 fetch 获取数据到上下文中

标签文本删除了 MUI 概述的输入

如何在 React Hook Form 中使用嵌套对象处理错误验证消息

Mui / Material UI 5:如何从 StaticTimePicker 中删除打开下一个视图/打开上一个视图按钮?

Reactjs:MUI5:MobileDateTimePicker API:如何自定义日历中的文本

解决在React测试库中的act()警告

React - 函数组件 - 点击两次问题处理

Material UI @mui/material/Button vs @material-ui/core/Button,它什么时候改变的,旧版本的文档在哪里

Stripe Checkout:是否可以创建不自动续订的订阅?

如何在 ReactJS 中提交后删除 URL 中的查询参数

react-router v6 中的 BrowserRouter 和 createBrowserRouter 有什么区别?我可以在不使用数据 API 的情况下使用 createBrowserRouter 吗?

如何禁用 redux-toolkit 的不可序列化值测试警告?

使用 Jest/React 测试库时,如何测试由 setInterval 函数创建的 DOM 更改?

谁能根据经验提供有关 useEffect 挂钩的更多信息

如果 URL 已随功能组件更改,则取消刷新

我在使用 Elements of stripe 时使用 React router v6