Timeline Animations Using Javascript

Banner for a MediaJam post

Eugene Musebe


An animation timeline allows a user to create chronological order of movement and position of objects on a webpage. It's also simple since its build is similar to CSS animation and it supports both JavaScript and CSS play methods. Well, be able to caption any point of the animation for Cloudinary upload.


Check the sandbox demo on Codesandbox.

You can also get the project GitHub repo using Github.


Entry-level javascript and React/Nextjs knowledge.

Setting Up the Sample Project

Create a Nextjs app npx create-next-app terminal . Head to your project cd terminal

We will begin by setting up Cloudinary integration of our serverside backend. We will use it to configure the Cloudinary media file upload procedure.

Create your Cloudinary account using Link and log into it. Each user account will have a dashboard containing environmental variable keys necessary for the integration into the project.

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


Restart your project: npm run dev.

In the pages/api folder, create a new file named upload.js. Configure the environment keys and libraries.

1var cloudinary = require("cloudinary").v2;
4 cloud_name: process.env.CLOUDINARY_NAME,
5 api_key: process.env.CLOUDINARY_API_KEY,
6 api_secret: process.env.CLOUDINARY_API_SECRET,

Create a handler function to execute the POST request. The function will receive media file data and post it to the Cloudinary website. It then captures the media file's Cloudinary link and sends it back as a response.

1export default async function handler(req, res) {
2 if (req.method === "POST") {
3 let url = ""
4 try {
5 let fileStr = req.body.data;
6 const uploadedResponse = await cloudinary.uploader.upload_large(
7 fileStr,
8 {
9 resource_type: "video",
10 chunk_size: 6000000,
11 }
12 );
13 url = uploadedResponse.url
14 } catch (error) {
15 res.status(500).json({ error: "Something wrong" });
16 }
18 res.status(200).json({data: url});
19 }

Our backend is concluded.

In the front end, start by pasting the following in the front end.

4 import anime from "animejs";
5 import { useEffect, useRef, useState } from "react";
6 import html2canvas from "html2canvas";
8export default function Home() {
9 const captionRef = useRef();
11 const captionHandler = () => {
12 }
13 return (
14 <>
15 <nav>
16 <h2>Timeline Animations using Javascript</h2>
17 <button onClick={captionHandler}>Caption</button>
18 </nav>
19 <section id="section" ref={captionRef}>
20 <div >
21 <img src="desert.jpg" id="desert" />
22 <img src="wolf.png" id="wolf" />
23 <a href="#" id="btn">Play</a>
24 <img src="cave.png" id="cave" />
25 <h2 id="text"><span>A</span>wesome</h2>
26 </div>
27 </section>
28 </>
29 )

In the code above, note the two dependencies html2canvas and anime. We use anime to animate our dom elements. Animejs is a lightweight JavaScript animation library with a simple, and powerful API. html2canvas will be used to caption the final result for backend upload. We will also involve react hooks to access the DOM elements in our functions. We use the useEffect hook to manage the animation side effects and finally, we have a function captionHandler that will manage the caption online upload.

In the return statement, we will have to merge 3 pictures. A dog, a cave, and a desert backend. We can also add text just to showcase. You can locate the images in the examples below and use the css files in the styles/global folder in the Github repo.

desert wolf cave

Now let us begin. Inside a useEffect hook, paste the following:

3 useEffect(() => {
4 var animation = anime.timeline({
5 autoplay: false
6 });
8 animation.add({
9 targets: '#btn',
10 top: '1500px',
11 duration: 500,
12 easing: 'easeInOutSine'
13 });
16 animation.add({
17 targets: '#wolf',
18 top: '50px',
19 duration: 500,
20 easing: 'easeInOutSine'
21 });
23 animation.add({
24 targets: '#cave',
25 top: '10px',
26 duration: 500,
27 easing: 'easeInOutSine'
28 });
30 animation.add({
31 targets: '#text',
32 top: '35%',
33 left: '50%',
34 duration: 500,
35 easing: 'easeInOutSine'
36 });
38 document.querySelector('#btn').onclick = animation.play;
40 }, []);

In the code above, we first instantiate the anime library and configure it not to run automatically when the web page is rendered. This is because we want the animation to begin only when instructed. There will be a button onl=click lister to make that happen. We will use the add property to include the 3 images and the button. When the button is clicked, It should move down below the screen and the dog, text, and cave appear from the top screen. The desert image will be placed in the background.

When adding each animation, use the targets parameter to reference the element. the top property shows how many pixels the object should be placed from the top of the page. you can use any direction on this property e.g left, right, and bottom. duration determines the milliseconds the object will take to animate, and finally easing is the process of making an animation not so severe or pronounced.

The final image should look like the below:


That completes it. We have successfully created a timeline animation in a webpage. Enjoy!

Eugene Musebe

Software Developer

I’m a full-stack software developer, content creator, and tech community builder based in Nairobi, Kenya. I am addicted to learning new technologies and loves working with like-minded people.