Animations and JS Object Literals

We just learned about arrays, an important data structure for storing multiple values. In this reading, we'll learn about another data structure that holds multiple values, namely objects. Later, we'll see them in action in the context of jQuery animations.

We've talked about objects before, and we used Date objects as examples. In this reading, we'll create objects from scratch, with complete control over the values stored in them.

You can copy the following code in the console of the browser to execute it.

var student1 = new Object();
student1.firstName = "Harry";
student1.lastName = "Potter";
student1.age = 17;
console.log(student1);

The result you will see is the following:

object in the console
How the student1 object prints in the JS Console

Let's see what the code does. In the first line, we declare a variable that will be storing an object, by invoking a special kind of function, called a constructor. When we created dates, we also used the constructor for dates, new Date(). We know that we're using a constructor, because of the special keyword new. (JavaScript programmers also have a convention — a general agreement — that constructors will be named with an initial capital letter and only constructors will be named like that.)

You might remember that when we declared variables before, we likened the process as one of storing a value in a box with a label. The role of the constructor is to create a special kind of box, that allows us to store many other values (properties) inside the box, instead of only one value at a time.

Then, in the following three lines, we added three properties to this object: firstName, lastName and age by also assigning them values. Printing the object on the console shows how all this information is now stored inside the variable person.

Visually, we can represent how this variable is stored in the computer memory, as shown below:

model of the object variable
A visual model of the student1 object

Object Literals

There is another (more compact) way for creating Javascript objects through the use of the object literal notation. We will use this exclusively from now on.

Concretely, the example we just saw can be rewritten in this way:

var student2 = {firstName: "Harry", lastName: "Potter", age: 17}
console.log(student2);

If you copy and paste this into the JS console, you will get the same result as before.

Syntax rules: An object literal

  • is enclosed in braces {}
  • has zero or more pairs of property names and associated values,
  • The property names follow the same rules as variables (letters, digits and underscores, starting with a letter)
  • The values can be any data type: numbers, strings, booleans, date objects, arrays, even other objects.
  • The property names are separated from the value with a colon
  • The property-value pairs are separated from one another with commas.

Objects versus Arrays

Since objects and arrays both store multiple pieces of information, how do you choose between them? The answer depends on how you expect to access (get or store) the data:

  • If you expect to organize them by number, arrays are best. This is often the case when all the values are uniform or homogeneous. An array of URLs is good for a slideshow, and we access them by a numerical index.
  • If you expect to organize them by name, objects are best. This is often the case when the values are heterogenous: different kinds or types of things. Our student1 example had two strings (firstName and lastName) and one number (age) in it.

You can, of course, combine these ideas. Here's an array of three students, along with some code to access some of the data in it. Can you guess what the alert will show? Try it!

var students = [ {name: "Harry Potter", pet: "Hedwig", age: 17},
                 {name: "Ron Weasley", pet: "Scabbers", age: 17},
                 {name: "Hermione Granger", pet: "Crookshanks", age: 17}];
alert( students[1].pet );

However, you need not worry about these more complex uses of arrays and objects. In this reading, we'll stick to simple objects where all the values are numbers.

Animations

As you know, jQuery can read the current value of a CSS property of an element and it can also dynamically change that value. Consider the following figure, which is just a box with a green background:

box1
A box with ID box1 and a background color

Try the following code, which reads the current width of the box, and updates it to make it 50px larger, until it reaches a maximum width of 300px. Click the button as many times as you like.

var curr_width = parseInt( $("#box1").css("width") );
console.log("curr_width is "+curr_width);
if( curr_width < 600 ) {
   curr_width = curr_width + 50;
   $("#box1").css("width", curr_width+"px");
}

Now, imagine a process that will click that button for you, maybe using smaller steps and smaller time intervals, so that the box smoothly widens to some desired target value.

box2
A box with ID box2 and a background color

jQuery provides a method to do that, namely the .animate() method. The way we will use it, that method takes two arguments:

  • properties: this is a JS object literal consisting of CSS properties and the target values you'd like them to have.
  • How long you want the animation to run, in milliseconds.

Let's see it in action. Here's a new box, with ID=box2:

$("#box2").animate( {width: "600px"}, 2000 );

Wasn't that cool? Did you notice how it accelerated at the beginning and decelerated at the end? Very nice effects.

Animations with Multiple Changes

The jQuery animate method works with lots of CSS properties, but not all of them. They have to have numerical values, since what's happening under the covers is the successive incrementing that we saw earlier. You can't animate a change in font or a change in color (well, there's a plugin that allows that). However, you can change multiple CSS properties at once. That's why the first argument is an object literal: you can specify a set of CSS properties and the target values you want, all in one convenient package.

We can even chain a series of animations together. Here's an example, where we enlarge three properties simultaneously over the course of 2 seconds, and then shrink them back in just 1 second. Click the button as often as you like.

box3
A box with ID box3 and a background color
$("#box3")
   .animate( {width: "600px", height: "300px", fontSize: "45px"}, 2000 )
   .animate( {width: "50px", height: "50px", fontSize: "15px"}, 1000 );

(Those of you with sharp eyes may spot that we renamed the CSS property font-size to fontSize. That's a standard pattern to convert CSS properties with hyphens to acceptable JS property names: remove the hyphens and capitalize the letter after the hyphen.)

Moving An Element

We learned about position:relative and position:absolute. With those ways of positioning, we used properties like left and top to position elements. jQuery animations can smoothly modify those properties for you as well, so you can move elements on the page.

In the following figure, we use position:absolute (relative to the figure) to position the figure of Harry and the broomstick.

Harry Potter broomstick
$("#broomstick").animate({left: "200px"},500);

We should rename that "execute it" button to be accio broomstick!

Carousels

We now know all that we need to understand how to make a cool effect for our automatic slideshow (carousel). The basic ingredients are these:

  1. We'll use CSS to lay out all the images in the slideshow side by side, left to right. This might be really wide, much wider than our browser, but don't worry.
  2. We'll put all the images in a container that is only as wide as one slide, so that the others will stick out to the left and right of the container
  3. We'll use the CSS overflow:hidden to ensure that the ones that stick out will not be seen by the user.
  4. We'll use the position:relative and left properties to move the assembled slides to the left, so that a different one shows.
  5. We can animate that change to the left property, just as we moved the broom above.

Let's take those one step at a time.

All Images Left to Right

We'll put the images in an unordered list. Since each of our slides is 256px wide, the UL will be 1024px wide (though anything wider than that would also work). We'll make the slides float:left so that they'll be arranged left to right.

  • Harry Potter
  • Ron Weasley
  • Hermione Granger
  • Draco Malfoy

Here's the HTML code:

  



And the CSS code:





A One-Slide Container

Here's our next version:

  • Harry Potter
  • Ron Weasley
  • Hermione Granger
  • Draco Malfoy

The HTML code is unchanged; here is the CSS code, which only adds one rule. You're strongly encouraged to right-click on the image above and do inspect element, so that you can use the Chrome Inspector to see that the other images are all there. Try unchecking the checkbox next to overflow:hidden or width:256px on the #slides2 element.





Animating the Sliding

Now, let's animate the sliding of the entire unordered list. Since this is an editable execution box, try different target values for the left property. From the starting position where left is zero, negative values move the list to the left, positive values move it to the right. If the target value is a multiple of 256px (the width of a slide), the display moves to a slide boundary.

  • Harry Potter
  • Ron Weasley
  • Hermione Granger
  • Draco Malfoy

Note that the JS object has a target value, not an amount by which to change. So, to move from slide to slide, we need to calculate the new target value.

Calculating Target Value for Left

If we are keeping track of the index of the current slide in a global variable, say currentSlideIndex, we can use that to calculate the desired target value. Here's a slideshow that does that. (Assume that the currentSlideIndex is initialized to zero when the page loads.)

  • Harry Potter
  • Ron Weasley
  • Hermione Granger
  • Draco Malfoy

Note that we take advantage of the fact that when the selector matches more than one element, jQuery returns an array-like value that has a .length property.

Additional Material

The following material is optional, but is here for the interested student.

Embedded Objects

The values in an object are not limited to simple objects like the one student1 example at the beginning of the reading; we can create objects that are composed of other objects. Let us see an example:

var hogwartsHouses = {gryffindor: 
                       {founder: "Godric Gryffindor", mascot: "lion", value: "courage"},
                      hufflepuff:  
                       {founder: "Helga Hufflepuff", mascot: "badger", value: "hard work"},
                      rawenclaw: 
                       {founder: "Rowena Rawenclaw",mascot: "eagle",value: "intelligence"},
                      slytherin: 
                       {founder: "Salazar Slytherin", mascot: "serpent", value: "ambition"}
}

In this example, the object hogwartsHouses has four properties and each of them has as a value an object. Running this code on the console and accessing the properties, will verify this fact:

composed objects
What the JS Console shows when access properties of our hogwartsHouses object of object

JSON

JSON (JavaScript Object Notation) is the most popular open format for transmiting data objects consisting of property/value pairs over the Web. It uses the Javascript object literal notation to represent objects and it can be parsed by every programming language. It can only contain properties, not method definitions.

All major websites use JSON to transmit data from their servers to the clients. Here is an examples:

  • Google uses JSON to transmit data from all of its services. Here is an example of Google Books API that has information about all published versions of Pride and Prejudice.

© Wellesley College Computer Science Staff. This work is licensed under a Creative Commons License. Date Modified: Sunday, 28-Aug-2016 13:09:42 EDT