camera controls enhancement
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { sceneRegistry, useScene } from '@pascal-app/core'
|
||||
import { useViewer } from '@pascal-app/viewer'
|
||||
import { CameraControls, CameraControlsImpl } from '@react-three/drei'
|
||||
import { useEffect, useMemo, useRef } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { Box3, Vector3 } from 'three'
|
||||
|
||||
const tempBox = new Box3()
|
||||
@@ -28,7 +28,7 @@ export const ViewerCameraControls = () => {
|
||||
: CameraControlsImpl.ACTION.DOLLY
|
||||
|
||||
return {
|
||||
left: CameraControlsImpl.ACTION.NONE,
|
||||
left: CameraControlsImpl.ACTION.SCREEN_PAN,
|
||||
middle: CameraControlsImpl.ACTION.SCREEN_PAN,
|
||||
right: CameraControlsImpl.ACTION.ROTATE,
|
||||
wheel: wheelAction,
|
||||
@@ -59,7 +59,7 @@ export const ViewerCameraControls = () => {
|
||||
target[0],
|
||||
target[1],
|
||||
target[2],
|
||||
true
|
||||
true,
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -81,7 +81,7 @@ export const ViewerCameraControls = () => {
|
||||
const cameraPos = new Vector3(
|
||||
tempCenter.x + distance * 0.7,
|
||||
tempCenter.y + distance * 0.5,
|
||||
tempCenter.z + distance * 0.7
|
||||
tempCenter.z + distance * 0.7,
|
||||
)
|
||||
|
||||
controls.current.setLookAt(
|
||||
@@ -91,10 +91,18 @@ export const ViewerCameraControls = () => {
|
||||
tempCenter.x,
|
||||
tempCenter.y,
|
||||
tempCenter.z,
|
||||
true
|
||||
true,
|
||||
)
|
||||
}, [targetNodeId, nodes])
|
||||
|
||||
const onTransitionStart = useCallback(() => {
|
||||
useViewer.getState().setCameraDragging(true)
|
||||
}, [])
|
||||
|
||||
const onRest = useCallback(() => {
|
||||
useViewer.getState().setCameraDragging(false)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<CameraControls
|
||||
ref={controls}
|
||||
@@ -103,6 +111,10 @@ export const ViewerCameraControls = () => {
|
||||
maxPolarAngle={Math.PI / 2 - 0.1}
|
||||
minPolarAngle={0}
|
||||
mouseButtons={mouseButtons}
|
||||
onTransitionStart={onTransitionStart}
|
||||
onRest={onRest}
|
||||
restThreshold={0.01}
|
||||
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { type CameraControlEvent, emitter, sceneRegistry, useScene } from '@pascal-app/core'
|
||||
import { useViewer } from '@pascal-app/viewer'
|
||||
import { CameraControls, CameraControlsImpl } from '@react-three/drei'
|
||||
import { useEffect, useMemo, useRef } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { Vector3 } from 'three'
|
||||
|
||||
const currentTarget = new Vector3()
|
||||
@@ -51,6 +51,86 @@ export const CustomCameraControls = () => {
|
||||
}
|
||||
}, [cameraMode])
|
||||
|
||||
useEffect(() => {
|
||||
console.log('ohla')
|
||||
const keyState = {
|
||||
shiftRight: false,
|
||||
shiftLeft: false,
|
||||
controlRight: false,
|
||||
controlLeft: false,
|
||||
space: false,
|
||||
}
|
||||
|
||||
const updateConfig = () => {
|
||||
if (!controls.current) return
|
||||
|
||||
const shift = keyState.shiftRight || keyState.shiftLeft
|
||||
const control = keyState.controlRight || keyState.controlLeft
|
||||
const space = keyState.space
|
||||
|
||||
const wheelAction =
|
||||
cameraMode === 'orthographic'
|
||||
? CameraControlsImpl.ACTION.ZOOM
|
||||
: CameraControlsImpl.ACTION.DOLLY
|
||||
controls.current.mouseButtons.wheel = wheelAction
|
||||
controls.current.mouseButtons.left = CameraControlsImpl.ACTION.NONE
|
||||
controls.current.mouseButtons.middle = CameraControlsImpl.ACTION.SCREEN_PAN
|
||||
controls.current.mouseButtons.right = CameraControlsImpl.ACTION.ROTATE
|
||||
if (space) {
|
||||
controls.current.mouseButtons.left = CameraControlsImpl.ACTION.SCREEN_PAN
|
||||
}
|
||||
}
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.code === 'Space') {
|
||||
keyState.space = true
|
||||
document.body.style.cursor = 'grab'
|
||||
}
|
||||
if (event.code === 'ShiftRight') {
|
||||
keyState.shiftRight = true
|
||||
}
|
||||
if (event.code === 'ShiftLeft') {
|
||||
keyState.shiftLeft = true
|
||||
}
|
||||
if (event.code === 'ControlRight') {
|
||||
keyState.controlRight = true
|
||||
}
|
||||
if (event.code === 'ControlLeft') {
|
||||
keyState.controlLeft = true
|
||||
}
|
||||
updateConfig()
|
||||
}
|
||||
|
||||
const onKeyUp = (event: KeyboardEvent) => {
|
||||
if (event.code === 'Space') {
|
||||
keyState.space = false
|
||||
document.body.style.cursor = ''
|
||||
}
|
||||
if (event.code === 'ShiftRight') {
|
||||
keyState.shiftRight = false
|
||||
}
|
||||
if (event.code === 'ShiftLeft') {
|
||||
keyState.shiftLeft = false
|
||||
}
|
||||
if (event.code === 'ControlRight') {
|
||||
keyState.controlRight = false
|
||||
}
|
||||
if (event.code === 'ControlLeft') {
|
||||
keyState.controlLeft = false
|
||||
}
|
||||
updateConfig()
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', onKeyDown)
|
||||
document.addEventListener('keyup', onKeyUp)
|
||||
updateConfig()
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('keydown', onKeyDown)
|
||||
document.removeEventListener('keyup', onKeyUp)
|
||||
}
|
||||
}, [cameraMode])
|
||||
|
||||
useEffect(() => {
|
||||
const handleNodeCapture = ({ nodeId }: CameraControlEvent) => {
|
||||
if (!controls.current) return
|
||||
@@ -139,6 +219,14 @@ export const CustomCameraControls = () => {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const onTransitionStart = useCallback(() => {
|
||||
useViewer.getState().setCameraDragging(true)
|
||||
}, [])
|
||||
|
||||
const onRest = useCallback(() => {
|
||||
useViewer.getState().setCameraDragging(false)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<CameraControls
|
||||
makeDefault
|
||||
@@ -148,6 +236,9 @@ export const CustomCameraControls = () => {
|
||||
minPolarAngle={0}
|
||||
ref={controls}
|
||||
mouseButtons={mouseButtons}
|
||||
onTransitionStart={onTransitionStart}
|
||||
onRest={onRest}
|
||||
restThreshold={0.01}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { type EventSuffix, emitter, type GridEvent } from '@pascal-app/core'
|
||||
import { useViewer } from '@pascal-app/viewer'
|
||||
import { useThree } from '@react-three/fiber'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { Plane, Raycaster, Vector2, Vector3 } from 'three'
|
||||
@@ -53,29 +54,35 @@ export function useGridEvents(gridY: number) {
|
||||
}
|
||||
|
||||
const handlePointerDown = (e: PointerEvent) => {
|
||||
if (useViewer.getState().cameraDragging) return
|
||||
if (e.button !== 0) return
|
||||
emit('pointerdown', e)
|
||||
}
|
||||
|
||||
const handlePointerUp = (e: PointerEvent) => {
|
||||
if (useViewer.getState().cameraDragging) return
|
||||
if (e.button !== 0) return
|
||||
emit('pointerup', e)
|
||||
}
|
||||
|
||||
const handleClick = (e: PointerEvent) => {
|
||||
if (useViewer.getState().cameraDragging) return
|
||||
if (e.button !== 0) return
|
||||
emit('click', e)
|
||||
}
|
||||
|
||||
const handlePointerMove = (e: PointerEvent) => {
|
||||
if (useViewer.getState().cameraDragging) return
|
||||
emit('move', e)
|
||||
}
|
||||
|
||||
const handleDoubleClick = (e: MouseEvent) => {
|
||||
if (useViewer.getState().cameraDragging) return
|
||||
emit('double-click', e)
|
||||
}
|
||||
|
||||
const handleContextMenu = (e: MouseEvent) => {
|
||||
if (useViewer.getState().cameraDragging) return
|
||||
emit('context-menu', e)
|
||||
}
|
||||
|
||||
@@ -95,5 +102,5 @@ export function useGridEvents(gridY: number) {
|
||||
canvas.removeEventListener('dblclick', handleDoubleClick)
|
||||
canvas.removeEventListener('contextmenu', handleContextMenu)
|
||||
}
|
||||
}, [camera, gl, gridY])
|
||||
}, [camera, gl])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user