mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-07-10 22:14:40 +00:00
add keyboard overlay for non-touch devices
This commit is contained in:
parent
0aadb3d6e7
commit
d7ef09c576
26 changed files with 215 additions and 107 deletions
130
app/page.tsx
130
app/page.tsx
|
|
@ -4,12 +4,17 @@ import { Canvas, GLProps } from "@react-three/fiber";
|
|||
import { NoToneMapping, SRGBColorSpace, PCFShadowMap, Camera } from "three";
|
||||
import { Mission } from "@/src/components/Mission";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { ObserverControls } from "@/src/components/ObserverControls";
|
||||
import {
|
||||
ObserverControls,
|
||||
KEYBOARD_CONTROLS,
|
||||
} from "@/src/components/ObserverControls";
|
||||
import { KeyboardOverlay } from "@/src/components/KeyboardOverlay";
|
||||
import {
|
||||
TouchJoystick,
|
||||
TouchCameraMovement,
|
||||
type JoystickState,
|
||||
} from "@/src/components/TouchControls";
|
||||
import { KeyboardControls } from "@react-three/drei";
|
||||
import { InspectorControls } from "@/src/components/InspectorControls";
|
||||
import { useTouchDevice } from "@/src/components/useTouchDevice";
|
||||
import { SettingsProvider } from "@/src/components/SettingsProvider";
|
||||
|
|
@ -130,68 +135,71 @@ function MapInspector() {
|
|||
<QueryClientProvider client={queryClient}>
|
||||
<main>
|
||||
<SettingsProvider>
|
||||
<div id="canvasContainer">
|
||||
{showLoadingIndicator && (
|
||||
<div id="loadingIndicator" data-complete={!isLoading}>
|
||||
<div className="LoadingSpinner" />
|
||||
<div className="LoadingProgress">
|
||||
<div
|
||||
className="LoadingProgress-bar"
|
||||
style={{ width: `${loadingProgress * 100}%` }}
|
||||
/>
|
||||
</div>
|
||||
<div className="LoadingProgress-text">
|
||||
{Math.round(loadingProgress * 100)}%
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<Canvas
|
||||
frameloop="always"
|
||||
gl={glSettings}
|
||||
shadows={{ type: PCFShadowMap }}
|
||||
onCreated={(state) => {
|
||||
cameraRef.current = state.camera;
|
||||
}}
|
||||
>
|
||||
<CamerasProvider>
|
||||
<AudioProvider>
|
||||
<Mission
|
||||
key={`${missionName}~${missionType}`}
|
||||
name={missionName}
|
||||
missionType={missionType}
|
||||
onLoadingChange={handleLoadingChange}
|
||||
/>
|
||||
<ObserverCamera />
|
||||
<DebugElements />
|
||||
{isTouch === null ? null : isTouch ? (
|
||||
<TouchCameraMovement
|
||||
joystickState={joystickStateRef}
|
||||
joystickZone={joystickZoneRef}
|
||||
lookJoystickState={lookJoystickStateRef}
|
||||
lookJoystickZone={lookJoystickZoneRef}
|
||||
<KeyboardControls map={KEYBOARD_CONTROLS}>
|
||||
<div id="canvasContainer">
|
||||
{showLoadingIndicator && (
|
||||
<div id="loadingIndicator" data-complete={!isLoading}>
|
||||
<div className="LoadingSpinner" />
|
||||
<div className="LoadingProgress">
|
||||
<div
|
||||
className="LoadingProgress-bar"
|
||||
style={{ width: `${loadingProgress * 100}%` }}
|
||||
/>
|
||||
) : (
|
||||
<ObserverControls />
|
||||
)}
|
||||
</AudioProvider>
|
||||
</CamerasProvider>
|
||||
</Canvas>
|
||||
</div>
|
||||
{isTouch && (
|
||||
<TouchJoystick
|
||||
joystickState={joystickStateRef}
|
||||
joystickZone={joystickZoneRef}
|
||||
lookJoystickState={lookJoystickStateRef}
|
||||
lookJoystickZone={lookJoystickZoneRef}
|
||||
</div>
|
||||
<div className="LoadingProgress-text">
|
||||
{Math.round(loadingProgress * 100)}%
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<Canvas
|
||||
frameloop="always"
|
||||
gl={glSettings}
|
||||
shadows={{ type: PCFShadowMap }}
|
||||
onCreated={(state) => {
|
||||
cameraRef.current = state.camera;
|
||||
}}
|
||||
>
|
||||
<CamerasProvider>
|
||||
<AudioProvider>
|
||||
<Mission
|
||||
key={`${missionName}~${missionType}`}
|
||||
name={missionName}
|
||||
missionType={missionType}
|
||||
onLoadingChange={handleLoadingChange}
|
||||
/>
|
||||
<ObserverCamera />
|
||||
<DebugElements />
|
||||
{isTouch === null ? null : isTouch ? (
|
||||
<TouchCameraMovement
|
||||
joystickState={joystickStateRef}
|
||||
joystickZone={joystickZoneRef}
|
||||
lookJoystickState={lookJoystickStateRef}
|
||||
lookJoystickZone={lookJoystickZoneRef}
|
||||
/>
|
||||
) : (
|
||||
<ObserverControls />
|
||||
)}
|
||||
</AudioProvider>
|
||||
</CamerasProvider>
|
||||
</Canvas>
|
||||
</div>
|
||||
{isTouch && (
|
||||
<TouchJoystick
|
||||
joystickState={joystickStateRef}
|
||||
joystickZone={joystickZoneRef}
|
||||
lookJoystickState={lookJoystickStateRef}
|
||||
lookJoystickZone={lookJoystickZoneRef}
|
||||
/>
|
||||
)}
|
||||
{isTouch === false && <KeyboardOverlay />}
|
||||
<InspectorControls
|
||||
missionName={missionName}
|
||||
missionType={missionType}
|
||||
onChangeMission={changeMission}
|
||||
cameraRef={cameraRef}
|
||||
isTouch={isTouch}
|
||||
/>
|
||||
)}
|
||||
<InspectorControls
|
||||
missionName={missionName}
|
||||
missionType={missionType}
|
||||
onChangeMission={changeMission}
|
||||
cameraRef={cameraRef}
|
||||
isTouch={isTouch}
|
||||
/>
|
||||
</KeyboardControls>
|
||||
</SettingsProvider>
|
||||
</main>
|
||||
</QueryClientProvider>
|
||||
|
|
|
|||
|
|
@ -513,6 +513,62 @@ input[type="range"] {
|
|||
}
|
||||
}
|
||||
|
||||
.KeyboardOverlay {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 10px;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.KeyboardOverlay-column {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.KeyboardOverlay-row {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
.KeyboardOverlay-spacer {
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.KeyboardOverlay-key {
|
||||
min-width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
flex: 1 0 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 8px;
|
||||
border-radius: 4px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.KeyboardOverlay-key[data-pressed="true"] {
|
||||
background: rgba(52, 187, 171, 0.6);
|
||||
border-color: rgba(35, 253, 220, 0.5);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.KeyboardOverlay-arrow {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.TouchJoystick {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue