73 lines
1.9 KiB
React
73 lines
1.9 KiB
React
|
import {useEffect, useState} from 'react';
|
||
|
|
||
|
import {useRadians} from '@/react/context/radians.js';
|
||
|
|
||
|
import styles from './damage.module.css';
|
||
|
|
||
|
export default function Damage({
|
||
|
camera,
|
||
|
damage,
|
||
|
scale,
|
||
|
}) {
|
||
|
const [hue, setHue] = useState(0);
|
||
|
const [opacity, setOpacity] = useState(0.5);
|
||
|
const [growth, setGrowth] = useState(0.25);
|
||
|
const [offset, setOffset] = useState({x: 0, y: 0});
|
||
|
const [randomness] = useState({
|
||
|
hue: Math.random() * 10,
|
||
|
x: 1 * (Math.random() - 0.5),
|
||
|
y: 150 * (Math.random()),
|
||
|
rotation: Math.random() * (Math.PI / 8) - (Math.PI / 16),
|
||
|
});
|
||
|
const radians = useRadians();
|
||
|
useEffect(() => {
|
||
|
setHue(15 + (Math.cos(radians * 4) * (5 + randomness.hue)));
|
||
|
}, [radians, randomness.hue]);
|
||
|
useEffect(() => {
|
||
|
let handle;
|
||
|
let accumulated = 0;
|
||
|
let last = Date.now();
|
||
|
function float() {
|
||
|
const elapsed = (Date.now() - last) / 1000;
|
||
|
accumulated += elapsed;
|
||
|
last = Date.now();
|
||
|
if (accumulated < 0.25) {
|
||
|
setOpacity(0.5 + accumulated * 2)
|
||
|
}
|
||
|
if (accumulated < 0.5) {
|
||
|
setGrowth(0.25 + (accumulated * 1.5))
|
||
|
setOffset({
|
||
|
x: 80 * (accumulated * randomness.x),
|
||
|
y: -((80 + randomness.y) * (accumulated)),
|
||
|
});
|
||
|
}
|
||
|
if (accumulated >= 1.5) {
|
||
|
damage.onClose();
|
||
|
}
|
||
|
handle = requestAnimationFrame(float);
|
||
|
}
|
||
|
handle = requestAnimationFrame(float);
|
||
|
return () => {
|
||
|
cancelAnimationFrame(handle);
|
||
|
};
|
||
|
}, [damage, randomness.x, randomness.y]);
|
||
|
|
||
|
const {amount, position} = damage;
|
||
|
const left = position.x * scale - camera.x + offset.x;
|
||
|
const top = position.y * scale - camera.y + offset.y;
|
||
|
return (
|
||
|
<div
|
||
|
className={styles.damage}
|
||
|
style={{
|
||
|
color: `hsl(${hue} 100% 50%)`,
|
||
|
left: `${left}px`,
|
||
|
opacity,
|
||
|
top: `${top}px`,
|
||
|
transform: `scale(${growth}) rotate(${randomness.rotation}rad)`,
|
||
|
}}
|
||
|
>
|
||
|
<p>{amount}</p>
|
||
|
</div>
|
||
|
);
|
||
|
}
|