如何限制反应三纤维MapControls中的平移距离
How to limit panning distance in react three fiber MapControls
我正在使用 React Three Fiber
和 drei
。我想知道如何使用 MapControls
限制最大平移距离。
网上有一些关于如何使用普通 three.js
存档的解决方案,但没有使用来自 drei
和 r3f
.
的 MapControls
或 OrbitControls
我试过了,但是一旦达到极限,相机就会出现奇怪的故障。
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>
我正在使用 React Three Fiber
和 drei
。我想知道如何使用 MapControls
限制最大平移距离。
网上有一些关于如何使用普通 three.js
存档的解决方案,但没有使用来自 drei
和 r3f
.
MapControls
或 OrbitControls
我试过了,但是一旦达到极限,相机就会出现奇怪的故障。
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>