From 0f478e8e1a74d9cf9c255a8d5d1623896366b236 Mon Sep 17 00:00:00 2001 From: Vishnu Date: Thu, 11 Sep 2025 10:14:17 +0530 Subject: [PATCH] feat: enhance camera controls and switch view functionality with 3D toggle integration --- .../cameraShortcutsControls.tsx | 80 ++++++++++++------- app/src/modules/scene/camera/switchView.tsx | 6 +- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/app/src/modules/scene/camera/shortcutsControls/cameraShortcutsControls.tsx b/app/src/modules/scene/camera/shortcutsControls/cameraShortcutsControls.tsx index 573584c..aaf3045 100644 --- a/app/src/modules/scene/camera/shortcutsControls/cameraShortcutsControls.tsx +++ b/app/src/modules/scene/camera/shortcutsControls/cameraShortcutsControls.tsx @@ -1,11 +1,14 @@ +import { Vector3 } from "three"; import { useEffect } from "react"; import { useThree } from "@react-three/fiber"; -import * as THREE from "three"; import type { CameraControls } from "@react-three/drei"; +import { useThreeDStore } from "../../../../store/ui/useModuleStore"; +import * as CONSTANTS from "../../../../types/world/worldConstants"; const CameraShortcutsControls = () => { const { camera, controls } = useThree(); - + const { toggleThreeD, setToggleThreeD } = useThreeDStore(); + const isTextInput = (element: Element | null): boolean => element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || @@ -18,54 +21,77 @@ const CameraShortcutsControls = () => { const cc = controls as CameraControls; // get current target - const target = new THREE.Vector3(); + const target = new Vector3(); cc.getTarget(target); const distance = camera.position.distanceTo(target); - let pos: THREE.Vector3 | null = null; + let pos: Vector3 | null = null; - const dir = new THREE.Vector3().subVectors(camera.position, target).normalize(); + const dir = new Vector3().subVectors(camera.position, target).normalize(); if (isTextInput(document.activeElement)) return; - switch (e.key) { - case "1": // Front - pos = new THREE.Vector3(0, 0, distance).add(target); + switch (e.code) { + case "Numpad1": // Front + pos = new Vector3(0, 0, distance).add(target); + LookAt(pos); break; - case "3": // Right - pos = new THREE.Vector3(distance, 0, 0).add(target); + case "Numpad3": // Right + pos = new Vector3(distance, 0, 0).add(target); + LookAt(pos); break; - case "7": // Top - pos = new THREE.Vector3(0, distance, 0).add(target); + case "Numpad7": // Top + pos = new Vector3(0, distance, 0).add(target); + LookAt(pos); break; - case "9": { + case "Numpad9": { // Opposite view logic if (Math.abs(dir.z) > Math.abs(dir.x) && Math.abs(dir.z) > Math.abs(dir.y)) { - // Currently looking Front/Back → flip Z - pos = new THREE.Vector3(0, 0, -Math.sign(dir.z) * distance).add(target); - } else if (Math.abs(dir.x) > Math.abs(dir.z) && Math.abs(dir.x) > Math.abs(dir.y)) { - // Currently looking Right/Left → flip X - pos = new THREE.Vector3(-Math.sign(dir.x) * distance, 0, 0).add(target); + pos = new Vector3(0, 0, -Math.sign(dir.z) * distance).add(target); + LookAt(pos); + } else if ( + Math.abs(dir.x) > Math.abs(dir.z) && + Math.abs(dir.x) > Math.abs(dir.y) + ) { + pos = new Vector3(-Math.sign(dir.x) * distance, 0, 0).add(target); + LookAt(pos); } else { - // Currently looking Top/Bottom → stay Top - pos = new THREE.Vector3(0, distance, 0).add(target); + pos = new Vector3(0, distance, 0).add(target); + LookAt(pos); + } + break; + } + case "Numpad5": { + // Only apply when on Top view + + if (!toggleThreeD) { + console.log("cc: ", cc.camera); + setToggleThreeD(true); + (cc as any).mouseButtons.left = CONSTANTS.threeDimension.leftMouse; + (cc as any).mouseButtons.right = CONSTANTS.threeDimension.rightMouse; + } else { + console.log("cc: ", cc.camera); + cc.setLookAt(0, distance, 0, target.x, target.y, target.z, false).then( + () => { + setToggleThreeD(false); + (cc as any).mouseButtons.left = CONSTANTS.twoDimension.leftMouse; + (cc as any).mouseButtons.right = CONSTANTS.twoDimension.rightMouse; + } + ); } break; } } - if (pos) { - cc.setLookAt( - pos.x, pos.y, pos.z, // camera position - target.x, target.y, target.z, // keep same target - true // smooth transition - ); + function LookAt(pos: Vector3) { + console.log('hi lookat'); + cc.setLookAt(pos.x, pos.y, pos.z, target.x, target.y, target.z, true); } }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); - }, [controls, camera]); + }, [controls, camera, toggleThreeD, setToggleThreeD]); return null; }; diff --git a/app/src/modules/scene/camera/switchView.tsx b/app/src/modules/scene/camera/switchView.tsx index 8028abc..592f510 100644 --- a/app/src/modules/scene/camera/switchView.tsx +++ b/app/src/modules/scene/camera/switchView.tsx @@ -6,11 +6,13 @@ import { useParams } from "react-router-dom"; import * as CONSTANTS from "../../../types/world/worldConstants"; import { getCameraApi } from "../../../services/factoryBuilder/camera/getCameraApi"; import { useToggleView } from "../../../store/builder/store"; +import { useThreeDStore } from "../../../store/ui/useModuleStore"; export default function SwitchView() { const { toggleView } = useToggleView(); const { controls } = useThree(); const { projectId } = useParams(); + const { toggleThreeD } = useThreeDStore(); useEffect(() => { if (toggleView && controls) { @@ -39,11 +41,11 @@ export default function SwitchView() { (controls as any).mouseButtons.right = CONSTANTS.threeDimension.rightMouse; } } - }, [toggleView, controls]); + }, [toggleView, controls, projectId]); return ( <> - {toggleView ? ( + {(toggleView || !toggleThreeD) ? (