Feat/env-manager #1
@@ -3,6 +3,7 @@ import { DebugOverlayLayout } from "@/components/ui/debug/DebugOverlayLayout";
|
|||||||
import { GameSettingsMenu } from "@/components/ui/GameSettingsMenu";
|
import { GameSettingsMenu } from "@/components/ui/GameSettingsMenu";
|
||||||
import { HandTrackingVisualizer } from "@/components/ui/HandTrackingVisualizer";
|
import { HandTrackingVisualizer } from "@/components/ui/HandTrackingVisualizer";
|
||||||
import { InteractPrompt } from "@/components/ui/InteractPrompt";
|
import { InteractPrompt } from "@/components/ui/InteractPrompt";
|
||||||
|
import { Subtitles } from "@/components/ui/Subtitles";
|
||||||
|
|
||||||
export function GameUI(): React.JSX.Element {
|
export function GameUI(): React.JSX.Element {
|
||||||
return (
|
return (
|
||||||
@@ -11,6 +12,7 @@ export function GameUI(): React.JSX.Element {
|
|||||||
<Crosshair />
|
<Crosshair />
|
||||||
<InteractPrompt />
|
<InteractPrompt />
|
||||||
<HandTrackingVisualizer />
|
<HandTrackingVisualizer />
|
||||||
|
<Subtitles />
|
||||||
<GameSettingsMenu />
|
<GameSettingsMenu />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { useSettingsStore } from "@/managers/stores/useSettingsStore";
|
||||||
|
|
||||||
|
export type SubtitleSpeaker = "Narrateur" | "Fermier" | "Leonie";
|
||||||
|
|
||||||
|
interface SubtitlesProps {
|
||||||
|
speaker?: SubtitleSpeaker | null;
|
||||||
|
text?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Subtitles({
|
||||||
|
speaker = null,
|
||||||
|
text = null,
|
||||||
|
}: SubtitlesProps): React.JSX.Element | null {
|
||||||
|
const subtitlesEnabled = useSettingsStore((state) => state.subtitlesEnabled);
|
||||||
|
const content = text?.trim();
|
||||||
|
|
||||||
|
if (!subtitlesEnabled || !content) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="subtitles" aria-live="polite">
|
||||||
|
<p>
|
||||||
|
{speaker ? (
|
||||||
|
<span
|
||||||
|
className={`subtitles__speaker subtitles__speaker--${speaker.toLowerCase()}`}
|
||||||
|
>
|
||||||
|
{speaker}:
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
{content}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -397,6 +397,47 @@ canvas {
|
|||||||
letter-spacing: 0.03em;
|
letter-spacing: 0.03em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Subtitles */
|
||||||
|
.subtitles {
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
bottom: 7vh;
|
||||||
|
z-index: 15;
|
||||||
|
width: min(780px, calc(100vw - 32px));
|
||||||
|
transform: translateX(-50%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitles p {
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: rgba(0, 0, 0, 0.82);
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: clamp(1rem, 2vw, 1.25rem);
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 1.45;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitles__speaker {
|
||||||
|
margin-right: 0.35em;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitles__speaker--narrateur {
|
||||||
|
color: #7dd3fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitles__speaker--fermier {
|
||||||
|
color: #86efac;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitles__speaker--leonie {
|
||||||
|
color: #f9a8d4;
|
||||||
|
}
|
||||||
|
|
||||||
/* In-game settings menu */
|
/* In-game settings menu */
|
||||||
.game-settings-menu {
|
.game-settings-menu {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
Reference in New Issue
Block a user