Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 832 of the free egghead.io lessons, plus get JavaScript content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

Just one more step!

Check your inbox for an email from us and click link to unlock your lesson.



GIF Loop Coder - Animation Functions

7:20 JavaScript lesson by

Animating with arrays is super simple with GIF Loop Coder, but using an animation function can give you the power to create much more complex animations.


egghead.io comment guidelines

Avatar
egghead.io

Animating with arrays is super simple with GIF Loop Coder, but using an animation function can give you the power to create much more complex animations.

Animating with arrays in Gif Loop Coder is drop-dead easy. You just supply two values to a property, and the value for that property moves back and forth between those two values. This can eventually become somewhat limiting. For example, if you want to move an object using an array of two values' position results in that object moving back and forth along a single line.

Perhaps you want to do something more interesting, like having the object move around in a circular or wavy path. The solution is an animation function. Here's how it works. In addition to passing a single value, an array of two or more values to a property, you can pass a function that will determine the value for that property on each frame.

I'll do that for the X position in this circle. The function will get a single parameter, "t," that will range from zero to one and relates to the current animation time. You set that function to return a value, and that's what gets assigned to the property on each frame.

For now, I'll just hard code it to return a single, static value, 200, which will put the object on the center of the canvas. That's what we get. Not very interesting, but before we go further, let's examine that "t" value. I'll just use console log to display its value and compile this.

Now, on the toolbar I can open up the console. Since GLC is running an embedded version of Chrome, we get all the Chrome developer tools. In the console we can see a stream of numbers going past. I'll pause and scrub through it to see what's going on.

At the start of the animation, "t" is zero, "t" moves up to one at the midway point of the animation and back down to zero at the end. Of course, this is in bounce mode. Switching over to single mode, "t" goes straight through from zero to one throughout the course of the animation. It's as if we've animated a property with a range of zero to one.

Now we can manipulate that value to return whatever we want. As a simple example, let's return t * 400. Now the object moves from the left side of the screen to the right, just as if we'd set the X property to an array of 0,400. You can do whatever you want here as long as it returns some number.

We can apply a conditional and say that If t < 0.5, return t * 400. Else return 200. Now the object will animate halfway across the screen, then stay still for a little while before moving back. It has the effect of inserting a pause in the middle of the animation.

Then you can do the opposite on the Y axis, saying If t >= 0.5, return t * 400. Else return 200. Now the object moves left to right, turns a corner and goes down and, of course, reverses that path on the return. Something you couldn't do with a single array.

One powerful effect is to use "t" as an input to some trigonometric function. I'll set Y back to a single value, and for X I'll say return 200 + math.cos(t * π * 2) * 150. This will cause the argument to math.cos to range from 0 to math.pi * 2π radians, which is equivalent to 0 to 360 degrees.

This results in values ranging from -1 to 1 in a smooth wave. Multiplying that times 150 gives us values from -150 to 150, and adding 200 to that gives us a range of 50 to 350.

As is, this looks a little bit confusing. The circle is moving between those two positions, but in a weird, bouncy way. We can clarify that by changing the Y property. I'll copy what we just have for X and apply that to Y. Then I'll change math.cos to math.sin.

Now that makes a lot more sense. We've just encoded the formula for a circle. Now, due to the nature of things moving in circles, the object starts and ends in the same position. We can switch over to single mode now, and things look pretty good. In fact, we can turn easing off, and we have a nice, smooth orbit.

For another example, I'll revert X to use a simple array that will move the circle from 0 to 400. I'll change that last value in the Y formula to 80. Now it's moving back and forth in a sine wave pattern.

Because we're using math.pi * 2π radians or 360 degrees, it does one full cycle of that sine wave. If we up that to math.pi * 4, we'll see that it has two waves. Eight gives us four waves as it moves back and forth.

To show off this next feature, I'll return this to math.pi * 2, bring the wave size down to 40, and make the circle radius a bit smaller at 10. You see that base animation that that gives us. Now, one of the more interesting things to do with GLC is to create lots of animating objects and see the patterns they create as they move together.

An easy way to do this is with a for loop. I'll wrap this circle creation code in one of those loops that goes from 0 to 400, incrementing by 20. This gives us 20 individual circles. Of course, they're all running the same animation code, so we only see one.

Now, my idea with numbering the for loop like I did here was to use that "i" variable to spread the animations out on the Y axis. Rather than saying return 200 + math.sin, etc., I'll say return i + sine, etc.

Since "i" is ranging from 0 to 400, that should do the trick, right? No, all the circles are down at the bottom. What happened? Well, realize this function is being called at runtime, evaluated over and over in each frame. That for loop happens just one time at the very beginning of the sketch before you see anything.

It loops through from 0 to 400 before anything ever animates. At the end of that, "i" is left with a value of 400. Later when those functions run, that's what they see. This is something that comes up from time to time in JavaScript. There are tricks to be able to handle it, usually involving nested functions to manipulate scope. GLC has you covered in a much simpler way.

You can assign arbitrary properties to the objects you pass into the add method. These properties can then be accessed from within the animation functions using this plus that property. For example, I'll create a property called ypoz, assigning "i" to it. Because this is a simple property assignment, it gets set the one time as the loop is running and will be equal to "i" at that point in the loop.

Every circle gets its own different ypoz property. Now in the animation function, we can access that using this.ypoz. Now we have all the circle wave animations spread out from top to bottom. Great. To make this a bit more interesting and to give you a sneak preview on the phase property, I'll set phase to i ÷ 400.

Now we have the start of something really interesting going on. A key feature of GLC is how easy it is to experiment with stuff like this, changing properties and being able to see the results right away. Keep playing with this one, adding, removing, changing things here and there, and see what it evolves into.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?