Hugo’s JS Loop Animation Tutorial v1.0

Today, you will build an animation using JS’s setInterval() function.

Introduction

Like the library animation in the other tutorial, this technique also makes use of tweening. But this time, we will use only simple, plain JavaScript. No libraries. Aside from giving you an idea of what is possible to achieve using JS to animate, this technique also anticipates some of the concepts that we will use while building the game project at the end of this course.

Because animation, at its base, is formed by properties, like position or size, that change in time, the most fundamental thing you need to create an animation is a timer that triggers constantly at a regular interval. When talking about animations, you often hear the term frame-per-second, of FPS. This refers to the number of times, whithin a second, that the image or frame changes. In digital animations, this rate of change is managed by what we could call a “ticker”. In the techiques of the other two tutorials, we did not consider the timer, because it was automatic. But this time, we will build our own ticker. (Note that ticker is not a technical term, it’s just me.)

In this tutorial, we use the JS function setInterval(), which you may have already used for other purposes in another class, as our ticker for the animation. We will be able to control the ticker in code, and we will also write our own tweening code. So we will control every aspect of the animation. It is more complex, but it is more flexible. And it helps you learn JavaScript, which is good, right?

To keep it as simple as possible, we will only animate simple properties of simple HTML elements in this tutorial. Of course, you can use this technique to animate SVG illustrations or more complex HTML elements, and even animate pixels in a canvas (that’s what we’ll do for the game). But here we keep it focussed and simple.

In this tutorial, you will write HTML and CSS. And you will write some JS code to animate the elements. The animation we want to make here is a simple ball that bounces up and down in a court.

Something like this:

Read the whole thing once before you start creating the animation. If you have issues with certain parts, ask me.

Part 1 — The Actors

Unlike the other animations, this time the animated elements will be plain HTML, with some CSS. We will create the elements we want to animate directly in code.

We want a bouncing ball, so we need two actors: a court and a ball. Both will be drawn using div tags. You can use other block tags if you prefer. In a plain HTML document, add the two elements. The ball must be inside the court. In the sample below, I have inserted the actor divs in a section, to keep it clean.

<!DOCTYPE html>
<html>
<head>
  <title>Bouncing Ball</title>
</head>
<body>
<section id="animation">
  <div id="court">
    <div id="ball"></div>
  </div>
</section>
</body>
</html>
        

Next, we will need to add simple, basic CSS to give these elements some properties, so we can see them. You can write this CSS in a style tag or in an external file; whatever you prefer. Make the court a square, and the ball a circle. It is easier to keep it simple for this exercise. Once you fully understand how it works, you can make your elements more fancy.

In my example, I have used the following CSS rules for the actors:

#court {
  position: relative;
  overflow: hidden;
  margin: auto;
  width: 300px; height: 300px;
  background: #eee;
  border: solid black 2px;
}
#ball {
  position: absolute;
  width: 100px; height: 100px;
  border-radius: 50%;
  background: #0f0;
}
        

You should understand most of the CSS properties in the above code. But let me explain a few things. The position property is very important. Because we will control the position of the ball to create the animation, we need to set these properties correctly. The court has to be set to position:relative; and the ball must be set to position:absolute;. This ensures that the court moves in the layout as a normal block element, but the ball is positionned within the court using absolute values. We will control its position to animate it.

The other property to look out for is the overflow. This makes sure that the content of the court never shows outside of the boundaries of the court. Overflow determines the visibility of elements that are written inside a tag, but rendered outside of the element boundary in the browser. If the ball goes outside the court, it will not show.

So, if you used the same code as me, your court and ball should look like this in the browser.

Part 2 — The animation code

In order to animate the ball within the court, we must write some JS code. There are three parts to the code we need: the global variables, the animation loop, and the trigger. It is important that you understand this. The basic concepts here are used in the game project as well.

Global Variables

Before we start animating, we need to create variables within the JS that will be used to make calculations. These are called global variables. They are set at the start of the program, and they are used throughout. In this animation, we need to bring the actors in the JS, we need to set the boundaries of the court (so the ball bounces), and we need a variable to track the ball’s position. We will also use this section of the JS code to place the ball in the horizontal centre of the court.

You will need a <script> tag to contain the JS code. As usual, write this tag at the end of of your HTML file, just before the closing body tag. All the code that follows should appear within this script tag.

So first, we need to create handlers for the two actors. This makes referring to them throughout the code easier. So we create two variables that refer to the elements in the DOM. Because the values of these references will not change in the program we write, we use the const command to create them, like this:

//The court
const court = document.getElementById("court");

//The ball
const ball = document.getElementById("ball");
    

Now we need a variable to control the vertical position of the ball. In our animation, the ball only moves up and down, so we only need one variable to control its position on the y axis. The animation will consist in changing the value of this variable every time the ticker ticks. You will see this variable used a lot in the animation code. If we wanted the ball to move left and right, we would need another variable. Notice that here, we use the let command to create the variable, because the value will change, that’s the whole point. The value of this variable will be translated to CSS in the animation code and applied to the top CSS attribute of the ball. (More about this later.) The ball starts at position 0, which is the top of the court, so we assign it the value 0.

//Position of ball (top)
let p = 0;
    

The next global variable we’ll create is the boundary of the bottom of the court. We need to calculate this because of the height of the ball. If the ball were flat, the bottom of the court would equal the height of the court. But because the ball has a height of its own, the bottom of the court – in the logic of the code – is the height of the court minus the height of the ball. This is maths, again, I know. We don’t want to have to calculate this every time we need it, so we make it a global variable. This one is also a constant.

