如何限制反应三纤维MapControls中的平移距离

How to limit panning distance in react three fiber MapControls

我正在使用 React Three Fiberdrei。我想知道如何使用 MapControls 限制最大平移距离。 网上有一些关于如何使用普通 three.js 存档的解决方案,但没有使用来自 dreir3f.

MapControlsOrbitControls

我试过了,但是一旦达到极限,相机就会出现奇怪的故障。

function Controls() {
  const { camera } = useThree();

  useFrame(() => {
    camera.position.x = THREE.MathUtils.clamp(camera.position.x, -90, 90)
    camera.position.y = THREE.MathUtils.clamp(camera.position.y, -90, 90)
  })
  
  return (
    <MapControls />
  )
}

感谢您的帮助

亚历山大

根据 this 的回答,解决方案是创建一个如下所示的自定义 'Controls' 组件。

const Controls = () => {
  const { camera } = useThree()
  const controlsRef = useRef()    

  useEffect(() => {
    controlsRef.current.addEventListener('change', function () {
      if (this.target.y < -10) {
        this.target.y = -10
        camera.position.y = -10
      } else if (this.target.y > 10) {
        this.target.y = 10
        camera.position.y = 10
      }
    })
  }, [])

  return (
    <MapControls ref={controlsRef} enableZoom={false} enableRotate={false} />
  )
}

然后可以用作 Canvas 组件的子组件。

<Canvas>
  <Controls />
</Canvas>

这是我使用 onChange 属性 或 MapControls 的解决方案。

控件组件:

import React, { useRef } from 'react'
import { MapControls } from '@react-three/drei'
import { useThree } from '@react-three/fiber'

const Controls = () => {
  const { camera } = useThree()
  const cameraLastPosition = useRef({
    x: camera.position.x,
    y: camera.position.y,
  })

  return (
    <MapControls
      onChange={(e) => {
        const maxX = 90
        const minX = -90
        const maxY = 90
        const minY = -90
        const x = e?.target.target.x
        const y = e?.target.target.y

        if (x < minX || x > maxX) {
          e?.target.target.setX(x < minX ? minX : maxX)
          camera.position.setX(cameraLastPosition.current.x)
        }
        if (y < minY || y > maxY) {
          e?.target.target.setY(y < minY ? minY : maxY)
          camera.position.setY(cameraLastPosition.current.y)
        }
        cameraLastPosition.current.x = camera.position.x
        cameraLastPosition.current.y = camera.position.y
      }}
    />
  )
}

export default Controls

导入该组件并在您的 Canvas:

中使用它
<Canvas>
  <Controls />
</Canvas>