From d8c26ba24ab80ba9f37f134278e95c5020d2d34c Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Mon, 28 Apr 2025 17:21:42 -0500 Subject: [PATCH] feat: begennings of reload visuals --- .../tankopedia/visualizers/reload/caret.png | Bin 0 -> 1683 bytes .../Characteristics/components/Firepower.tsx | 3 + .../ReloadVisualizer/components/Shell.tsx | 61 ++++++++ .../components/ReloadVisualizer/index.tsx | 135 ++++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 packages/website/public/assets/images/tankopedia/visualizers/reload/caret.png create mode 100644 packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/components/Shell.tsx create mode 100644 packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/index.tsx diff --git a/packages/website/public/assets/images/tankopedia/visualizers/reload/caret.png b/packages/website/public/assets/images/tankopedia/visualizers/reload/caret.png new file mode 100644 index 0000000000000000000000000000000000000000..66085397118f185d4115acf024d3a470b36648b0 GIT binary patch literal 1683 zcmV;E25k9>P)!WGKMpPpks@X5f>yeA!-IcNVY|jWlOdnVq)h07&EgNl4U=Z zY%cR-uq8-Ff^*DG7ug0(1c8AjW-7)d-6m;d2$X)`yXS3hwbW8t>;g-8lPBk%b8hc> z&U>EsocEL{{$>Uq0Lv-PCQy7W0eAyQ1l|I)v`9?_JPnKjGGGPrXptIwvl(!cpR8M{ z>uHf0%V`HN0Z8O0%djc!@s`^YSvqiy9+3=yi4OxQv`CDD=m21+$H~e{JNIj7fsKPI zmmUSx45(D9!1Fy|H7&3uYPH(0Pu8rNLr01K-L8`0XkYB*N={C8y?^xRPdh3rM@3PTGcz;oDJd!Amo8n(al73-4(mG= zxUZ0wC`OwPSspYSIIRp$(5>?!Qk^G6D}wycrZFTDh&+{Wx?A5CZ$H- z2H*_&^N0VOtN~~Mo(BXDq|KW*kDNGhq9Zjm)k*%7%Lk1{0%(bGgN0Ne5w` zs7{&W1;9fwSgc~_!HR(00DDQ!&dwe?b?Q_{dV0E7c_(=LB1pm8)YNog&6+hR( zuK=5r??r8~dNu_Eeo6klRRx{ePM$pZb#ZaA70b?EVz@(*l$2y!yLRm#=gyrga5|k@ zWuniLUk5<>^m@IkzP|p4y1Kf%&@7=X0H1l43S`1nTD5AGZG3$E zpMimaJg?Ww-{O4tZ{RnIGT35ShLyk-ARAirR8&-SH8(eZziinuS?TwcOpd}IyE4d9 zO-;>C>=4^L9uIrhLVoRAq9G8iW;v)10VdWRHvBt{jg1#UG@?f&Ng^!!!^s$pMyc_1 zV>`TjQ_-&plY5u^N&B1@jSK=obqoU-5J*-8%*W8+eMrIyLY$~D99&{>hf=rWeTLKJ zayis$wFA!%y+Lm)Dk{3x-rinpv)TB7$OkS0f6YZC8nVe44_(%m3lHc3f+77Q%&^2?>u2tJIGy z?InD>1grKf`IGsuq{5jIA7}&F(#p!p1FfyCozR&I!N5t&EI*l562Z@5Wil}_Ay-vZ zZR_dj`3O?zg?D$7|FSv5!nuhz>uTUd?5Ce&KkcIUTIeKr|0NtSKj-G=eu}N*1+?u_ zc+9YHp3Q_udrW5Y^>5CeeY>=@)CG;HaJ&*qLaCz1y*L-CNcBJ|4G#}%%gf6@85_R~q|O8|VGN*N%lnuBQYJG0d(s8pHFW-ny$YgboS zwO96Lpyw9~3bx<@`FTCO`W=>|wy&>mI4vzrpy=|4`FMJ^HmR_%aKnuoH(Eqds&c!1 z|2xQ`WRrm=+@o51dwb93et?KHA{upoeij%a^u+>Q1ZZ(XHm0Yh9>Zq8hm>G@c#*??y7%D0gGX_f zvQy-xj}&0Bq@0mfLVyH4qFR0R>Xp8IHm9ST{D+D!J$n^VzLIlgKvbZf2gG=yrKLqo z121^=b%iHAg(zI#(a{n2!QudRo_dAJ#5dxVgmd4_GvJ%&Vg!4W9f`ot )} + + {typeof shell.penetration !== 'number' && ( <> 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 new file mode 100644 index 000000000..e345c3f89 --- /dev/null +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/components/Shell.tsx @@ -0,0 +1,61 @@ +import { Box, Flex } from '@radix-ui/themes'; +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'; + +interface ShellProps { + index: number; +} + +export function Shell({ index, stats }: ShellProps & StatsAcceptorProps) { + const bar = useRef(null!); + + useEffect(() => { + const handleReloadUpdate: QuicklimeCallback = ({ + data, + }) => { + bar.current.style.width = `${data.shells[index] * 100}%`; + }; + + reloadUpdate.on(handleReloadUpdate); + + return () => { + reloadUpdate.off(handleReloadUpdate); + }; + }, []); + + return ( + + + + + + ); +} 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 new file mode 100644 index 000000000..001cb7ba3 --- /dev/null +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ReloadVisualizer/index.tsx @@ -0,0 +1,135 @@ +import { Box, Card } from '@radix-ui/themes'; +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 { Shell } from './components/Shell'; + +export interface ReloadUpdateData { + reload: number; + shells: number[]; +} + +export const reloadUpdate = new Quicklime(); + +export function ReloadVisualizer({ stats }: StatsAcceptorProps) { + const reloadCircle = useRef(null!); + const reloadCore = useRef(null!); + const reloadGlow = useRef(null!); + + const size = `${stats.shells === 1 ? 66 : 58}%`; + + useEffect(() => { + let cancel = false; + + function frame() { + const now = Date.now() / 1000; + + const t = now % stats.shellReload!; + const x = t / stats.shellReload!; + + reloadUpdate.dispatch({ + reload: x, + shells: Array(stats.shells).fill(x), + }); + + if (!cancel) requestAnimationFrame(frame); + } + + frame(); + + return () => { + cancel = true; + }; + }, [stats]); + + useEffect(() => { + const handleReloadUpdate: QuicklimeCallback = ({ + data, + }) => { + const reloadAngle = data.reload * 2 * Math.PI; + + reloadCircle.current.style.background = `conic-gradient(${Var('amber-9')} 0 ${reloadAngle}rad, ${Var('red-7')} ${reloadAngle}rad)`; + reloadCore.current.style.background = `conic-gradient(${Var('amber-3')} 0 ${reloadAngle}rad, ${Var('red-2')} ${reloadAngle}rad)`; + reloadGlow.current.style.background = `conic-gradient(${Var('amber-8')} 0 ${reloadAngle}rad, transparent ${reloadAngle}rad)`; + }; + + reloadUpdate.on(handleReloadUpdate); + + return () => { + reloadUpdate.off(handleReloadUpdate); + }; + }, []); + + return ( + + + + + + + + + + + + {times(stats.shells, (index) => ( + + ))} + + ); +}