Creating Confetti Animation in Next.js: A Step-by-Step Guide

thumbnail

Hello Guys, In this quick tutorial, we’ll walk through the process of creating a simple yet cool confetti effect in a Next.js application. We will create a simple button that on clicked shows the confetti animation effect. Let’s get started!

Step 1: Set Up Your Next.js Project

If you haven’t already set up a Next.js project, you can do so using the following commands:

npx create-next-app

Step 2: Create the Confetti Component

Import Statements and Constants:

import React, { useState, useEffect, useRef } from 'react';
const SHAPES = ['square', 'triangle'];
const COLOR_DIGIT = "ABCDEF1234567890";
  • Import React and necessary hooks (useState, useEffect, useRef).
  • Define an array SHAPES representing possible shapes for confetti particles.
  • Define COLOR_DIGIT with characters for generating random colors.

Component Declaration:

...
const ConfettiButton = () => {
    const [isConfettiActive, setConfettiActive] = useState(false);
    const containerRef = useRef(null);
    useEffect(() => {
        if (isConfettiActive) {
            generateConfetti();
        }
    }, [isConfettiActive]);
  • Create a component named ConfettiButton.
  • Use the useState hook to create a state variable isConfettiActive and setConfettiActive function to control confetti activation.
  • Use the useRef hook to create a reference (containerRef) for the container where confetti particles will be rendered.
  • Utilize the useEffect hook to trigger the generateConfetti function when isConfettiActive changes.

Random Color Generation:

...
const generateRandomColor = () => {
    let color = "#";
    for (let i = 0; i < 6; i++) {
        color += COLOR_DIGIT[Math.floor(Math.random() * COLOR_DIGIT.length)];
    }
    return color;
};
  • Define a function generateRandomColor to generate a random hex color code, as hex color code has 6 characters after # so we have a loop to find the 6 random characters for our set COLOR_DIGIT.

Confetti Generation:

...
const generateConfetti = () => {
    const container = containerRef.current;    
    if (container) {
        for (let i = 0; i < 50; i++) {
            const confetti = document.createElement('div');
            const positionX = Math.random() * window.innerWidth;
            const positionY = Math.random() * window.innerHeight;
            const rotation = Math.random() * 360;
            const size = Math.floor(Math.random() * (20 - 5 + 1)) + 5;            // Set confetti styles
            confetti.style.left = `${positionX}px`;
            confetti.style.top = `${positionY}px`;
            confetti.style.transform = `rotate(${rotation}deg)`;
            confetti.className = 'confetti ' + SHAPES[Math.floor(Math.random() * 3)];
            confetti.style.width = `${size}px`
            confetti.style.height = `${size}px`
            confetti.style.backgroundColor = generateRandomColor();            // Append confetti to the container
            container.appendChild(confetti);            
            // Remove confetti element after animation duration (4 seconds)
            setTimeout(() => {
                container.removeChild(confetti);
            }, 4000);
        }
    }
};

Explanation:

  • Define a function generateConfetti responsible for creating and animating confetti particles.
  • Use a loop to create 50 confetti elements.
  • Set random position, rotation, size, shape, and color for each confetti particle.
  • Append each confetti element to the container, which we will create later.
  • Remove confetti elements after an animation duration of 4 seconds.

Button Click Handler:

const handleClick = () => {
    setConfettiActive(true);
    // Reset the confetti after a short delay
    setTimeout(() => {
        setConfettiActive(false);
    }, 4000);
};
  • function handleClick to set isConfettiActive to true when the button is clicked.
  • Reset isConfettiActive to false after a short delay (4 seconds) to stop the confetti animation.

JSX:

...
return (
    <div>
        <button className='font-bold text-xl' onClick={handleClick}>Click for Confetti</button>
        <div className='fixed top-0 left-0 w-full h-full pointer-events-none' ref={containerRef} id="confetti-container"></div>
    </div>
);
export default ConfettiButton;
  • For JSX we have a button triggering the confetti (<button>).

  • Attach the handleClick function to the button's onClick event.

  • Include a fixed container (<div>) for rendering confetti particles, with a reference (ref={containerRef}) and an id (id="confetti-container") Inside this our confetti’s will be appended on the button click. Now we can use this component on the page we wish I am adding it to the home page.

    // /src/app/page.tsx

    import ConfettiButton from '@/components/confetti-button'

    export default function Home() { return (

    ) }

Let's add the styles in the global.css

@tailwind base;
@tailwind components;
@tailwind utilities;


.confetti {
  position: absolute;
  width: 10px;
  height: 10px; 
  transform-origin: center bottom;
  animation: fall 4s linear infinite;
}

.confetti.square {
  clip-path: polygon(0% 0%, 0% 100%, 100% 100%, 100% 0%);
}
.confetti.triangle {
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

@keyframes fall {
  to {
    transform: translateY(100vh) rotate(720deg);
  }
}

The above styles help in setting the confetti animation to move from its current position down to the screen height and also rotate while moving. for shapes, we use clip-path.

Now you can run the Next JS app using npm run devVisit http://localhost:3000 in your browser to see the confetti button animation in action.

Congratulations! You’ve successfully created a confetti effect in your Next.js application. Feel free to customize the confetti shapes, colors, and other parameters to match your site’s style. Happy Coding :)