feat(ui): complete ProCanvas role-based overhaul and fix Recharts crash
- Implement unified Neomorphic tactical layout for ProCanvas across Agent, Admin, and Owner roles. - Add Quick Operations Log widget for immediate action logging. - Integrate discrete Checkpoint/Stages progression system to replace static prize tracks. - Build custom AnimatedCounter for GSAP-style numerical state changes. - Fix Recharts ResponsiveContainer loading crash in OwnerSnapshot.jsx.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { useInView } from 'framer-motion';
|
||||
|
||||
export const AnimatedCounter = ({ from = 0, to, duration = 1.5, className = "" }) => {
|
||||
const [value, setValue] = useState(from);
|
||||
const ref = useRef(null);
|
||||
const isInView = useInView(ref, { once: true, margin: "-20px" });
|
||||
|
||||
useEffect(() => {
|
||||
if (!isInView) return;
|
||||
|
||||
let startTime;
|
||||
let animationFrame;
|
||||
|
||||
const animate = (timestamp) => {
|
||||
if (!startTime) startTime = timestamp;
|
||||
const progress = (timestamp - startTime) / (duration * 1000);
|
||||
|
||||
if (progress < 1) {
|
||||
// Easing function: easeOutQuart
|
||||
const easeOut = 1 - Math.pow(1 - progress, 4);
|
||||
setValue(Math.floor(from + (to - from) * easeOut));
|
||||
animationFrame = requestAnimationFrame(animate);
|
||||
} else {
|
||||
setValue(to);
|
||||
}
|
||||
};
|
||||
|
||||
animationFrame = requestAnimationFrame(animate);
|
||||
|
||||
return () => cancelAnimationFrame(animationFrame);
|
||||
}, [from, to, duration, isInView]);
|
||||
|
||||
return (
|
||||
<span ref={ref} className={className}>
|
||||
{value.toLocaleString()}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user