feat: requestedDisplay

This commit is contained in:
TrèsAbhi committed 2025-11-27 13:20:06 -06:00
1 parent 344e7caa81
commit cd4fa366a0
5 files changed
+30 -20

No files matched your search

@@ -15,7 +15,7 @@ type ThicknessesProps = MaybeSkeletonComponentProps & {
}; };
export function Thicknesses({ thicknessRange, skeleton }: ThicknessesProps) { export function Thicknesses({ thicknessRange, skeleton }: ThicknessesProps) {
const display = Tankopedia.use((state) => state.requestedDisplay); const display = Tankopedia.use((state) => state.display);
const showExternalModules = TankopediaPersistent.use( const showExternalModules = TankopediaPersistent.use(
(state) => state.showExternalModules (state) => state.showExternalModules
); );
@@ -56,7 +56,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
const hasCustomShell = Tankopedia.use( const hasCustomShell = Tankopedia.use(
(state) => state.customShell !== undefined (state) => state.customShell !== undefined
); );
const display = Tankopedia.use((state) => state.requestedDisplay); const requestedDisplay = Tankopedia.use((state) => state.requestedDisplay);
const isFullScreen = useFullScreen(); const isFullScreen = useFullScreen();
const advancedHighlighting = TankopediaPersistent.use( const advancedHighlighting = TankopediaPersistent.use(
(state) => state.advancedHighlighting (state) => state.advancedHighlighting
@@ -86,7 +86,9 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
gap="2" gap="2"
direction="column" direction="column"
top="50%" top="50%"
right={display === TankopediaDisplay.DynamicArmor ? "3" : "-4rem"} right={
requestedDisplay === TankopediaDisplay.DynamicArmor ? "3" : "-4rem"
}
style={{ style={{
position: "absolute", position: "absolute",
transform: "translateY(-50%)", transform: "translateY(-50%)",
@@ -298,7 +300,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
> >
{disturbed && ( {disturbed && (
<> <>
{display === TankopediaDisplay.DynamicArmor && ( {requestedDisplay === TankopediaDisplay.DynamicArmor && (
<IconButton <IconButton
size="2" size="2"
highContrast highContrast
@@ -400,7 +402,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
<Flex gap="3" align="center" mt="2"> <Flex gap="3" align="center" mt="2">
<SegmentedControl.Root <SegmentedControl.Root
variant="classic" variant="classic"
value={`${disturbed ? display : -1}`} value={`${disturbed ? requestedDisplay : -1}`}
onValueChange={(value) => { onValueChange={(value) => {
Tankopedia.mutate((draft) => { Tankopedia.mutate((draft) => {
draft.disturbed = true; draft.disturbed = true;
@@ -446,7 +448,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
</SegmentedControl.Item> </SegmentedControl.Item>
</SegmentedControl.Root> </SegmentedControl.Root>
{display === TankopediaDisplay.DynamicArmor && ( {requestedDisplay === TankopediaDisplay.DynamicArmor && (
<Dialog.Root <Dialog.Root
open={antagonistSelectorOpen} open={antagonistSelectorOpen}
onOpenChange={setAntagonistSelectorOpen} onOpenChange={setAntagonistSelectorOpen}
@@ -7,21 +7,22 @@ import { Tankopedia } from "../../../../../../stores/tankopedia";
import { TankopediaPersistent } from "../../../../../../stores/tankopediaPersistent"; import { TankopediaPersistent } from "../../../../../../stores/tankopediaPersistent";
import { HelpingSpotLight } from "../../../../../HelpingSpotLight"; import { HelpingSpotLight } from "../../../../../HelpingSpotLight";
const ANGLE = Math.PI / 3; const ANGLE = Math.PI * 2 ** -2;
const REVEAL_ANIMATION_TIME = 3; const REVEAL_ANIMATION_TIME = 3;
const TRANSITION_ANIMATION_TIME = 0.5; const TRANSITION_ANIMATION_TIME = 0.5;
const LIGHTS_COUNT = 4; const LIGHTS_COUNT = 4;
const THETA_OFFSET = degToRad(-150); const THETA_OFFSET = degToRad(-150);
const LIGHT_DISTANCE = 13; const LIGHT_DISTANCE = 13;
const LIGHT_HEIGHT_0 = 4; const LIGHT_HEIGHT_0 = 5;
const LIGHT_HEIGHT_1 = 8; const LIGHT_HEIGHT_1 = 10;
const INTENSITY_0 = 70; const INTENSITY_0 = 60;
const INTENSITY_1 = 40; const INTENSITY_1 = 30;
export function Lighting() { export function Lighting() {
const wrapper = useRef<Group>(null!); const wrapper = useRef<Group>(null!);
const t0 = useRef(0); const t0 = useRef(0);
const transition = useRef(false);
const clock = useThree((state) => state.clock); const clock = useThree((state) => state.clock);
const display = Tankopedia.use((state) => state.display); const display = Tankopedia.use((state) => state.display);
const requestedDisplay = Tankopedia.use((state) => state.requestedDisplay); const requestedDisplay = Tankopedia.use((state) => state.requestedDisplay);
@@ -36,13 +37,18 @@ export function Lighting() {
t0.current = clock.elapsedTime - REVEAL_ANIMATION_TIME; t0.current = clock.elapsedTime - REVEAL_ANIMATION_TIME;
}, []); }, []);
useFrame(({ clock, invalidate }) => { useFrame(({ invalidate }) => {
if (transition.current) {
transition.current = false;
t0.current = clock.elapsedTime;
}
const x = clamp( const x = clamp(
(clock.elapsedTime - t0.current) / animationTime.current, (clock.elapsedTime - t0.current) / animationTime.current,
0, 0,
2 2
); );
const t = 0.5 * Math.sin(Math.PI * (x + 0.5)) + 0.5; const t = (0.5 * Math.sin(Math.PI * (x + 0.5)) + 0.5) ** 2;
for (const child of wrapper.current.children) { for (const child of wrapper.current.children) {
if (child instanceof SpotLight) { if (child instanceof SpotLight) {
@@ -52,7 +58,10 @@ export function Lighting() {
if (x < 2) invalidate(); if (x < 2) invalidate();
if (x === 2 && display !== requestedDisplay) { if (
x > 1 &&
Tankopedia.state.display !== Tankopedia.state.requestedDisplay
) {
Tankopedia.mutate((draft) => { Tankopedia.mutate((draft) => {
draft.display = requestedDisplay; draft.display = requestedDisplay;
}); });
@@ -62,7 +71,7 @@ export function Lighting() {
useEffect(() => { useEffect(() => {
if (requestedDisplay === display) return; if (requestedDisplay === display) return;
t0.current = clock.elapsedTime; transition.current = true;
animationTime.current = TRANSITION_ANIMATION_TIME; animationTime.current = TRANSITION_ANIMATION_TIME;
}, [requestedDisplay]); }, [requestedDisplay]);
@@ -59,10 +59,7 @@ export function TankModel() {
} }
function onPointerDown(event: ThreeEvent<PointerEvent>) { function onPointerDown(event: ThreeEvent<PointerEvent>) {
if ( if (isTrack && Tankopedia.state.display === TankopediaDisplay.Model) {
isTrack &&
Tankopedia.state.requestedDisplay === TankopediaDisplay.Model
) {
position.set(event.clientX, event.clientY); position.set(event.clientX, event.clientY);
event.stopPropagation(); event.stopPropagation();
@@ -47,7 +47,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
const turretModelDefinition = const turretModelDefinition =
tankModelDefinition.turrets[protagonistTurret.id]; tankModelDefinition.turrets[protagonistTurret.id];
const gunModelDefinition = turretModelDefinition.guns[protagonistGun.id]; const gunModelDefinition = turretModelDefinition.guns[protagonistGun.id];
const display = Tankopedia.use((state) => state.requestedDisplay); const display = Tankopedia.use((state) => state.display);
const hideTankModelUnderArmor = TankopediaPersistent.use( const hideTankModelUnderArmor = TankopediaPersistent.use(
(state) => state.hideTankModelUnderArmor (state) => state.hideTankModelUnderArmor
); );
@@ -148,6 +148,8 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
} }
}, [display]); }, [display]);
console.log(TankopediaDisplay[display]);
return ( return (
<SmartCanvas <SmartCanvas
ref={canvas} ref={canvas}