mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: fullscreen
This commit is contained in:
1 parent
f9c182e68c
commit
d2e7a477bb
2 files changed
+191
-167
No files matched your search
+188
-158
@@ -90,6 +90,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
|||||||
const mutateTankopediaPersistent = TankopediaPersistent.useMutation();
|
const mutateTankopediaPersistent = TankopediaPersistent.useMutation();
|
||||||
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
|
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
|
||||||
const { strings, unwrap } = useLocale();
|
const { strings, unwrap } = useLocale();
|
||||||
|
const revealed = TankopediaEphemeral.use((state) => state.revealed);
|
||||||
const disturbed = TankopediaEphemeral.use((state) => state.disturbed);
|
const disturbed = TankopediaEphemeral.use((state) => state.disturbed);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -324,7 +325,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
|||||||
direction="column"
|
direction="column"
|
||||||
align="center"
|
align="center"
|
||||||
position="absolute"
|
position="absolute"
|
||||||
bottom={disturbed ? '4' : '-100%'}
|
bottom={revealed ? '4' : '-100%'}
|
||||||
left="50%"
|
left="50%"
|
||||||
style={{ transform: 'translateX(-50%)', transitionDuration: '200ms' }}
|
style={{ transform: 'translateX(-50%)', transitionDuration: '200ms' }}
|
||||||
>
|
>
|
||||||
@@ -401,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
|
||||||
value={`${display}`}
|
value={`${disturbed ? display : -1}`}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
mutateTankopediaEphemeral((draft) => {
|
mutateTankopediaEphemeral((draft) => {
|
||||||
draft.disturbed = true;
|
draft.disturbed = true;
|
||||||
@@ -455,185 +456,214 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
|||||||
</SegmentedControl.Item> */}
|
</SegmentedControl.Item> */}
|
||||||
</SegmentedControl.Root>
|
</SegmentedControl.Root>
|
||||||
|
|
||||||
<DropdownMenu.Root>
|
{disturbed && (
|
||||||
<DropdownMenu.Trigger>
|
<>
|
||||||
<IconButton variant="ghost" color="gray">
|
<DropdownMenu.Root>
|
||||||
<EyeOpenIcon />
|
<DropdownMenu.Trigger>
|
||||||
</IconButton>
|
<IconButton variant="ghost" color="gray">
|
||||||
</DropdownMenu.Trigger>
|
<EyeOpenIcon />
|
||||||
|
</IconButton>
|
||||||
|
</DropdownMenu.Trigger>
|
||||||
|
|
||||||
<DropdownMenu.Content>
|
<DropdownMenu.Content>
|
||||||
<DropdownMenu.Item onClick={() => poseEvent.emit(Pose.HullDown)}>
|
<DropdownMenu.Item
|
||||||
{strings.website.tools.tankopedia.sandbox.poses.hull_down}
|
onClick={() => poseEvent.emit(Pose.HullDown)}
|
||||||
</DropdownMenu.Item>
|
>
|
||||||
|
{strings.website.tools.tankopedia.sandbox.poses.hull_down}
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
|
||||||
<DropdownMenu.Item onClick={() => poseEvent.emit(Pose.FaceHug)}>
|
<DropdownMenu.Item
|
||||||
{strings.website.tools.tankopedia.sandbox.poses.face_hug}
|
onClick={() => poseEvent.emit(Pose.FaceHug)}
|
||||||
</DropdownMenu.Item>
|
>
|
||||||
|
{strings.website.tools.tankopedia.sandbox.poses.face_hug}
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
|
||||||
<DropdownMenu.Item onClick={() => poseEvent.emit(Pose.Default)}>
|
<DropdownMenu.Item
|
||||||
{strings.website.tools.tankopedia.sandbox.poses.default}
|
onClick={() => poseEvent.emit(Pose.Default)}
|
||||||
</DropdownMenu.Item>
|
>
|
||||||
</DropdownMenu.Content>
|
{strings.website.tools.tankopedia.sandbox.poses.default}
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Item>
|
||||||
|
</DropdownMenu.Content>
|
||||||
|
</DropdownMenu.Root>
|
||||||
|
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger>
|
<DropdownMenu.Trigger>
|
||||||
<IconButton variant="ghost" color="gray">
|
<IconButton variant="ghost" color="gray">
|
||||||
<GearIcon />
|
<GearIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</DropdownMenu.Trigger>
|
</DropdownMenu.Trigger>
|
||||||
|
|
||||||
|
<DropdownMenu.Content>
|
||||||
|
{display === TankopediaDisplay.DynamicArmor && (
|
||||||
|
<>
|
||||||
|
<DropdownMenu.Label>
|
||||||
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.settings
|
||||||
|
.armor
|
||||||
|
}
|
||||||
|
</DropdownMenu.Label>
|
||||||
|
|
||||||
|
<DropdownMenu.CheckboxItem
|
||||||
|
checked={greenPenetration}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
mutateTankopediaPersistent((draft) => {
|
||||||
|
draft.greenPenetration = checked;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.settings
|
||||||
|
.green_penetration
|
||||||
|
}
|
||||||
|
</DropdownMenu.CheckboxItem>
|
||||||
|
|
||||||
|
<DropdownMenu.CheckboxItem
|
||||||
|
checked={hideTankModelUnderArmor}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
mutateTankopediaPersistent((draft) => {
|
||||||
|
draft.hideTankModelUnderArmor = checked;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.settings
|
||||||
|
.hide_model_under_armor
|
||||||
|
}
|
||||||
|
</DropdownMenu.CheckboxItem>
|
||||||
|
|
||||||
|
<DropdownMenu.CheckboxItem
|
||||||
|
checked={opaque}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
mutateTankopediaPersistent((draft) => {
|
||||||
|
draft.opaque = checked;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.settings
|
||||||
|
.opaque
|
||||||
|
}
|
||||||
|
</DropdownMenu.CheckboxItem>
|
||||||
|
|
||||||
|
{developerMode && (
|
||||||
|
<DropdownMenu.CheckboxItem
|
||||||
|
checked={wireframe}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
mutateTankopediaPersistent((draft) => {
|
||||||
|
draft.wireframe = checked;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.settings
|
||||||
|
.dev_wireframe
|
||||||
|
}
|
||||||
|
</DropdownMenu.CheckboxItem>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<DropdownMenu.Content>
|
|
||||||
{display === TankopediaDisplay.DynamicArmor && (
|
|
||||||
<>
|
|
||||||
<DropdownMenu.Label>
|
<DropdownMenu.Label>
|
||||||
{strings.website.tools.tankopedia.sandbox.settings.armor}
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.settings
|
||||||
|
.environment
|
||||||
|
}
|
||||||
</DropdownMenu.Label>
|
</DropdownMenu.Label>
|
||||||
|
|
||||||
<DropdownMenu.CheckboxItem
|
<DropdownMenu.CheckboxItem
|
||||||
checked={greenPenetration}
|
checked={showGrid}
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
mutateTankopediaPersistent((draft) => {
|
mutateTankopediaPersistent((draft) => {
|
||||||
draft.greenPenetration = checked;
|
draft.showGrid = checked;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
strings.website.tools.tankopedia.sandbox.settings
|
strings.website.tools.tankopedia.sandbox.settings
|
||||||
.green_penetration
|
.show_grid
|
||||||
}
|
}
|
||||||
</DropdownMenu.CheckboxItem>
|
</DropdownMenu.CheckboxItem>
|
||||||
|
</DropdownMenu.Content>
|
||||||
|
</DropdownMenu.Root>
|
||||||
|
|
||||||
<DropdownMenu.CheckboxItem
|
<Popover.Root>
|
||||||
checked={hideTankModelUnderArmor}
|
<Popover.Trigger>
|
||||||
onCheckedChange={(checked) => {
|
<IconButton color="gray" variant="ghost">
|
||||||
mutateTankopediaPersistent((draft) => {
|
<CameraIcon />
|
||||||
draft.hideTankModelUnderArmor = checked;
|
</IconButton>
|
||||||
});
|
</Popover.Trigger>
|
||||||
}}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
strings.website.tools.tankopedia.sandbox.settings
|
|
||||||
.hide_model_under_armor
|
|
||||||
}
|
|
||||||
</DropdownMenu.CheckboxItem>
|
|
||||||
|
|
||||||
<DropdownMenu.CheckboxItem
|
<Popover.Content>
|
||||||
checked={opaque}
|
<Flex direction="column" gap="2">
|
||||||
onCheckedChange={(checked) => {
|
<Popover.Close>
|
||||||
mutateTankopediaPersistent((draft) => {
|
<Button
|
||||||
draft.opaque = checked;
|
onClick={() => {
|
||||||
});
|
if (!canvas.current) return;
|
||||||
}}
|
|
||||||
>
|
|
||||||
{strings.website.tools.tankopedia.sandbox.settings.opaque}
|
|
||||||
</DropdownMenu.CheckboxItem>
|
|
||||||
|
|
||||||
{developerMode && (
|
const anchor = document.createElement('a');
|
||||||
<DropdownMenu.CheckboxItem
|
|
||||||
checked={wireframe}
|
anchor.setAttribute(
|
||||||
onCheckedChange={(checked) => {
|
'download',
|
||||||
mutateTankopediaPersistent((draft) => {
|
`${protagonistTank.name}.png`,
|
||||||
draft.wireframe = checked;
|
);
|
||||||
});
|
anchor.setAttribute(
|
||||||
}}
|
'href',
|
||||||
>
|
canvas.current.toDataURL('image/png'),
|
||||||
{
|
);
|
||||||
strings.website.tools.tankopedia.sandbox.settings
|
anchor.click();
|
||||||
.dev_wireframe
|
}}
|
||||||
}
|
>
|
||||||
</DropdownMenu.CheckboxItem>
|
<DownloadIcon />
|
||||||
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.screenshot
|
||||||
|
.download
|
||||||
|
}
|
||||||
|
</Button>
|
||||||
|
</Popover.Close>
|
||||||
|
<Popover.Close>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => {
|
||||||
|
if (!canvas.current) return;
|
||||||
|
|
||||||
|
canvas.current.toBlob((blob) => {
|
||||||
|
if (!blob) return;
|
||||||
|
|
||||||
|
navigator.clipboard.write([
|
||||||
|
new ClipboardItem({ 'image/png': blob }),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CopyIcon />
|
||||||
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.screenshot
|
||||||
|
.copy
|
||||||
|
}
|
||||||
|
</Button>
|
||||||
|
</Popover.Close>
|
||||||
|
</Flex>
|
||||||
|
</Popover.Content>
|
||||||
|
</Popover.Root>
|
||||||
|
|
||||||
|
{fullScreenAvailable && (
|
||||||
|
<IconButton
|
||||||
|
color="gray"
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => {
|
||||||
|
if (isFullScreen) {
|
||||||
|
document.exitFullscreen();
|
||||||
|
} else document.body.requestFullscreen();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isFullScreen ? (
|
||||||
|
<ExitFullScreenIcon />
|
||||||
|
) : (
|
||||||
|
<EnterFullScreenIcon />
|
||||||
)}
|
)}
|
||||||
</>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
<DropdownMenu.Label>
|
|
||||||
{strings.website.tools.tankopedia.sandbox.settings.environment}
|
|
||||||
</DropdownMenu.Label>
|
|
||||||
|
|
||||||
<DropdownMenu.CheckboxItem
|
|
||||||
checked={showGrid}
|
|
||||||
onCheckedChange={(checked) => {
|
|
||||||
mutateTankopediaPersistent((draft) => {
|
|
||||||
draft.showGrid = checked;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{strings.website.tools.tankopedia.sandbox.settings.show_grid}
|
|
||||||
</DropdownMenu.CheckboxItem>
|
|
||||||
</DropdownMenu.Content>
|
|
||||||
</DropdownMenu.Root>
|
|
||||||
|
|
||||||
<Popover.Root>
|
|
||||||
<Popover.Trigger>
|
|
||||||
<IconButton color="gray" variant="ghost">
|
|
||||||
<CameraIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Popover.Trigger>
|
|
||||||
|
|
||||||
<Popover.Content>
|
|
||||||
<Flex direction="column" gap="2">
|
|
||||||
<Popover.Close>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
if (!canvas.current) return;
|
|
||||||
|
|
||||||
const anchor = document.createElement('a');
|
|
||||||
|
|
||||||
anchor.setAttribute(
|
|
||||||
'download',
|
|
||||||
`${protagonistTank.name}.png`,
|
|
||||||
);
|
|
||||||
anchor.setAttribute(
|
|
||||||
'href',
|
|
||||||
canvas.current.toDataURL('image/png'),
|
|
||||||
);
|
|
||||||
anchor.click();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DownloadIcon />
|
|
||||||
{
|
|
||||||
strings.website.tools.tankopedia.sandbox.screenshot
|
|
||||||
.download
|
|
||||||
}
|
|
||||||
</Button>
|
|
||||||
</Popover.Close>
|
|
||||||
<Popover.Close>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
onClick={() => {
|
|
||||||
if (!canvas.current) return;
|
|
||||||
|
|
||||||
canvas.current.toBlob((blob) => {
|
|
||||||
if (!blob) return;
|
|
||||||
|
|
||||||
navigator.clipboard.write([
|
|
||||||
new ClipboardItem({ 'image/png': blob }),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CopyIcon />
|
|
||||||
{strings.website.tools.tankopedia.sandbox.screenshot.copy}
|
|
||||||
</Button>
|
|
||||||
</Popover.Close>
|
|
||||||
</Flex>
|
|
||||||
</Popover.Content>
|
|
||||||
</Popover.Root>
|
|
||||||
|
|
||||||
{fullScreenAvailable && (
|
|
||||||
<IconButton
|
|
||||||
color="gray"
|
|
||||||
variant="ghost"
|
|
||||||
onClick={() => {
|
|
||||||
if (isFullScreen) {
|
|
||||||
document.exitFullscreen();
|
|
||||||
} else document.body.requestFullscreen();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{isFullScreen ? <ExitFullScreenIcon /> : <EnterFullScreenIcon />}
|
|
||||||
</IconButton>
|
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import type { MaybeSkeletonComponentProps } from '../../../types/maybeSkeletonCo
|
|||||||
import type { ThicknessRange } from '../../Armor/components/StaticArmor';
|
import type { ThicknessRange } from '../../Armor/components/StaticArmor';
|
||||||
import { classIcons } from '../../ClassIcon';
|
import { classIcons } from '../../ClassIcon';
|
||||||
import { Options } from './components/Options';
|
import { Options } from './components/Options';
|
||||||
import { ScrollHint } from './components/ScrollHint';
|
|
||||||
import { TankSandbox } from './components/TankSandbox';
|
import { TankSandbox } from './components/TankSandbox';
|
||||||
import { NATION_COLORS, Title } from './components/TankSandbox/Title';
|
import { NATION_COLORS, Title } from './components/TankSandbox/Title';
|
||||||
|
|
||||||
@@ -119,13 +118,14 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ScrollHint />
|
{/* <ScrollHint /> */}
|
||||||
|
|
||||||
<Flex
|
<Flex
|
||||||
direction={{ initial: 'column-reverse', md: 'row' }}
|
direction={{ initial: 'column-reverse', md: 'row' }}
|
||||||
style={{
|
style={{
|
||||||
zIndex: isFullScreen ? 2 : undefined,
|
zIndex: isFullScreen ? 2 : undefined,
|
||||||
transitionDuration: '1s',
|
transitionDuration: '1s',
|
||||||
|
background: isFullScreen ? 'black' : undefined,
|
||||||
}}
|
}}
|
||||||
height={disturbed && !isFullScreen ? 'calc(100vh - 6rem)' : '100vh'}
|
height={disturbed && !isFullScreen ? 'calc(100vh - 6rem)' : '100vh'}
|
||||||
maxHeight={isFullScreen ? undefined : '60rem'}
|
maxHeight={isFullScreen ? undefined : '60rem'}
|
||||||
@@ -182,13 +182,7 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
|
|||||||
|
|
||||||
{!disturbed && (
|
{!disturbed && (
|
||||||
<Box
|
<Box
|
||||||
onPointerDown={(event) => {
|
onClick={(event) => {
|
||||||
event.stopPropagation();
|
|
||||||
mutateTankopediaEphemeral((draft) => {
|
|
||||||
draft.disturbed = true;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
onWheel={(event) => {
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
mutateTankopediaEphemeral((draft) => {
|
mutateTankopediaEphemeral((draft) => {
|
||||||
draft.disturbed = true;
|
draft.disturbed = true;
|
||||||
|
|||||||
Reference in new issue
Block a user