Skip to content

Background Animation Effect with Next.js

This article demonstrates how Javascript and css can be used to create an awesome background ie for a website.

Check the sandbox demo on Codesandbox.

You can also get the project GitHub repo using Github.

Entry-level javascript, CSS, and React/Nextjs knowledge.

In your respective folder, create a new net js app using npx create-next-app removePerson in your terminal. Head to your project root directory cd removePerson

We will use Cloudinary for captioning any point of our animated background. That is, in case a user wishes to present a background sample.

Create your own cloudinary account using Link and log into it. Each cloudinary user account will have a dashboard containing environment variable keys that are necessary for the cloudinary integration in our project.

In your project directory, start by including Cloudinary in your project dependencies npm install cloudinary create a new file named .env and paste the following code. Fill the blanks with your environment variables from the cloudinary dashboard.

".env"

CLOUDINARY_CLOUD_NAME =

CLOUDINARY_API_KEY =

CLOUDINARY_API_SECRET =

Restart your project: npm run dev.

In the pages/api folder, create a new file named upload.js. Start by installing cloudinary npm install cloudinary and configuring the environment keys and libraries.

"pages/api/upload.js"


var cloudinary = require("cloudinary").v2;

cloudinary.config({
    cloud_name: process.env.CLOUDINARY_NAME,
    api_key: process.env.CLOUDINARY_API_KEY,
    api_secret: process.env.CLOUDINARY_API_SECRET,
});

Include a handler function to receive media file data and post it to the cloudinary website then capture the media file’s cloudinary link and send it back as a response.

"pages/api/upload.js"


export default async function handler(req, res) {
    if (req.method === "POST") {
        let url = ""
        try {
            let fileStr = req.body.data;
            const uploadedResponse = await cloudinary.uploader.upload_large(
                fileStr,
                {
                    chunk_size: 6000000,
                }
            );
            url = uploadedResponse.url
        } catch (error) {
            res.status(500).json({ error: "Something wrong" });
        }

        res.status(200).json({data: url});
    }
}

For the front end, we will animate a website background. This article will show 2 kinds of backgrounds. In the pages/index folder, paste the following in the return statement

"pages/index"


    return (
        <>
            <div className="item">
                {link? <h3><b>Uploaded</b></h3>: <h3>Double Click anywhere to save Caption</h3>}
            </div>
            <div className="container" onClick={captionHandler}>
                <div className="heart"></div>
            </div>
        </>
    )

Notice the captionHandler function. We will use it to capture a screenshot of the background effect and send it to the backend for upload. Since the screenshot will be for the whole document body, go ahead and paste the following code.

"pages/index"


    async function captionHandler  () {
        await takeScreenshot(document.body).then(function (caption) {
            if (!caption) return
            try {
                fetch('/api/upload', {
                  method: 'POST',
                  body: JSON.stringify({ data: userprofile }),
                  headers: { 'Content-Type': 'application/json' },
                })
                  .then((response) => response.json())
                  .then((data) => {
                    setLink(data.data);
                  });
              } catch (error) {
                console.error(error);
              }
        })
    }

The code above is meant to capture the document body and post it to the backend as an image file. The code’s response will include the media file’s cloudinary link which will be saved to a use state hook.

Let us now animate the background. Paste the following code in ’the styles/global“ directory.

html body {
  text-align: left;
  object-fit: cover;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: 0;
}
.item{
  align-items: center;
  display: flex;
  flex-direction: row;
  /* border: 3px solid rgb(0, 0, 0); */
  text-align: center;
  padding: 10px;
  margin: 10px;
}

.column {
  flex: 1 1 0px;
  border: 10px;
  /* border:3px solid  rgb(182, 0, 0); */
  text-align: center;
}
.container {
  /* border: 5px solid blue; */
  position: absolute;
  top: 0;
  left: 50;
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-image: #e80202;
  overflow: hidden
}

.heart {
  position: absolute;
  width: 40px;
  height: 40px;
  background: transparent;
  transform: rotate(45deg);
  box-shadow: 0 -20px 20px rgba(0, 0, 0, 0.1);
}

.heart::before {
  content: '';
  position: absolute;
  top: -50%;
  left: 0%;
  width: 100%;
  height: 100%;
  background: #e80202;
  border-radius: 50%;
  box-shadow: -20px 0 20px rgba(0, 0, 0, 0.1);
}

.heart::after {
  content: '';
  position: absolute;
  top: 0;
  left: -50%;
  width: 100%;
  height: 100%;
  background: transparent;
  border-radius: 50%;
  box-shadow: -20px 0 20px rgba(0, 0, 0, 0.1);
}

button {
  padding: 15px;
    color: #7B7B7B;
    background-color: #FFF;
    border-radius: 1rem;
    border: 1px solid;
    font-size: 20px;
    width: 200px;
    height: 60px;
    align-items: center;
    text-align: center;
}
button:hover {
  transform: translateY(-3px);
  transition: 1s;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}

The css code above will create a heart-like div that rotates randomly on the screen. We will however need to tweak it at this level to make it more appealing. Such will be achieved through a useEffect hook and an animaheHandler function. We use animejs to achieve this.

npm install animejs

import anime from 'animejs';

 useEffect(() => {
        const container = document.querySelector('.container');

        for (var i = 1; i <= 50; i++) {
            const hearts = document.createElement('div');
            hearts.classList.add('heart')
            container.appendChild(hearts);
        }

        animateHearts()
    }, [])

 function animateHearts() {
        anime({
            targets: '.heart',
            translateX: function (x) {
                return anime.random(-700, 700);
            },
            translateY: function (x) {
                return anime.random(-500, 500);
            },
            rotate: 45,
            scale: function () {
                return anime.random(1, 5)
            },
            easing: 'easeInOutBack',
            duration: 3000,
            delay: anime.stagger(10),
            complete: animateHearts,
        })
    }

That’s it. If u run your code at this point you should have a richly animated background that loops through animated effects. Ensure to go through this article to enjoy the experience.

Back to top

Featured Post