From 1b947486680994efab8011b7931cf27111047bca Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Tue, 22 Apr 2025 16:35:49 -0500 Subject: [PATCH] feat: start of ricochet visual 2 --- .../components/RicochetVisualizer2/index.css | 134 ++++++++++++++++ .../components/RicochetVisualizer2/index.tsx | 145 ++++++++++++++++++ .../components/Characteristics/index.tsx | 2 + 3 files changed, 281 insertions(+) create mode 100644 packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer2/index.css create mode 100644 packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer2/index.tsx diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer2/index.css b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer2/index.css new file mode 100644 index 000000000..5a8def587 --- /dev/null +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer2/index.css @@ -0,0 +1,134 @@ +@keyframes penetrating-shell-slide { + 0% { + margin-top: -9rem; + } + 28%, + 100% { + margin-top: 8rem; + } +} + +.ricochet-visualizer-penetrating-shell { + animation: penetrating-shell-slide infinite; +} + +@keyframes ricocheting-shell-slide { + 0% { + margin-top: -18rem; + } + 38% { + margin-top: -18rem; + } + 63%, + 69% { + margin-top: 0rem; + } + 100% { + margin-top: 8rem; + } +} + +@keyframes ricocheting-shell-slide-container { + 0% { + transform: translateX(-50%) rotate(80deg); + } + 63% { + transform: translateX(-50%) rotate(80deg); + } + 69% { + transform: translateX(-50%) rotate(100deg); + } + 100% { + transform: translateX(-50%) rotate(100deg); + } +} + +.ricochet-visualizer-ricocheting-shell { + animation: ricocheting-shell-slide infinite; +} + +.ricochet-visualizer-ricocheting-shell-container { + animation: ricocheting-shell-slide-container infinite; +} + +@keyframes surface-impact { + 0%, + 60% { + opacity: 1; + width: 0; + height: 0; + } + 66% { + opacity: 1; + width: 1.5rem; + height: 1.5rem; + } + 72%, + 100% { + opacity: 0; + width: 3rem; + height: 3rem; + } +} + +.ricochet-visualizer-surface-impact { + animation: surface-impact linear infinite; +} + +@keyframes puncture { + 0%, + 10% { + opacity: 1; + margin-top: -6rem; + } + 15%, + 30% { + opacity: 1; + margin-top: -1rem; + } + 45%, + 100% { + opacity: 0; + margin-top: -1rem; + } +} + +.ricochet-visualizer-puncture { + animation: puncture infinite; +} + +@keyframes safe { + 0% { + opacity: 0; + } + 5%, + 28% { + opacity: 1; + } + 33%, + 100% { + opacity: 0; + } +} + +.ricochet-visualizer-safe { + animation: safe infinite; +} + +@keyframes unsafe { + 0%, + 33% { + opacity: 0; + } + 38%, + 95% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +.ricochet-visualizer-unsafe { + animation: unsafe infinite; +} diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer2/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer2/index.tsx new file mode 100644 index 000000000..6ab71462f --- /dev/null +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer2/index.tsx @@ -0,0 +1,145 @@ +import { asset } from '@blitzkit/core'; +import { Box, Card, Text } from '@radix-ui/themes'; +import { clamp } from 'lodash-es'; +import { useRef } from 'react'; +import { degToRad } from 'three/src/math/MathUtils.js'; +import { Var } from '../../../../../../../core/radix/var'; +import { Duel } from '../../../../../../../stores/duel'; +import type { VisualizerProps } from '../HullTraverseVisualizer'; +import './index.css'; + +const MAX_THICKNESS = 300; +const EXAGGERATION = 4; + +export function RicochetVisualizer2({ stats }: VisualizerProps) { + const thickness = 150; + const shell = Duel.use((state) => state.protagonist.shell); + const container = useRef(null); + const incomingTracer = useRef(null); + const normalizedTracer = useRef(null); + const normalization = EXAGGERATION * degToRad(stats.shellNormalization); + + return ( + { + if ( + !container.current || + !incomingTracer.current || + !normalizedTracer.current + ) + return; + + const rect = container.current.getBoundingClientRect(); + const x = event.clientX - rect.left - rect.width / 2; + const y = event.clientY - rect.top - rect.height / 2; + const angle = clamp(Math.atan2(y, x), -Math.PI / 2, Math.PI / 2); + const normalizedAngle = + Math.sign(angle) * Math.max(0, Math.abs(angle) - normalization); + + incomingTracer.current.style.transform = `rotate(${-Math.PI / 2 + angle}rad)`; + normalizedTracer.current.style.transform = `rotate(${-Math.PI / 2 + normalizedAngle}rad)`; + }} + > + + + + + + + + + + + + + + + + + + *Not to scale + + + + ); +} 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 72010177e..b9e538c3b 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx @@ -35,6 +35,7 @@ import { HullTraverseVisualizer } from './components/HullTraverseVisualizer'; import { Info } from './components/Info'; import { InfoWithDelta } from './components/InfoWithDelta'; import { RicochetVisualizer } from './components/RicochetVisualizer'; +import { RicochetVisualizer2 } from './components/RicochetVisualizer2'; import { ViewRangeVisualizer } from './components/ViewRangeVisualizer'; const [equipmentDefinitions, provisionDefinitions] = await Promise.all([ @@ -389,6 +390,7 @@ export function Characteristics() { value="shellRicochet" /> + )}