diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json index 4090ac1a9..1c1882820 100644 --- a/packages/i18n/strings/en.json +++ b/packages/i18n/strings/en.json @@ -12,7 +12,8 @@ "deg": "%s1°", "hp": "%s1hp", "x": "x%s1", - "percentage": "%s1%" + "percentage": "%s1%", + "deg_s": "%s1°/s" }, "gun_types": { @@ -885,7 +886,8 @@ "turret": "Turret", "hard": "Hard", "medium": "Medium", - "soft": "Soft" + "soft": "Soft", + "effective": "Effective" }, "ricochet": { diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Crew.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Crew.tsx index 48127306e..13760a012 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Crew.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Crew.tsx @@ -7,9 +7,9 @@ import { awaitableProvisionDefinitions } from '../../../../../../core/awaitables import { useEquipment } from '../../../../../../hooks/useEquipment'; import { useLocale } from '../../../../../../hooks/useLocale'; import { Duel } from '../../../../../../stores/duel'; -import type { StatsAcceptorProps } from './HullTraverseVisualizer'; import { InfoWithDelta } from './InfoWithDelta'; import { StatsTableWrapper } from './StatsTableWrapper'; +import type { StatsAcceptorProps } from './TraverseVisualizer'; const provisionDefinitions = await awaitableProvisionDefinitions; diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx index 02bb96e51..1da75a991 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx @@ -21,11 +21,11 @@ import { useEquipment } from '../../../../../../hooks/useEquipment'; import { useLocale } from '../../../../../../hooks/useLocale'; import { useTankModelDefinition } from '../../../../../../hooks/useTankModelDefinition'; import { Duel } from '../../../../../../stores/duel'; -import type { StatsAcceptorProps } from './HullTraverseVisualizer'; import { Info } from './Info'; import { InfoWithDelta } from './InfoWithDelta'; import { RicochetVisualizer } from './RicochetVisualizer'; import { StatsTableWrapper } from './StatsTableWrapper'; +import type { StatsAcceptorProps } from './TraverseVisualizer'; export function Firepower({ stats }: StatsAcceptorProps) { const mutateDuel = Duel.useMutation(); diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.css b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.css deleted file mode 100644 index 4199ac3b9..000000000 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.css +++ /dev/null @@ -1,13 +0,0 @@ -@keyframes spin { - from { - transform: translate(-50%, -50%) rotate(0deg); - } - - to { - transform: translate(-50%, -50%) rotate(360deg); - } -} - -.hull-traverse-visualizer { - animation: spin linear infinite; -} diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Maneuverability.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Maneuverability.tsx index 768ce031f..858479216 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Maneuverability.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Maneuverability.tsx @@ -1,12 +1,12 @@ import { Heading } from '@radix-ui/themes'; import { useLocale } from '../../../../../../hooks/useLocale'; -import { - HullTraverseVisualizer, - type StatsAcceptorProps, -} from './HullTraverseVisualizer'; import { Info } from './Info'; import { InfoWithDelta } from './InfoWithDelta'; import { StatsTableWrapper } from './StatsTableWrapper'; +import { + TraverseVisualizer, + type StatsAcceptorProps, +} from './TraverseVisualizer'; export function Maneuverability({ stats }: StatsAcceptorProps) { const { strings } = useLocale(); @@ -130,7 +130,7 @@ export function Maneuverability({ stats }: StatsAcceptorProps) { value="hullTraverseSoftTerrain" /> - + ); } diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/components/Shell.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/components/Shell.tsx index 9ff3b8a10..1d261de51 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/components/Shell.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/components/Shell.tsx @@ -3,7 +3,7 @@ import type { QuicklimeCallback } from 'quicklime'; import { useEffect, useRef } from 'react'; import { reloadUpdate, type ReloadUpdateData } from '..'; import { Var } from '../../../../../../../../core/radix/var'; -import type { StatsAcceptorProps } from '../../HullTraverseVisualizer'; +import type { StatsAcceptorProps } from '../../TraverseVisualizer'; import { ShellBorder } from './ShellBorder'; interface ShellProps { diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/index.tsx index 319de8da9..127cd62af 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/index.tsx @@ -4,7 +4,7 @@ import { times } from 'lodash-es'; import { Quicklime, type QuicklimeCallback } from 'quicklime'; import { useEffect, useRef } from 'react'; import { Var } from '../../../../../../../core/radix/var'; -import type { StatsAcceptorProps } from '../HullTraverseVisualizer'; +import type { StatsAcceptorProps } from '../TraverseVisualizer'; import { Shell } from './components/Shell'; import { Target } from './components/Target'; diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/index.tsx index 45c30a373..f6557e589 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/index.tsx @@ -6,7 +6,7 @@ import { clamp, degToRad, radToDeg } from 'three/src/math/MathUtils.js'; import { Var } from '../../../../../../../core/radix/var'; import { useLocale } from '../../../../../../../hooks/useLocale'; import { Duel } from '../../../../../../../stores/duel'; -import type { StatsAcceptorProps } from '../HullTraverseVisualizer'; +import type { StatsAcceptorProps } from '../TraverseVisualizer'; import { ShellSwitcher } from './components/ShellSwitcher'; export function RicochetVisualizer({ stats }: StatsAcceptorProps) { diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Survivability.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Survivability.tsx index fbd47a868..edd9c96f7 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Survivability.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Survivability.tsx @@ -1,9 +1,9 @@ import { Heading } from '@radix-ui/themes'; import { useLocale } from '../../../../../../hooks/useLocale'; -import type { StatsAcceptorProps } from './HullTraverseVisualizer'; import { Info } from './Info'; import { InfoWithDelta } from './InfoWithDelta'; import { StatsTableWrapper } from './StatsTableWrapper'; +import type { StatsAcceptorProps } from './TraverseVisualizer'; import { ViewRangeVisualizer } from './ViewRangeVisualizer'; export function Survivability({ stats }: StatsAcceptorProps) { diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/TraverseVisualizer/index.tsx similarity index 67% rename from packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.tsx rename to packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/TraverseVisualizer/index.tsx index c4e9afc6e..40b33a035 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/TraverseVisualizer/index.tsx @@ -1,8 +1,8 @@ -import { Card, Checkbox, Flex, Tabs, Text } from '@radix-ui/themes'; -import { useRef, useState } from 'react'; +import { literals } from '@blitzkit/i18n'; +import { Card, Checkbox, Code, Flex, Tabs, Text } from '@radix-ui/themes'; +import { useEffect, useRef, useState } from 'react'; import type { TankCharacteristics } from '../../../../../../../core/blitzkit/tankCharacteristics'; import { useLocale } from '../../../../../../../hooks/useLocale'; -import './index.css'; export interface StatsAcceptorProps { stats: TankCharacteristics; @@ -10,7 +10,7 @@ export interface StatsAcceptorProps { type Terrain = 'Hard' | 'Medium' | 'Soft'; -export function HullTraverseVisualizer({ stats }: StatsAcceptorProps) { +export function TraverseVisualizer({ stats }: StatsAcceptorProps) { const hull = useRef(null); const turret = useRef(null); const [terrain, setTerrain] = useState('Hard'); @@ -19,12 +19,46 @@ export function HullTraverseVisualizer({ stats }: StatsAcceptorProps) { const { strings } = useLocale(); const isTurretless = stats.azimuthLeft !== undefined || stats.azimuthRight !== undefined; + const turretAngle = useRef(0); + const hullAngle = useRef(0); + const turretSpeedDeg = rotateTurret ? stats.turretTraverseSpeed : 0; + const hullSpeedDeg = rotateHull ? stats[`hullTraverse${terrain}Terrain`] : 0; + + useEffect(() => { + let cancel = false; + const turretSpeedRad = turretSpeedDeg * (Math.PI / 180); + const hullTraverseRad = hullSpeedDeg * (Math.PI / 180); + let lastT = Date.now() / 1000; + + function frame() { + if (!turret.current || !hull.current) return; + + const t = Date.now() / 1000; + const dt = t - lastT; + lastT = t; + + turretAngle.current = + (turretAngle.current + turretSpeedRad * dt) % (2 * Math.PI); + hullAngle.current = + (hullAngle.current + hullTraverseRad * dt) % (2 * Math.PI); + + turret.current.style.transform = `translate(-50%, -50%) rotate(${-turretAngle.current}rad)`; + hull.current.style.transform = `translate(-50%, -50%) rotate(${-hullAngle.current}rad)`; + + if (!cancel) requestAnimationFrame(frame); + } + + frame(); + + return () => { + cancel = true; + }; + }, [terrain, turretSpeedDeg, hullSpeedDeg]); return ( + + + {strings.website.tools.tankopedia.visualizers.rotator.effective} + + + {literals(strings.common.units.deg_s, [ + `${(turretSpeedDeg + hullSpeedDeg).toFixed(1)}`, + ])} + + + {!isTurretless && (
+ {literals(strings.common.units.deg_s, [ + `${(turretSpeedDeg + hullSpeedDeg).toFixed(1)}`, + ])} +