73 lines
1.9 KiB
TypeScript
73 lines
1.9 KiB
TypeScript
|
import React, {useState, useEffect} from 'react';
|
||
|
import {useSpring, animated} from '@react-spring/web';
|
||
|
|
||
|
import './ScoreCounter.css';
|
||
|
|
||
|
let scrollInterval: ReturnType<typeof setInterval>;
|
||
|
|
||
|
const points = {
|
||
|
attempt: 1,
|
||
|
scheduledPoop: 5,
|
||
|
selfPoop: 10,
|
||
|
cleanUndies: 50,
|
||
|
streakBonus: [50, 60, 80, 100, 120, 140, 150]
|
||
|
};
|
||
|
|
||
|
const calcPoints = (stats: Stats) => {
|
||
|
return stats.attempts * points.attempt +
|
||
|
stats.scheduledPoops * points.scheduledPoop +
|
||
|
stats.selfPoops * points.selfPoop +
|
||
|
stats.cleanUndies * points.cleanUndies;
|
||
|
//+ stats.streaks.reduce((p,s,i) => p + s * points.streakBonus[i]);
|
||
|
};
|
||
|
|
||
|
const getShakeStyle = () => {
|
||
|
const xr = Math.random();
|
||
|
const yr = Math.random();
|
||
|
const rr = Math.random();
|
||
|
const sr = Math.random();
|
||
|
return {
|
||
|
x: Math.floor(xr * 30) - 15,
|
||
|
y: Math.floor(yr * 30) - 15,
|
||
|
rotate: Math.floor((rr * 40)) - 20,
|
||
|
scale: sr * 0.3 + .80
|
||
|
};
|
||
|
};
|
||
|
|
||
|
const ScoreCounter = ({stats}: {stats: Stats}) => {
|
||
|
const score = calcPoints(stats);
|
||
|
const [showing, setShowing] = useState<number>(score);
|
||
|
|
||
|
const restState = { x: 0, y: 0, rotate: 0, scale: 1};
|
||
|
|
||
|
const [springs, api] = useSpring(() => (restState));
|
||
|
|
||
|
useEffect(() => {
|
||
|
scrollInterval = setInterval(() => {
|
||
|
setShowing(n => {
|
||
|
const delta = Math.ceil(Math.abs(n - score)/5);
|
||
|
if(n < score) {
|
||
|
api.start(getShakeStyle());
|
||
|
return n + delta;
|
||
|
} else if( n > score) {
|
||
|
api.start(getShakeStyle());
|
||
|
return n - delta;
|
||
|
} else {
|
||
|
clearInterval(scrollInterval);
|
||
|
Promise.all(api.start(
|
||
|
{x:0, y: -10, rotate: 0, scale: 1.25})).then(() => {
|
||
|
api.start(restState);
|
||
|
});;
|
||
|
return n;
|
||
|
}
|
||
|
});
|
||
|
}, 80);
|
||
|
|
||
|
return () => clearInterval(scrollInterval);
|
||
|
}, [score]);
|
||
|
|
||
|
return <animated.span style={{display: "inline-block", ...springs}} className="score-counter">{showing}</animated.span>;
|
||
|
};
|
||
|
|
||
|
export default ScoreCounter;
|