0
New Detections
import React, { useState, useEffect, useRef } from 'react';import './minimal_count_up.css' const MinimalCountUp = ({ title = "New Detections", number = 1492, limit = 2000,}) => { const [count, setCount] = useState(0); const [counted, setCounted] = useState(0); useEffect(() => { setCount(0); setCount(number <= 100 ? 0 : number - 100) let i = number <= 100 ? 0 : number - 100; const interval = setInterval(() => { if (i < number) { setCount((currentCount) => currentCount + 1); i += 1; } else { clearInterval(interval); } }, 0); return () => clearInterval(interval); }, [number]); useEffect(() => { setCounted(0); const scaledNumber = ((number - 0) / (limit - 0)) * (50 - 0) + 0; const countLimit = Math.round(scaledNumber); const easeOutQuad = (t) => t * (2 - t); let i = 0; const interval = setInterval(() => { if (i < countLimit) { const progress = i / countLimit; // Progress ratio (0 to 1) const easedProgress = easeOutQuad(progress); // Apply easing function const easedValue = easedProgress * countLimit; // Scale eased progress setCounted(Math.round(easedValue)); // Update state with eased value (rounded) i += 1; } else { clearInterval(interval); } }, 20); return () => clearInterval(interval); }, [number, limit, setCounted]); return ( <div className="mcu_wrap"> <div className="mcu_txt_wrap"> <p className="mcu_num"> {count} </p> <p className="mcu_title"> {title} </p> </div> <div className="mcu_line_chart_wrap"> <div className="mcu_line_chart"> {Array.from({ length: 50 }, (_, index) => index).map((line, i) => <div className="mcu_line" style={{ height: `${0.07 * i * i + 6}px` }}></div> )} </div> </div> <div className="mcu_line_chart_wrap"> <div className="mcu_line_chart"> {Array.from({ length: 50 }, (_, index) => index).map((line, i) => { return ( <div> <div className={`mcu_line ${i <= counted ? 'mcu_line_counted' : ''}`} style={{ height: `${0.07 * i * i + 6}px` }}> <div className="mcu_line indicator" style={{ display: i == counted ? 'block' : 'none', height: `${0.07 * i * i + 20}px`, bottom: '14px' }}></div> </div> </div> ) })} </div> </div> </div> );}; export { MinimalCountUp };
.mcu_wrap { height: 240px; width: 400px; padding: 20px; margin: 0px !important; background-color: #DDDDDD; position: relative; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; border-radius: 6px; color: #515151;} .mcu_num { margin: 0px !important; font-weight: 300; font-size: 70px; line-height: 45px;} .mcu_title { margin: 0px !important; font-weight: bold; font-weight: 100; font-size: 30px; padding-left: 4px;} .mcu_line_chart_wrap { position: absolute; bottom: 20px; left: 0px; margin: 0px !important; width: 100%;} .mcu_line_chart { width: 90%; margin: 0px auto; display: flex; justify-content: space-around; align-items: flex-end;} .mcu_line { margin: 0px !important; background-color: #BBBBBB; width: 1px;} .mcu_line_counted { background-color: #515151;} .indicator{ background-color: red; position: relative; bottom: 0px;} .indicator::after{ content: ''; position: absolute; top: -2px; left: -2px; background-color: red; height: 5px; width: 5px; border-radius: 1000px;}