Open In App

Responsive Number Counting Animation Using React JS

Last Updated : 06 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will create a responsive number counting animation using ReactJS. The application will show a number of statistics and each number will be animated as it goes up to the point value. Such a format of animation is often applied for interactive data within sites, for example, to demonstrate the number of customers, sales, statistics and so on.

Preview of Final Output:

Prerequisite

Approach:

  • The CountUpAnimation component accepts props such as an icon, initial value, final value, and text.
  • It sets up the useEffect for animations, determining the exact duration required to reach the target value in four seconds.
  • Within the useEffect, a counter is created using setInterval, incrementing the count by one at each interval and updating the state with setCount until the target is reached.
  • The component displays a container containing an icon, an animated number, and text.
  • In the parent component, App, multiple instances of CountUpAnimation are used to showcase diverse statistics.
  • Each instance is customized with unique icons, values, and text within a wrapper.

Steps to Create the Project:

Step 1: Create a react application by using this command

npx create-react-app CountUpAnimation

Step 2: After creating your project folder, i.e. CountUpAnimation, use the following command to navigate to it:

cd CountUpAnimation

Project Structure:

The updated dependencies in package.json file will look like:

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

Example: Below is the implementation of the above approach.

Javascript




// App.js
 
import React, {
    useEffect,
    useState
}
    from 'react';
import './App.css';
import {
    FaUtensils,
    FaSmileBeam,
    FaList,
    FaStar
}
    from 'react-icons/fa';
 
const CountUpAnimation = ({
    iconComponent,
    initialValue,
    targetValue,
    text,
}) => {
    const [count, setCount] = useState(initialValue);
    const duration = 4000; // 4 seconds
 
    useEffect(() => {
        let startValue = initialValue;
        const interval = Math.floor(
            duration / (targetValue - initialValue));
 
        const counter = setInterval(() => {
            startValue += 1;
            setCount(startValue);
            if (startValue >= targetValue) {
                clearInterval(counter);
            }
        }, interval);
 
        return () => {
            clearInterval(counter);
        };
    }, [targetValue, initialValue]);
 
    return (
        <div className="container">
            <div className="icon">{iconComponent}</div>
            <span className="num">{count}</span>
            <span className="text">{text}</span>
        </div>
    );
};
 
function App() {
    return (
        <div>
            <h2>
                Responsive Number Counting
                Animation - Geeksforgeeks
            </h2>
            <div className="wrapper">
                <CountUpAnimation
                    iconComponent={<FaUtensils />}
                    initialValue={0}
                    targetValue={150}
                    text="Meals Delivered"
                />
                <CountUpAnimation
                    iconComponent={<FaSmileBeam />}
                    initialValue={0}
                    targetValue={200}
                    text="Happy Customers"
                />
                <CountUpAnimation
                    iconComponent={<FaList />}
                    initialValue={0}
                    targetValue={250}
                    text="Menu Items"
                />
                <CountUpAnimation
                    iconComponent={<FaStar />}
                    initialValue={0}
                    targetValue={300}
                    text="Five Stars"
                />
            </div>
        </div>
    );
}
 
export default App;


CSS




/* App.css */
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  font-family: 'Poppins', sans-serif;
}
 
body {
  background-color: #f0f0f0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
}
 
h2 {
  text-align: center;
  margin-bottom: 40px;
  color: green;
}
 
.wrapper {
  display: flex;
  justify-content: space-around;
  gap: 15px;
}
 
.container {
  width: 28vmin;
  height: 28vmin;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  padding: 1em 0;
  position: relative;
  background-color: #ffffff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  border-radius: 15px;
  text-align: center;
  transition: transform 0.3s ease-in-out;
}
 
.container:hover {
  transform: scale(1.05);
}
 
.icon {
  color: red;
  font-size: 2.5em;
  text-align: center;
}
 
span.num {
  color: red;
  font-weight: 600;
  font-size: 2.5em;
}
 
span.text {
  color: #333;
  font-size: 1.2em;
  padding: 0.7em 0;
  font-weight: 600;
  text-transform: uppercase;
}
 
@media screen and (max-width: 1024px) {
  .wrapper {
    width: 90vw;
    flex-wrap: wrap;
    gap: 20px;
  }
 
  .container {
    width: calc(33.33% - 20px);
    height: 350px;
    font-size: 1.4em;
  }
}
 
@media screen and (max-width: 768px) {
  .wrapper {
    width: 90vw;
    flex-wrap: wrap;
    gap: 20px;
  }
 
  .container {
    width: calc(50% - 20px);
    height: 350px;
    font-size: 1.6em;
  }
}
 
@media screen and (max-width: 480px) {
  .wrapper {
    gap: 15px;
  }
 
  .container {
    width: 100%;
    height: 350px;
    font-size: 1.4em;
  }
}


Step 4: Type the following command in the terminal:

npm start

Step 5: Type the following URL in the browser:

 http://localhost:3000/

Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads