feat: add camera shortcut functionality for improved navigation in 3D space; refactor ShortcutHelper and Builder components for better structure
This commit is contained in:
@@ -55,6 +55,7 @@ interface ShortcutHelperProps {
|
||||
const ShortcutHelper: React.FC<ShortcutHelperProps> = ({
|
||||
setShowShortcuts,
|
||||
}) => {
|
||||
|
||||
const shortcuts: ShortcutGroup[] = [
|
||||
// Essential
|
||||
{
|
||||
@@ -310,6 +311,7 @@ const ShortcutHelper: React.FC<ShortcutHelperProps> = ({
|
||||
>
|
||||
<CloseIcon />
|
||||
</button>
|
||||
|
||||
<div className="header">
|
||||
<div className="header-wrapper">
|
||||
{shortcuts.map((group) => (
|
||||
|
||||
47
app/src/hooks/useCameraShortcuts.ts
Normal file
47
app/src/hooks/useCameraShortcuts.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useEffect } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import type { CameraControls } from "@react-three/drei";
|
||||
|
||||
export const useCameraShortcuts = (controlsRef: React.RefObject<CameraControls>) => {
|
||||
const { camera } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (!controlsRef.current) return;
|
||||
|
||||
// get current distance from camera to target
|
||||
const target = new THREE.Vector3();
|
||||
controlsRef.current.getTarget(target);
|
||||
|
||||
const distance = camera.position.distanceTo(target);
|
||||
let pos: THREE.Vector3 | null = null;
|
||||
|
||||
switch (e.key) {
|
||||
case "1": // Front
|
||||
pos = new THREE.Vector3(0, 0, distance).add(target);
|
||||
break;
|
||||
case "3": // Right
|
||||
pos = new THREE.Vector3(distance, 0, 0).add(target);
|
||||
break;
|
||||
case "7": // Top
|
||||
pos = new THREE.Vector3(0, distance, 0).add(target);
|
||||
break;
|
||||
case "9": // Back
|
||||
pos = new THREE.Vector3(0, 0, -distance).add(target);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pos) {
|
||||
controlsRef.current.setLookAt(
|
||||
pos.x, pos.y, pos.z, // camera position
|
||||
target.x, target.y, target.z, // keep same target
|
||||
true // smooth transition
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [controlsRef, camera]);
|
||||
};
|
||||
@@ -57,6 +57,7 @@ export default function Builder() {
|
||||
const { setHoveredPoint, setHoveredLine } = useBuilderStore();
|
||||
const { userId, organization } = getUserData();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!toggleView) {
|
||||
setHoveredLine(null);
|
||||
|
||||
@@ -18,6 +18,7 @@ import ContextControls from "./contextControls/contextControls";
|
||||
import SelectionControls2D from "./selectionControls/selection2D/selectionControls2D";
|
||||
import UndoRedo2DControls from "./undoRedoControls/undoRedo2D/undoRedo2DControls";
|
||||
import UndoRedo3DControls from "./undoRedoControls/undoRedo3D/undoRedo3DControls";
|
||||
import { useCameraShortcuts } from "../../../hooks/useCameraShortcuts";
|
||||
|
||||
export default function Controls() {
|
||||
const controlsRef = useRef<CameraControls>(null);
|
||||
@@ -116,6 +117,7 @@ export default function Controls() {
|
||||
stopInterval();
|
||||
};
|
||||
}, [toggleView, state, socket]);
|
||||
useCameraShortcuts(controlsRef);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user