mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
feat: more ui
This commit is contained in:
1 parent
dcc3ab6e4e
commit
8a2dc24f7e
3 files changed
+197
-42
No files matched your search
@@ -1,12 +1,32 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Button, Flex, Heading } from '@radix-ui/themes';
|
import { ArrowLeftIcon } from '@radix-ui/react-icons';
|
||||||
|
import {
|
||||||
|
AspectRatio,
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Checkbox,
|
||||||
|
Flex,
|
||||||
|
Heading,
|
||||||
|
Inset,
|
||||||
|
Select,
|
||||||
|
Slider,
|
||||||
|
Text,
|
||||||
|
Theme,
|
||||||
|
Tooltip,
|
||||||
|
} from '@radix-ui/themes';
|
||||||
|
import { OrbitControls } from '@react-three/drei';
|
||||||
|
import { Canvas } from '@react-three/fiber';
|
||||||
|
import Link from 'next/link';
|
||||||
import { use, useEffect, useState } from 'react';
|
import { use, useEffect, useState } from 'react';
|
||||||
import { Flag } from '../../../../components/Flag';
|
import { Flag } from '../../../../components/Flag';
|
||||||
import PageWrapper from '../../../../components/PageWrapper';
|
import PageWrapper from '../../../../components/PageWrapper';
|
||||||
import { gunDefinitions } from '../../../../core/blitzkrieg/definitions/guns';
|
import { gunDefinitions } from '../../../../core/blitzkrieg/definitions/guns';
|
||||||
import { shellDefinitions } from '../../../../core/blitzkrieg/definitions/shells';
|
import { shellDefinitions } from '../../../../core/blitzkrieg/definitions/shells';
|
||||||
import { tankDefinitions } from '../../../../core/blitzkrieg/definitions/tanks';
|
import {
|
||||||
|
TIER_ROMAN_NUMERALS,
|
||||||
|
tankDefinitions,
|
||||||
|
} from '../../../../core/blitzkrieg/definitions/tanks';
|
||||||
import { turretDefinitions } from '../../../../core/blitzkrieg/definitions/turrets';
|
import { turretDefinitions } from '../../../../core/blitzkrieg/definitions/turrets';
|
||||||
|
|
||||||
const SIZE = 0.05;
|
const SIZE = 0.05;
|
||||||
@@ -22,55 +42,188 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
awaitedTurretDefinitions[tank.turrets[0]],
|
awaitedTurretDefinitions[tank.turrets[0]],
|
||||||
);
|
);
|
||||||
const [gun, setGun] = useState(awaitedGunDefinitions[turret.guns[0]]);
|
const [gun, setGun] = useState(awaitedGunDefinitions[turret.guns[0]]);
|
||||||
const [shell, setShell] = useState(awaitedShellDefinitions[gun.shells[0]]);
|
const [crew, setCrew] = useState(100);
|
||||||
|
|
||||||
useEffect(() => setGun(awaitedGunDefinitions[turret.guns[0]]), [turret]);
|
useEffect(() => setGun(awaitedGunDefinitions[turret.guns[0]]), [turret]);
|
||||||
useEffect(() => setShell(awaitedShellDefinitions[gun.shells[0]]), [gun]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageWrapper>
|
<PageWrapper>
|
||||||
<Flex gap="2" align="center">
|
<Flex gap="8" direction="column">
|
||||||
<Flag nation={tank.nation} />
|
<Flex gap="4" direction="column">
|
||||||
<Heading>{tank.name}</Heading>
|
<Flex justify="between" align="center">
|
||||||
</Flex>
|
<Link
|
||||||
|
href="/tools/tankopedia"
|
||||||
|
style={{ color: 'unset', textDecoration: 'none' }}
|
||||||
|
>
|
||||||
|
<Flex gap="1" align="center">
|
||||||
|
<ArrowLeftIcon />
|
||||||
|
<Text>Back to tankopedia</Text>
|
||||||
|
</Flex>
|
||||||
|
</Link>
|
||||||
|
|
||||||
<Flex gap="2" align="center">
|
<Flex gap="2" align="center">
|
||||||
<Heading size="5">Turrets</Heading>
|
<Heading>{tank.name}</Heading>
|
||||||
|
<Flag nation={tank.nation} />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
{tank.turrets.map((turretId) => (
|
<AspectRatio ratio={16 / 9}>
|
||||||
<Button
|
<Card
|
||||||
onClick={() => setTurret(awaitedTurretDefinitions[turretId])}
|
style={{ width: '100%', height: '100%', position: 'relative' }}
|
||||||
variant={turret.id === turretId ? 'solid' : 'soft'}
|
>
|
||||||
>
|
<Inset style={{ height: 'calc(100% + 24px)' }}>
|
||||||
{awaitedTurretDefinitions[turretId].name}
|
<Canvas onPointerDown={(event) => event.preventDefault()}>
|
||||||
</Button>
|
<OrbitControls />
|
||||||
))}
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex gap="2" align="center">
|
<ambientLight />
|
||||||
<Heading size="5">Guns</Heading>
|
<directionalLight />
|
||||||
|
|
||||||
{turret.guns.map((gunId) => (
|
<mesh>
|
||||||
<Button
|
<torusKnotGeometry args={[undefined, undefined, 128, 16]} />
|
||||||
onClick={() => setGun(awaitedGunDefinitions[gunId])}
|
<meshStandardMaterial color="red" />
|
||||||
variant={gun.id === gunId ? 'solid' : 'soft'}
|
</mesh>
|
||||||
>
|
</Canvas>
|
||||||
{awaitedTurretDefinitions[gunId]?.name ?? gunId}
|
</Inset>
|
||||||
</Button>
|
|
||||||
))}
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex gap="2" align="center">
|
<Flex
|
||||||
<Heading size="5">Shells</Heading>
|
gap="2"
|
||||||
|
align="center"
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
left: 16,
|
||||||
|
bottom: 16,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Checkbox defaultChecked />
|
||||||
|
<Text>Enhanced armor</Text>
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
</AspectRatio>
|
||||||
|
|
||||||
{gun.shells.map((shellId) => (
|
<Card style={{}}>
|
||||||
<Button
|
<Flex align="center" justify="between" gap="2">
|
||||||
onClick={() => setShell(awaitedShellDefinitions[shellId])}
|
<Flex align="center" gap="4">
|
||||||
variant={shell.id === shellId ? 'solid' : 'soft'}
|
<Text>Versus</Text>
|
||||||
>
|
|
||||||
{awaitedShellDefinitions[shellId].name}
|
<Select.Root value="1">
|
||||||
</Button>
|
<Select.Trigger variant="ghost" />
|
||||||
))}
|
|
||||||
|
<Select.Content>
|
||||||
|
<Select.Item value="1">XM66F</Select.Item>
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex gap="2" align="center">
|
||||||
|
<Checkbox defaultChecked />
|
||||||
|
<Text>Calibrated shells</Text>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex gap="1">
|
||||||
|
<Button variant="solid" radius="small">
|
||||||
|
<img src="/images/ammo/ap.png" width={24} height={24} />
|
||||||
|
</Button>
|
||||||
|
<Button variant="soft" radius="small" color="gray">
|
||||||
|
<img src="/images/ammo/hcp.png" width={24} height={24} />
|
||||||
|
</Button>
|
||||||
|
<Button variant="soft" radius="small" color="gray">
|
||||||
|
<img src="/images/ammo/he.png" width={24} height={24} />
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex gap="6" direction="column">
|
||||||
|
<Heading>Build</Heading>
|
||||||
|
|
||||||
|
<Flex gap="2" direction="column">
|
||||||
|
<Heading size="5" weight="regular">
|
||||||
|
Modules
|
||||||
|
</Heading>
|
||||||
|
<Theme radius="small">
|
||||||
|
<Flex gap="4">
|
||||||
|
<Flex gap="1">
|
||||||
|
{tank.turrets.map((turretId) => {
|
||||||
|
const thisTurret = awaitedTurretDefinitions[turretId];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip content={thisTurret.name}>
|
||||||
|
<Button
|
||||||
|
onClick={() => setTurret(thisTurret)}
|
||||||
|
variant={
|
||||||
|
turret.id === thisTurret.id ? 'solid' : 'soft'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/images/modules/turret.png"
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
|
/>
|
||||||
|
{TIER_ROMAN_NUMERALS[thisTurret.tier]}
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex gap="1">
|
||||||
|
{turret.guns.map((gunId, index) => {
|
||||||
|
const thisGun = awaitedGunDefinitions[gunId];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip content={thisGun.name}>
|
||||||
|
<Button
|
||||||
|
onClick={() => setGun(thisGun)}
|
||||||
|
variant={gun.id === thisGun.id ? 'solid' : 'soft'}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/images/modules/gun.png"
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
|
/>
|
||||||
|
{TIER_ROMAN_NUMERALS[thisGun.tier]}
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Theme>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex gap="2" direction="column">
|
||||||
|
<Heading size="5" weight="regular">
|
||||||
|
Crew
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
<Flex gap="4" align="center">
|
||||||
|
<Text>{crew}%</Text>
|
||||||
|
|
||||||
|
<Slider
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
value={[crew]}
|
||||||
|
min={50}
|
||||||
|
max={100}
|
||||||
|
onValueChange={([crew]) => setCrew(crew)}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex gap="2" direction="column">
|
||||||
|
<Heading size="5">Shells</Heading>
|
||||||
|
|
||||||
|
{gun.shells.map((shellId) => {
|
||||||
|
const shell = awaitedShellDefinitions[shellId];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Text>
|
||||||
|
{shell.name} ({shell.type}): {shell.damage.armor}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</PageWrapper>
|
</PageWrapper>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { asset } from '../asset';
|
import { asset } from '../asset';
|
||||||
|
import { Tier } from './tanks';
|
||||||
|
|
||||||
export interface BlitzkriegGunDefinition {
|
export interface BlitzkriegGunDefinition {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
tier: number;
|
tier: Tier;
|
||||||
pitch: [number, number];
|
pitch: [number, number];
|
||||||
shells: number[];
|
shells: number[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { asset } from '../asset';
|
import { asset } from '../asset';
|
||||||
|
import { Tier } from './tanks';
|
||||||
|
|
||||||
export interface BlitzkriegTurretDefinition {
|
export interface BlitzkriegTurretDefinition {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
tier: number;
|
tier: Tier;
|
||||||
yaw: [number, number];
|
yaw: [number, number];
|
||||||
guns: number[];
|
guns: number[];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user