feat: add camera shortcut functionality for improved navigation in 3D space; refactor ShortcutHelper and Builder components for better structure

This commit is contained in:
Nalvazhuthi
2025-08-25 17:49:18 +05:30
parent 6f308ddda4
commit 60cdf4e6af
4 changed files with 52 additions and 0 deletions

View File

@@ -55,6 +55,7 @@ interface ShortcutHelperProps {
const ShortcutHelper: React.FC<ShortcutHelperProps> = ({ const ShortcutHelper: React.FC<ShortcutHelperProps> = ({
setShowShortcuts, setShowShortcuts,
}) => { }) => {
const shortcuts: ShortcutGroup[] = [ const shortcuts: ShortcutGroup[] = [
// Essential // Essential
{ {
@@ -310,6 +311,7 @@ const ShortcutHelper: React.FC<ShortcutHelperProps> = ({
> >
<CloseIcon /> <CloseIcon />
</button> </button>
<div className="header"> <div className="header">
<div className="header-wrapper"> <div className="header-wrapper">
{shortcuts.map((group) => ( {shortcuts.map((group) => (

View 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]);
};

View File

@@ -57,6 +57,7 @@ export default function Builder() {
const { setHoveredPoint, setHoveredLine } = useBuilderStore(); const { setHoveredPoint, setHoveredLine } = useBuilderStore();
const { userId, organization } = getUserData(); const { userId, organization } = getUserData();
useEffect(() => { useEffect(() => {
if (!toggleView) { if (!toggleView) {
setHoveredLine(null); setHoveredLine(null);

View File

@@ -18,6 +18,7 @@ import ContextControls from "./contextControls/contextControls";
import SelectionControls2D from "./selectionControls/selection2D/selectionControls2D"; import SelectionControls2D from "./selectionControls/selection2D/selectionControls2D";
import UndoRedo2DControls from "./undoRedoControls/undoRedo2D/undoRedo2DControls"; import UndoRedo2DControls from "./undoRedoControls/undoRedo2D/undoRedo2DControls";
import UndoRedo3DControls from "./undoRedoControls/undoRedo3D/undoRedo3DControls"; import UndoRedo3DControls from "./undoRedoControls/undoRedo3D/undoRedo3DControls";
import { useCameraShortcuts } from "../../../hooks/useCameraShortcuts";
export default function Controls() { export default function Controls() {
const controlsRef = useRef<CameraControls>(null); const controlsRef = useRef<CameraControls>(null);
@@ -116,6 +117,7 @@ export default function Controls() {
stopInterval(); stopInterval();
}; };
}, [toggleView, state, socket]); }, [toggleView, state, socket]);
useCameraShortcuts(controlsRef);
return ( return (
<> <>