diff --git a/src/app/tools/tankopedia/[id]/components/Control.tsx b/src/app/tools/tankopedia/[id]/components/Control.tsx index 30e687573..22dc7afbe 100644 --- a/src/app/tools/tankopedia/[id]/components/Control.tsx +++ b/src/app/tools/tankopedia/[id]/components/Control.tsx @@ -14,5 +14,7 @@ export function Controls() { orbitControls.current?.target.set(0, 1.5, 0); }, []); - return ; + return ( + + ); } diff --git a/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx b/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx new file mode 100644 index 000000000..5d0e18171 --- /dev/null +++ b/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx @@ -0,0 +1,168 @@ +import { + EnterFullScreenIcon, + ExitFullScreenIcon, + FrameIcon, +} from '@radix-ui/react-icons'; +import { Button, Card, Flex, Tabs, Theme } from '@radix-ui/themes'; +import { Html } from '@react-three/drei'; +import { Canvas } from '@react-three/fiber'; +import { Suspense, useEffect, useRef, useState } from 'react'; +import { Group } from 'three'; +import { theme } from '../../../../../../stitches.config'; +import mutateTankopedia, { + TankopediaMode, + useTankopedia, +} from '../../../../../../stores/tankopedia'; +import { Loader } from '../../../../components/Loader'; +import { Controls } from '../Control'; +import { RotationInputs } from '../RotationInputs'; +import { SceneProps } from '../SceneProps'; +import { TankModel } from './components/TankModel'; + +interface TankDisplayProps { + tankId: number; + turretId: number; + gunId: number; +} + +export function TankDisplay({ tankId, turretId, gunId }: TankDisplayProps) { + const canvas = useRef(null); + const canvasWrapper = useRef(null); + const [isFullScreen, setIsFullScreen] = useState(false); + const mode = useTankopedia((state) => state.mode); + const hullContainer = useRef(null); + const showGrid = useTankopedia((state) => state.model.showGrid); + + function handlePointerDown() { + window.addEventListener('pointermove', handlePointerMove); + window.addEventListener('pointerup', handlePointerUp); + } + function handlePointerMove(event: PointerEvent) { + event.preventDefault(); + } + function handlePointerUp(event: PointerEvent) { + event.preventDefault(); + + window.removeEventListener('pointermove', handlePointerMove); + window.removeEventListener('pointerup', handlePointerUp); + } + + useEffect(() => { + function handleFullScreenChange() { + setIsFullScreen(document.fullscreenElement !== null); + } + + document.addEventListener('fullscreenchange', handleFullScreenChange); + + return () => { + document.removeEventListener('fullscreenchange', handleFullScreenChange); + }; + }); + + return ( + + + + + { + mutateTankopedia((draft) => { + draft.mode = mode as TankopediaMode; + }); + }} + > + + Model + Armor + + + +
+ + + + + + + + } + > + + + +
+ + + + + + + + +
+
+
+
+ ); +} diff --git a/src/app/tools/tankopedia/[id]/components/TankModel.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx similarity index 93% rename from src/app/tools/tankopedia/[id]/components/TankModel.tsx rename to src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx index 21a865932..34eb598f3 100644 --- a/src/app/tools/tankopedia/[id]/components/TankModel.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel.tsx @@ -8,17 +8,17 @@ import { } from 'react'; import { Group, Vector3 } from 'three'; import { GLTFLoader } from 'three-stdlib'; -import { X_AXIS } from '../../../../../constants/axis'; +import { X_AXIS } from '../../../../../../../constants/axis'; import { ModelDefinitions, modelDefinitions, -} from '../../../../../core/blitzkrieg/modelDefinitions'; +} from '../../../../../../../core/blitzkrieg/modelDefinitions'; import mutateTankopedia, { useTankopedia, -} from '../../../../../stores/tankopedia'; -import { GunContainer } from './GunContainer'; -import { HullContainer } from './HullContainer'; -import { TurretContainer } from './TurretContainer'; +} from '../../../../../../../stores/tankopedia'; +import { GunContainer } from '../../GunContainer'; +import { HullContainer } from '../../HullContainer'; +import { TurretContainer } from '../../TurretContainer'; interface TankModelProps { tankId: number; diff --git a/src/app/tools/tankopedia/[id]/components/SceneProps.tsx b/src/app/tools/tankopedia/[id]/components/SceneProps.tsx index 40d3a7d03..b5d183ae8 100644 --- a/src/app/tools/tankopedia/[id]/components/SceneProps.tsx +++ b/src/app/tools/tankopedia/[id]/components/SceneProps.tsx @@ -1,22 +1,29 @@ import { Color } from 'three'; import InfiniteGridHelper from '../../../../../components/InfiniteGridHelper'; +import { useTankopedia } from '../../../../../stores/tankopedia'; export function SceneProps() { + const showGrid = useTankopedia((state) => state.model.showGrid); + return ( <> - - + {showGrid && ( + <> + + + + )} (null); - const hullContainer = useRef(null); const [versusTankSearchResults, setVersusTankSearchResults] = useState< number[] >([]); @@ -66,35 +53,7 @@ export default function Page({ params }: { params: { id: string } }) { const [versusTurret, setVersusTurret] = useState(versusTank.turrets.at(-1)!); const [versusGun, setVersusGun] = useState(versusTurret.guns.at(-1)!); const [versusTankTab, setVersusTankTab] = useState('search'); - const canvas = useRef(null); - const canvasWrapper = useRef(null); - const [isFullScreen, setIsFullScreen] = useState(false); - - function handlePointerDown() { - window.addEventListener('pointermove', handlePointerMove); - window.addEventListener('pointerup', handlePointerUp); - } - function handlePointerMove(event: PointerEvent) { - event.preventDefault(); - } - function handlePointerUp(event: PointerEvent) { - event.preventDefault(); - - window.removeEventListener('pointermove', handlePointerMove); - window.removeEventListener('pointerup', handlePointerUp); - } - - useEffect(() => { - function handleFullScreenChange() { - setIsFullScreen(document.fullscreenElement !== null); - } - - document.addEventListener('fullscreenchange', handleFullScreenChange); - - return () => { - document.removeEventListener('fullscreenchange', handleFullScreenChange); - }; - }); + const mode = useTankopedia((state) => state.mode); return ( @@ -117,153 +76,7 @@ export default function Page({ params }: { params: { id: string } }) { - - - - - - - Model - Armor - - - -
- - - - - - - - } - > - - - -
- - - - - - - - -
-
-
-
- - - - - {tank.turrets.map((thisTurret) => { - return ( - - - - ); - })} - - - - {turret.guns.map((thisGun) => { - return ( - - - - ); - })} - - - + {mode === 'armor' && ( @@ -464,7 +277,7 @@ export default function Page({ params }: { params: { id: string } }) { - Calibrated shells + Calibrated @@ -493,44 +306,53 @@ export default function Page({ params }: { params: { id: string } }) { )} - - - Build + + + + {tank.turrets.map((thisTurret) => { + return ( + + + + ); + })} + - - - Modules - - - - - - Crew - - - - {crew}% - - setCrew(crew)} - /> + + {turret.guns.map((thisGun) => { + return ( + + + + ); + })} + - - - - - Shells - - {gun.shells.map((shell) => ( - - {shell.name} ({shell.type}): {shell.damage.armor} - - ))} +
diff --git a/src/stores/tankopedia.ts b/src/stores/tankopedia.ts index 632e34f4c..339f981a5 100644 --- a/src/stores/tankopedia.ts +++ b/src/stores/tankopedia.ts @@ -6,6 +6,7 @@ import { Tier } from '../core/blitzkrieg/tankDefinitions'; export type TankopediaSortBy = 'tier' | 'name'; export type TankopediaSortDirection = 'ascending' | 'descending'; export type TankopediaTestTankDisplay = 'include' | 'exclude' | 'only'; +export type TankopediaMode = 'model' | 'armor'; type Tankopedia = { sort: { @@ -24,8 +25,9 @@ type Tankopedia = { turretYaw: number; gunPitch: number; controlsEnabled: boolean; + showGrid: boolean; }; - showSettings: boolean; + mode: TankopediaMode; }; export const useTankopedia = create()(() => ({ @@ -45,8 +47,9 @@ export const useTankopedia = create()(() => ({ hullYaw: 0, turretYaw: 0, controlsEnabled: true, + showGrid: true, }, - showSettings: false, + mode: 'model', })); export default function mutateTankopedia(recipe: (draft: Tankopedia) => void) {