控制更改期间的 React 状态更新将 OrbitControls 从三个

发布于 2025-01-11 09:58:19 字数 1150 浏览 0 评论 0原文

我将 React 3 与 drei OrbitControls 结合使用,并在移动相机时尝试检测相机是否高于或低于零。目前,我正在使用 onEnd 侦听器来触发 ParentComponent 中的代码。如果我像这样更改父组件的状态,那么一切都会按预期进行。不幸的是,如果我在结束另一次轨道控制之前开始另一次改变轨道控制并改变我的父母状态,轨道控制将会中断。例如,我旋转相机并按住鼠标左键,然后使用相机将其降到零以下,同时用鼠标滚轮滚动,轨道控件不再起作用。当使用触摸时,这尤其痛苦。一旦第二根手指触碰,我就会越过地面,轨道控制就会中断。

这是我的控件组件:

const Controls = forwardRef(({ handleCamera }, ref) => {
  const { gl, camera } = useThree();
  const controls = useRef(null);

  useImperativeHandle(ref, () => ({
    getCamera() {
      return camera
    },
  }))

  const handleChange = (e) => {
      handleCamera(camera); 
  }

  return (
    <OrbitControls ref={controls}
      onEnd={(e) => handleChange(e)}
    />
  );
});

export default Controls;

这是我的父组件:

function App() {  
  const handleCamera = (camera) => {
    setCameraBelowSurface(camera.position.y <= 0 ? true : false);
  };
  return
    <Canvas >
      <Suspense>
        <Controls
          ref={controlsRef}
          handleCamera={handleCamera}
        />          
      </Suspense>
    </Canvas>    
}

export default App;

I am using react three with drei orbitControls and try to detect wether the camera is above or below zero, while moving the camera around. Currently I'm using onEnd listener to trigger my code in my ParentComponent. If I change a state of my parent component like so everything works as expected. Unfortunately if I start another change of orbit controls before ending another and change my parents state, orbit controls will break. E.g. I rotate the camera and hold down my left mouse button, than get below zero with my camera and the scroll with my mouse wheel at the same time, Orbit controls no longer works. This is especially painful when using touch. As soon as a second finger touches and I cross the ground orbit control breaks.

This is my Controls Component:

const Controls = forwardRef(({ handleCamera }, ref) => {
  const { gl, camera } = useThree();
  const controls = useRef(null);

  useImperativeHandle(ref, () => ({
    getCamera() {
      return camera
    },
  }))

  const handleChange = (e) => {
      handleCamera(camera); 
  }

  return (
    <OrbitControls ref={controls}
      onEnd={(e) => handleChange(e)}
    />
  );
});

export default Controls;

And this is my parent:

function App() {  
  const handleCamera = (camera) => {
    setCameraBelowSurface(camera.position.y <= 0 ? true : false);
  };
  return
    <Canvas >
      <Suspense>
        <Controls
          ref={controlsRef}
          handleCamera={handleCamera}
        />          
      </Suspense>
    </Canvas>    
}

export default App;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奢望 2025-01-18 09:58:19

我遇到了同样的问题,幸运的是我找到了解决这个问题的方法。我希望这对某人有帮助。

首先,当您使用状态变量并更改其值时,组件将重新渲染,从而导致此问题。因此,您只需使用 ref 即可代替状态变量。

 const isDragging = React.useRef(false);

在“onStart”和“onEnd”事件中设置 ref 的当前属性:

<OrbitControls
  onStart={() => {
    isDragging.current = true;
  }}
  onEnd={() => {
    isDragging.current = false;
  }}
  autoRotate={false}
  autoRotateSpeed={0.4}
/>

I had the same issue and fortunatelly I found out a solution for this problem. I hope it is going to be helpful for someone.

First of all when you use state variable and change their value then component will re-render which causing this issue. So instead of state variables you need to just use ref.

 const isDragging = React.useRef(false);

Setting the current property of ref in 'onStart' and 'onEnd' events:

<OrbitControls
  onStart={() => {
    isDragging.current = true;
  }}
  onEnd={() => {
    isDragging.current = false;
  }}
  autoRotate={false}
  autoRotateSpeed={0.4}
/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文