refactor: Enhance ControlsPlayer and CamMode for improved camera mode handling and UI responsiveness

This commit is contained in:
Vishnu 2025-05-15 12:06:51 +05:30
parent 8facad31bc
commit 9cd08f75e3
6 changed files with 104 additions and 34 deletions

View File

@ -1,23 +1,44 @@
import React, { useState } from "react";
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
import React, { useEffect, useState } from "react";
import useCameraModeStore, {
usePlayButtonStore,
} from "../../../store/usePlayButtonStore";
import useModuleStore from "../../../store/useModuleStore";
import { PlayIcon } from "../../icons/ShortcutIcons";
import InputToggle from "../../ui/inputs/InputToggle";
import { EyeCloseIcon, WalkIcon } from "../../icons/ExportCommonIcons";
import { ExitIcon } from "../../icons/SimulationIcons";
import { useCamMode } from "../../../store/builder/store";
const ControlsPlayer = () => {
const ControlsPlayer: React.FC = () => {
const { setIsPlaying } = usePlayButtonStore();
const { activeModule } = useModuleStore();
const [walkMode, setWalkMode] = useState(false);
const { walkMode, toggleWalkMode } = useCameraModeStore();
const [hidePlayer, setHidePlayer] = useState(false);
const { camMode } = useCamMode();
const changeCamMode = () => {
setWalkMode(!walkMode);
console.log("switch camera mode to first person");
toggleWalkMode();
echo.log("switch camera mode to first person");
// Simulate "/" keypress
const slashKeyEvent = new KeyboardEvent("keydown", {
key: "/",
code: "Slash",
keyCode: 191, // for compatibility
which: 191,
bubbles: true,
cancelable: true,
});
document.dispatchEvent(slashKeyEvent);
};
useEffect(() => {
if (camMode === "ThirdPerson") {
toggleWalkMode();
} else return;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [camMode]);
return (
<div className="controls-player-container">
<div className={`controls-player-container${hidePlayer ? " hide" : ""}`}>
{!hidePlayer && (
<div className="controls-left">
<PlayIcon />
@ -26,7 +47,7 @@ const ControlsPlayer = () => {
)}
<div className="controls-right">
{!hidePlayer && (
{!hidePlayer && activeModule === "builder" && (
<div className="walkMode-wrapper">
<WalkIcon />
<InputToggle

View File

@ -6,6 +6,7 @@ import { useKeyboardControls } from "@react-three/drei";
import switchToThirdPerson from "./switchToThirdPerson";
import switchToFirstPerson from "./switchToFirstPerson";
import { detectModifierKeys } from "../../../utils/shortcutkeys/detectModifierKeys";
import { firstPersonCamera } from "./firstPersonCamera";
const CamMode: React.FC = () => {
const { camMode, setCamMode } = useCamMode();
@ -65,26 +66,14 @@ const CamMode: React.FC = () => {
const keyCombination = detectModifierKeys(event);
if (keyCombination === "/" && !isTransitioning && !toggleView) {
setIsTransitioning(true);
state.controls.mouseButtons.left =
CONSTANTS.controlsTransition.leftMouse;
state.controls.mouseButtons.right =
CONSTANTS.controlsTransition.rightMouse;
state.controls.mouseButtons.wheel =
CONSTANTS.controlsTransition.wheelMouse;
state.controls.mouseButtons.middle =
CONSTANTS.controlsTransition.middleMouse;
if (camMode === "ThirdPerson") {
setCamMode("FirstPerson");
await switchToFirstPerson(state.controls, state.camera);
} else if (camMode === "FirstPerson") {
setCamMode("ThirdPerson");
await switchToThirdPerson(state.controls, state.camera);
}
setIsTransitioning(false);
firstPersonCamera({
setIsTransitioning,
state,
camMode,
setCamMode,
switchToFirstPerson,
switchToThirdPerson,
});
}
};
@ -92,6 +81,7 @@ const CamMode: React.FC = () => {
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
camMode,
isTransitioning,
@ -140,6 +130,3 @@ const CamMode: React.FC = () => {
};
export default CamMode;

View File

@ -0,0 +1,39 @@
import * as CONSTANTS from "../../../types/world/worldConstants";
interface FirstPersonCameraProps {
setIsTransitioning?: (value: boolean) => void;
state: any;
}
interface FirstPersonCameraParams extends FirstPersonCameraProps {
camMode: string;
setCamMode: (mode: string) => void;
switchToFirstPerson: (controls: any, camera: any) => Promise<void>;
switchToThirdPerson: (controls: any, camera: any) => Promise<void>;
}
export async function firstPersonCamera({
setIsTransitioning,
state,
camMode,
setCamMode,
switchToFirstPerson,
switchToThirdPerson
}: FirstPersonCameraParams): Promise<void> {
setIsTransitioning && setIsTransitioning(true);
state.controls.mouseButtons.left = CONSTANTS.controlsTransition.leftMouse;
state.controls.mouseButtons.right = CONSTANTS.controlsTransition.rightMouse;
state.controls.mouseButtons.wheel = CONSTANTS.controlsTransition.wheelMouse;
state.controls.mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse;
if (camMode === "ThirdPerson") {
setCamMode("FirstPerson");
await switchToFirstPerson(state.controls, state.camera);
} else if (camMode === "FirstPerson") {
setCamMode("ThirdPerson");
await switchToThirdPerson(state.controls, state.camera);
}
setIsTransitioning && setIsTransitioning(false);
}

View File

@ -33,3 +33,17 @@ export const useAnimationPlaySpeed = create<AnimationSpeedState>((set) => ({
speed: 1,
setSpeed: (value) => set({ speed: value }),
}));
interface CameraModeState {
walkMode: boolean;
setWalkMode: (enabled: boolean) => void;
toggleWalkMode: () => void;
}
const useCameraModeStore = create<CameraModeState>((set) => ({
walkMode: false,
setWalkMode: (enabled) => set({ walkMode: enabled }),
toggleWalkMode: () => set((state) => ({ walkMode: !state.walkMode })),
}));
export default useCameraModeStore;

View File

@ -358,7 +358,8 @@
}
.controls-player-container {
max-width: 50vw;
min-width: 26vw;
max-width: 80vw;
border-radius: 15px;
gap: 40px;
background: var(--background-color);
@ -375,6 +376,12 @@
isolation: isolate;
font-weight: 700;
padding: 8px;
transition: all 0.2s;
&.hide {
min-width: none;
width: 92px;
}
.controls-left,
.controls-right {

View File

@ -11,7 +11,7 @@ import {
useToggleView,
useToolMode,
} from "../../store/builder/store";
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
import useCameraModeStore, { usePlayButtonStore } from "../../store/usePlayButtonStore";
import { detectModifierKeys } from "./detectModifierKeys";
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
@ -29,6 +29,7 @@ const KeyPressListener: React.FC = () => {
const { setActiveTool } = useActiveTool();
const { clearSelectedZone } = useSelectedZoneStore();
const { showShortcuts, setShowShortcuts } = useShortcutStore();
const { setWalkMode } = useCameraModeStore();
const isTextInput = (element: Element | null): boolean =>
element instanceof HTMLInputElement ||
@ -168,6 +169,7 @@ const KeyPressListener: React.FC = () => {
}
if (keyCombination === "ESCAPE") {
setWalkMode(false);
setActiveTool("cursor");
setActiveSubTool("cursor");
setIsPlaying(false);