//Lower point of court
const bottom = court.offsetHeight - ball.offsetHeight;
    

Finally, we need an operator to determine the direction of the ball. The position of the ball in time is determined by a calculation. In the math (or logical) context, every time the ticker ticks, the next position is either greater than the current position (ball is going down) or it is lesser than the current position (ball is going up). So in math terms, ball going down means addition, ball going up means subtraction. So we simply need to use a multiplyer that has a positive or negative value whenever we want to change direction – when the ball hits a court boundary. This will be our operator. When its value is positive, 1, the ball goes down; when it is negative, -1, the ball goes up.

//Operator (to change direction)
let oper = 1;
    

Before we get started on the next section of the code, we need to position the ball in the horizontal centre of the court. The ball will move up and down, but we want it to stay in the middle horizontally. It is easier to position the ball using JS, so here is the simple code to achieve this. Notice how we transform the numerical value of the JS calculation into a CSS value with a unit. We’ll do this to the vertical position as well later on.

//Place ball in horizontal centre of stage
ball.style.left = court.offsetWidth/2 - ball.offsetWidth/2 + "px";
    

Just to be sure you can compare your code with mine, here is how the whole Global Variables section should look.

/*** GLOBAL VARIABLES ***/
//The court
const court = document.getElementById("court");

//The ball
const ball = document.getElementById("ball");
 
//Position of ball (top)
let p = 0;

//Lower point of court
const bottom = court.offsetHeight - ball.offsetHeight;

//Operator (to change direction)
let oper = 1;

//Place ball in horizontal centre of stage
ball.style.left = court.offsetWidth/2 - ball.offsetWidth/2 + "px";
   

Next, we will write the animation loop.

Animation Loop

Now that we have our global variables, we can write the code that will set the animation in motion. The animation code is all built within a function. And we will call this function using the ticker later; the function will be called every time the ticker ticks. (If you’re following, the ticker’s rate sets the FPS of our animation.) So the first thing we do is create the function.

const bounce = function() {

};
    

I will not repeat the lines above in the code samples below, but all the code we will discuss in this section has to be written within this function (before the closing curly brackets). Note that there are different ways of creating functions in JS, this is done here using a reference method. Don’t worry too much about this for now.

The first thing we need to do in the loop is to check if the ball has reached a boundary of the court and needs to change direction – to bounce. Remember that we use the oper variable to determine the direction. So we make a test. If the position of the ball, p is greater than the bottom of the court (calculated in the global variables), or if it is lesser than the top of the court (which is 0), then mathematically invert the value of the oper: in maths, multiply the number by -1.

  //Detect reaching court boundary
  if (p > bottom || p < 0) {
    //Change direction
    oper *= -1;
  }
    

And then, we need to move the ball. Remember that this function will be called every time the ticker ticks. The purpose of this function is to move the ball, to create the animation. So this is what it does. We calculate the next position by adding 15 pixels (this sets the speed which can be different) in the current direction: positive is down, negative is up.

  //Move ball by 15px in direction of oper (logical, math)
  p = p + 15 * oper;
    

Once we have the numeric value of the next position, we need to translate it in a usable CSS value that we can assign to the top property of the ball. So we take the numeric value and add a unit to it, px, so we can assign it to the CSS.

  //Set ball at logical position (in CSS)
  ball.style.top = p + "px";
    

That’s it for the animation loop. Here is the whole thing for your reference.

/*** Animation Loop ***/
const bounce = function() {
  //Detect reaching court boundary
  if (p > bottom || p < 0) {
    //Change direction
    oper *= -1;
  }
  
  //Move ball by 15px in direction of oper (logical, math)
  p = p + 15 * oper;
  
  //Set ball at logical position (in CSS)
  ball.style.top = p + "px";
}
    

Trigger

Lastly, we need to start the animation. This is the easiest step. So we have setup the initial elements, and the global variables. Then we have written the code that calculates and controls the animation (the position of the ball). Now the last step is to start the animation by setting up our ticker, and calling the animation loop. The code looks like this.

/*** Trigger animation ***/
let i = setInterval(bounce,40); //runs at 25 frames per sec
    

This animation’s FPS is 25. The interval uses milliseconds. We set it at 40 milliseconds, so it will tick 25 times per seconds. (1000 divided by 25 equals 40. Maths again.) Note that setInterval does not run at the exact set interval all the time. In the game we will use a different ticker, and this one will have a better FPS rate and will be more accurate.

Congratulations! You have built an animation in pure JS. The result should look like what I have presented at the start of the tutorial.

One more thing is important to note. You will have more than one animation written in JavaScript in your showcase file. Be careful to use different names for the functions and variables of your different animations. Otherwise, you will have conflicts between them.

Extra — Animating Different Properties

In the main tutorial above, we have only manipulated the position of the ball. But, of course, with this method, you can animate any property of any object.

For example, we could make a hand that holds a glowing orb, like below. (This is a sample, the illustrations are crude – that “hand” haha. Yours should be more elaborate, and should follow your concept.)

I will let you figure out how this works. By now, you should be able to make it happen on your own. If you’re not sure, of course, all the code discussed in all the tutorials, including the hand and orb just here, exists right in the page. Just look at any tutorial’s page’s source, and you will be able to see exactly where the code goes and how it is built.