diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json index 289509378..90113a9c2 100644 --- a/packages/i18n/strings/en.json +++ b/packages/i18n/strings/en.json @@ -873,6 +873,13 @@ "ricochet": { "safe": "Safe <%s1°", "unsafe": "Unsafe ≥%s1°" + }, + + "view_range": { + "camo": "Camo", + "percentage": "%s1%", + "desert_sands": "Desert Sands", + "new_bay": "New Bay" } }, diff --git a/packages/website/public/assets/images/tankopedia/visualizers/range/desert-sands-full.webp b/packages/website/public/assets/images/tankopedia/visualizers/range/desert-sands-full.webp new file mode 100644 index 000000000..7cd69cb17 Binary files /dev/null and b/packages/website/public/assets/images/tankopedia/visualizers/range/desert-sands-full.webp differ diff --git a/packages/website/public/assets/images/tankopedia/visualizers/range/desert-sands.webp b/packages/website/public/assets/images/tankopedia/visualizers/range/desert-sands.webp new file mode 100644 index 000000000..602d7f5f9 Binary files /dev/null and b/packages/website/public/assets/images/tankopedia/visualizers/range/desert-sands.webp differ diff --git a/packages/website/public/assets/images/tankopedia/visualizers/range/new-bay-full.webp b/packages/website/public/assets/images/tankopedia/visualizers/range/new-bay-full.webp new file mode 100644 index 000000000..117430af6 Binary files /dev/null and b/packages/website/public/assets/images/tankopedia/visualizers/range/new-bay-full.webp differ diff --git a/packages/website/public/assets/images/tankopedia/visualizers/range/new-bay.webp b/packages/website/public/assets/images/tankopedia/visualizers/range/new-bay.webp new file mode 100644 index 000000000..71c53ad0d Binary files /dev/null and b/packages/website/public/assets/images/tankopedia/visualizers/range/new-bay.webp differ diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisuazlizer/index.css b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/index.css similarity index 100% rename from packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisuazlizer/index.css rename to packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/index.css diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisuazlizer/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/index.tsx similarity index 100% rename from packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisuazlizer/index.tsx rename to packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/index.tsx diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ViewRangeVisualizer.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ViewRangeVisualizer.tsx new file mode 100644 index 000000000..907b936b2 --- /dev/null +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ViewRangeVisualizer.tsx @@ -0,0 +1,145 @@ +import { literals } from '@blitzkit/i18n'; +import { EyeOpenIcon } from '@radix-ui/react-icons'; +import { Box, Card, Code, Flex, Slider, Tabs, Text } from '@radix-ui/themes'; +import { useRef, useState } from 'react'; +import { Var } from '../../../../../../core/radix/var'; +import { useLocale } from '../../../../../../hooks/useLocale'; +import type { VisualizerProps } from './HullTraverseVisualizer'; + +const maps = [ + { + id: 'new-bay', + string: 'new_bay', + size: 512, + }, + { + id: 'desert-sands', + string: 'desert_sands', + size: 512, + }, +] as const; + +export function ViewRangeVisualizer({ stats }: VisualizerProps) { + const [mapIndex, setMapIndex] = useState(0); + const [camouflage, setCamouflage] = useState(0); + const map = maps[mapIndex]; + const resolvedViewRange = stats.viewRange * (1 - camouflage); + const fraction = resolvedViewRange / map.size; + const fractionPercentage = `${fraction * 100}%`; + const { strings } = useLocale(); + const container = useRef(null); + const range = useRef(null); + + return ( + + { + if (!container.current || !range.current) return; + + const rect = container.current.getBoundingClientRect(); + range.current.style.left = `${event.clientX - rect.left}px`; + range.current.style.top = `${event.clientY - rect.top - 16}px`; + }} + flexGrow="1" + position="absolute" + top="0" + left="0" + width="100%" + height="100%" + style={{ + backgroundImage: `url(/assets/images/tankopedia/visualizers/range/${map.id}.webp)`, + backgroundSize: 'cover', + backgroundPosition: 'center', + }} + > + + + + + {literals(strings.common.units.m, [resolvedViewRange.toFixed(0)])} + + + + + + + + {strings.website.tools.tankopedia.visualizers.view_range.camo} + + + setCamouflage(value)} + /> + + + + {literals( + strings.website.tools.tankopedia.visualizers.view_range + .percentage, + [`${Math.round(camouflage * 100)}`.padStart(3, ' ')], + )} + + + + + + setMapIndex(Number(index))} + > + + {maps.map((map) => ( + + { + strings.website.tools.tankopedia.visualizers.view_range[ + map.string + ] + } + + ))} + + + + + ); +} diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx index bed27e35e..72010177e 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx @@ -34,7 +34,8 @@ import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral'; import { HullTraverseVisualizer } from './components/HullTraverseVisualizer'; import { Info } from './components/Info'; import { InfoWithDelta } from './components/InfoWithDelta'; -import { RicochetVisualizer } from './components/RicochetVisuazlizer'; +import { RicochetVisualizer } from './components/RicochetVisualizer'; +import { ViewRangeVisualizer } from './components/ViewRangeVisualizer'; const [equipmentDefinitions, provisionDefinitions] = await Promise.all([ awaitableEquipmentDefinitions, @@ -398,7 +399,7 @@ export function Characteristics() { /> @@ -786,6 +787,7 @@ export function Characteristics() { unit="m" decimals={0} /> +