From d764f1fffaddc0a195b86b70546e72dd4198233a Mon Sep 17 00:00:00 2001 From: Rijan Dahal Date: Thu, 12 Mar 2026 00:47:28 +0545 Subject: [PATCH 1/2] add: add Counter Up Animation component --- .../components/CountUp/CountUpAnimation.tsx | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 frontend/src/app/components/CountUp/CountUpAnimation.tsx diff --git a/frontend/src/app/components/CountUp/CountUpAnimation.tsx b/frontend/src/app/components/CountUp/CountUpAnimation.tsx new file mode 100644 index 0000000..9c9644c --- /dev/null +++ b/frontend/src/app/components/CountUp/CountUpAnimation.tsx @@ -0,0 +1,54 @@ +"use client" +import gsap from 'gsap'; +import React, { useLayoutEffect, useRef } from 'react' +import { ScrollTrigger } from 'gsap/ScrollTrigger'; +import { cabinetBold, cabinetRegular } from "@/app/utils/fonts" + +gsap.registerPlugin(ScrollTrigger) + +interface CountdownProps{ + target: number; + isExtra: boolean; + time?: number; + className?: string; +} + +const CountUpAnimation = ({target, isExtra, time = 2, className = ""} : CountdownProps) => { + + const numberRef = useRef(null); + const containerRef = useRef(null); + + useLayoutEffect(() =>{ + const ctx = gsap.context(() =>{ + const countObj = {val : 0} + gsap.to(countObj, { + val: target, + duration: time, + ease: 'power2.out', + scrollTrigger: { + trigger: containerRef.current, + start: "top 95%", + toggleActions: "play none none none", + // markers: true // debugging ko bela only + }, + onUpdate: () => { + if(numberRef.current){ + const currentVal = Math.floor(countObj.val); + const formatted = currentVal + numberRef.current.innerText = isExtra ? `${formatted}+` : `${formatted}` + } + } + }) + }, containerRef) + + return () => ctx.revert() + }, [target, isExtra, time]) + + return ( +
+

0{isExtra && "+"}

+
+ ) +} + +export default CountUpAnimation \ No newline at end of file From 76a5b92c09c78b357c55547d9b7dee7fd9ab4c8e Mon Sep 17 00:00:00 2001 From: Rijan Dahal Date: Thu, 12 Mar 2026 00:47:51 +0545 Subject: [PATCH 2/2] Feat: add Count Up animation on Deerhack Stats Section --- frontend/src/app/components/DeerhackStats/CardMedium.tsx | 7 +++++-- frontend/src/app/components/DeerhackStats/CardMini.tsx | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/components/DeerhackStats/CardMedium.tsx b/frontend/src/app/components/DeerhackStats/CardMedium.tsx index a54877d..0f7e35f 100644 --- a/frontend/src/app/components/DeerhackStats/CardMedium.tsx +++ b/frontend/src/app/components/DeerhackStats/CardMedium.tsx @@ -1,5 +1,6 @@ import ApplicantsSVG from "@/app/assets/images/applicants" import { cabinetBold, cabinetRegular } from "@/app/utils/fonts" +import CountUpAnimation from "../CountUp/CountUpAnimation" export default function CardMedium() { return ( @@ -9,14 +10,16 @@ export default function CardMedium() { {/* Mobile View */}

Total

-

3840+

+ {/*

3840+

*/} +

Applicants

{/* DeskTop View */}

Total Applicants

-

3840+

+ {/*

3840+

*/} +
diff --git a/frontend/src/app/components/DeerhackStats/CardMini.tsx b/frontend/src/app/components/DeerhackStats/CardMini.tsx index 0b46894..b27c069 100644 --- a/frontend/src/app/components/DeerhackStats/CardMini.tsx +++ b/frontend/src/app/components/DeerhackStats/CardMini.tsx @@ -1,5 +1,6 @@ import { cabinetBold, cabinetRegular } from "@/app/utils/fonts"; import { ReactElement } from "react"; +import CountUpAnimation from "../CountUp/CountUpAnimation"; export default function CardMini({ svg, @@ -18,9 +19,10 @@ export default function CardMini({ {title}

-

+ {/*

{numbers} -

+

*/} + ); }