mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-22 11:17:05 +02:00
feat: begennings of reload visuals
This commit is contained in:
1 parent
aeaf52d3ac
commit
d8c26ba24a
4 files changed
+199
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
+3
@@ -24,6 +24,7 @@ import { Duel } from '../../../../../../stores/duel';
|
||||
import type { StatsAcceptorProps } from './HullTraverseVisualizer';
|
||||
import { Info } from './Info';
|
||||
import { InfoWithDelta } from './InfoWithDelta';
|
||||
import { ReloadVisualizer } from './ReloadVisualizer';
|
||||
import { RicochetVisualizer } from './RicochetVisualizer';
|
||||
import { StatsTableWrapper } from './StatsTableWrapper';
|
||||
|
||||
@@ -165,6 +166,8 @@ export function Firepower({ stats }: StatsAcceptorProps) {
|
||||
value="intraClip"
|
||||
/>
|
||||
)}
|
||||
<ReloadVisualizer stats={stats} />
|
||||
|
||||
<InfoWithDelta stats={stats} decimals={0} value="penetration" />
|
||||
{typeof shell.penetration !== 'number' && (
|
||||
<>
|
||||
|
||||
+61
@@ -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<HTMLDivElement>(null!);
|
||||
|
||||
useEffect(() => {
|
||||
const handleReloadUpdate: QuicklimeCallback<ReloadUpdateData> = ({
|
||||
data,
|
||||
}) => {
|
||||
bar.current.style.width = `${data.shells[index] * 100}%`;
|
||||
};
|
||||
|
||||
reloadUpdate.on(handleReloadUpdate);
|
||||
|
||||
return () => {
|
||||
reloadUpdate.off(handleReloadUpdate);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: `translate(-50%, -50%) rotate(${(index - Math.floor(stats.shells / 2)) * 10}deg)`,
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
justify="end"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '50%',
|
||||
marginLeft: 'calc(25% + 2rem)',
|
||||
width: '1.25rem',
|
||||
height: '0.5rem',
|
||||
borderRadius: '0.25rem',
|
||||
overflow: 'hidden',
|
||||
outline: `1px solid ${Var('jade-6')}`,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
ref={bar}
|
||||
style={{
|
||||
background: Var('jade-9'),
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
+135
@@ -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<ReloadUpdateData>();
|
||||
|
||||
export function ReloadVisualizer({ stats }: StatsAcceptorProps) {
|
||||
const reloadCircle = useRef<HTMLDivElement>(null!);
|
||||
const reloadCore = useRef<HTMLDivElement>(null!);
|
||||
const reloadGlow = useRef<HTMLDivElement>(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<ReloadUpdateData> = ({
|
||||
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 (
|
||||
<Card variant="classic" mb="6" style={{ aspectRatio: '1 / 1' }}>
|
||||
<Box
|
||||
p="4"
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
width={size}
|
||||
height={size}
|
||||
className="reload"
|
||||
ref={reloadGlow}
|
||||
style={{
|
||||
transform: 'translate(-50%, -50%)',
|
||||
borderRadius: '50%',
|
||||
filter: 'blur(0.5rem)',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Box
|
||||
p="1"
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
width={size}
|
||||
height={size}
|
||||
className="reload"
|
||||
ref={reloadCircle}
|
||||
style={{
|
||||
transform: 'translate(-50%, -50%)',
|
||||
borderRadius: '50%',
|
||||
background: Var('red-7'),
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
ref={reloadCore}
|
||||
style={{
|
||||
backgroundColor: Var('red-2'),
|
||||
borderRadius: '50%',
|
||||
}}
|
||||
width="100%"
|
||||
height="100%"
|
||||
overflow="hidden"
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
background: `radial-gradient(${Var('gray-3')} 25%, transparent)`,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<img
|
||||
src="/assets/images/tankopedia/visualizers/reload/caret.png"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: '10%',
|
||||
height: '10%',
|
||||
}}
|
||||
/>
|
||||
|
||||
{times(stats.shells, (index) => (
|
||||
<Shell stats={stats} index={index} key={index} />
|
||||
))}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user