(Updated: 2007.02.20)

JavaScript: Image Browser

Last Updated by Sherry Wang
Comments to Steve Wolfman.


Sources and contributions: This lab was created by Dan Tulpan, revised by Sherry Wang.


Contents


Objectives

In this lab you will learn how to create a JavaScript-powered image viewer, which can be embedded easily in your course web page.

You will use JavaScript to generate web pages with dynamic content that contain images and text. You will be able to create a web page like this sample after the lab.

Interested in creating an image browser that will amaze the visitors of your web page? This lab will provide you with the necessary information to achieve this goal. A brief outline of the main learning goals of this lab follows:

  1. Gain experience in the use of JavaScript to dynamically display images.
  2. Understand how to use arrays to index data.
  3. Gain a first, basic understanding of the idea of iteration ('for' loop).
  4. Learn how to use a random number generator to implement random choice.
  5. Understand how to use an auxiliary variable to implement swapping.
  6. Learn how to sort an array by swapping elements
  7. Create thumbnails
  8. Source code and pictures

Lab Overview

This lab will guide you through JavaScript subtleties to enable you to create dynamic Web-based publications that contain buttons and images.

You will learn advanced JavaScript skills to create a dynamic web page.


Before the Lab

Before the lab you should be familiar with how to edit an HTML file and have some basic knowledge of JavaScript. In particular, you should know about if-statements, Be sure to review your notes and read all sections of this lab prior to your lab session and to make sure that you can understand what is being described here. Your TA will be evaluating your work at the end of your lab session.

(Note: You might like to try using Crimson Editor instead of Notepad or WordPad. Crimson Editor is a free program that you can download at home. Some features you might find useful are syntax highlighting, tab editing, re-opening recent files, among others. You can hit ALT-B to automatically open an HTML file in a browser. To find Crimson Editor, go to your L: drive -> Crimson Editor directory -> open cedt.exe.)


During the Lab

1. Gain experience in the use of JavaScript to dynamically display images.

An image browser is an application that allows someone to see images sequentially by simply pressing navigation buttons. The image browser that you will build during this lab consists of six buttons (Back, Next, Random, Shuffle, Sort, Thumbnails), one text field and an image. Every time a button is pressed, a message will be displayed in the text field. When Back, Next or Random is pressed, the text field will display the descriptive text associated with an image (and a new image will be presented to the viewer). When Shuffle, Sort and Thumbnails are pressed, the text field will display the name of the action performed. You are provided with a simple skeleton for the JavaScript code, which includes the complete implementation of the actions associated with the Next and Random buttons. In this lab you are asked to add to this skeleton code by implementing additional functions.

What you need to do:

  1. Download the skeleton for the JavaScript code and put it in your own directory.
  2. Create a new directory called "pictures" in the same directory.
  3. Download the pictures and unzip the contents into the "pictures" folder. Alternatively, you can use your own pictures for 1 bonus mark.

2. Understand how to use arrays to index data.

An array can be seen as an ordered arrangement of data elements. Most programming languages use arrays to store and manipulate information. JavaScript is such a programming language, and in this lab you will use arrays to store numbers (integer or real) and strings.

How to create an array:

/* Creates an array */
var my_array = new Array(10);

This piece of code creates an array called my_array with 10 elements. The elements in this array are given indices, numbered from 0 to 9, with which you use to access the element. For example, the first element is referred to as my_array[0], and the last element is my_array[9]. The last index is always (the number of elements - 1).

The skeleton provided contains five arrays that store (how many elements do the arrays have?):

/* define array with image locations */
/*-----------------------------------*/
var pics = new Array(num_pics)
/* define array with image text */
/*------------------------------*/
var pics_text = new Array(num_pics)
/* define array with image heights */
/*---------------------------------*/
var pics_height = new Array(num_pics)

/* define array with image widths */
/*--------------------------------*/
var pics_width = new Array(num_pics)

Task 1: Add 4 new images [2 marks]

Your first task is to add four new images to the image browser. The source code provided contains JavaScript code for only four images, namely f1.jpg, f2.jpg, f3.jpg and f4.jpg that can be found in the /pictures directory. That directory contains four more pictures, namely f5.jpg, f6.jpg, f7.jpg and f8.jpg. As you can easily notice in the JavaScript code, for each image you must specify its width and height, the image location and the descriptive text associated with each image.

For example, the first image has the following parameters:

pics_width[0] = 100;
pics_height[0] = 100;
pics[0] = "./pictures/f1.jpg";
pics_text[0] = "my text for image 1";

Note: Do not forget to increment the index of each array before adding a new item to it. Otherwise, you will overwrite the content of the previous values.

3. Gain a first, basic understanding of the idea of iteration ('for' loop).

Let's start this topic with an example. Assume that you must write a very simple JavaScript code that prints on a web page the numbers from 1 to 3. You can easily accomplish this task by writing the following code:

<script type="text/javascript">
   document.write('<p>1</p>');
   document.write('<p>2</p>');
   document.write('<p>3</p>');
</script>

But what happens if someone is asking you to write a JavaScript code that prints on a web page the numbers from 1 to 5000? Writting 5000 document.write() lines is clearly not a good solution. Apparently you need to find a way to repeat the document.write() procedure 5000 times. The 'for' loop allows you to solve the problem as follows:

for (i=0; i<5000; i++)
{
   document.write('<p>i+1</p>');
}

The first line can be read as follows "For each value of i from 0 to 4999, execute the statement from the body of the 'for' loop." The body of a 'for' loop is defined as the set of statements included between braces {}. Note that more than one statement can be placed in the body of a 'for' loop. At the beginning of the for-loop, the variable i is set to 0. At the end of each iteration, i is incremented by one, and the body of the for-loop executes while i < 5000. When i is equal to 5000, the body of the for-loop will not be executed.

Implementation of the Next button

The implementation of the behavior for Next button can be found in the function next_image().

function next_image()
{
  // Increment the index of the current image by 1
  current_img = current_img +1;

  // What to do when you reach the end
  if (current_img > num_pics-1)
  {
     current_img = 0;
  }

  // Update what's being displayed on the webpage
  document[current_img_name].src = pics[ current_img ];
  document.form1.text1.value     = pics_text[ current_img ];
  document.img1.width            = pics_width[ current_img ];
  document.img1.height           = pics_height[ current_img ];
}

First, the value stored in the variable current_img is incremented by one.  Note that the variable current_img stores the index of the image that is currently displayed.  If the incremented value of current_img gets larger than the number of pictures - 1 (the index of the last element), then we set the current_img to be the one with index zero, thereby setting it to the first picture. Thus all images will be displayed in a circular fashion. After the current_img index has been incremented, the form values of the elements displayed on the main web page are updated to correspond to the current image.

NOTE: When refreshing this page to see the effects of your modifications, use SHIFT+"refresh" instead of just "refresh".

Task 2: Implement the Back button [2 marks]

Your second task is to implement the behavior of the Back button in a similar fashion as we have done for the Next button. The difference lies in the fact that you must decrement the value of the current image index and must check if the index gets lower than zero. If the index becomes negative, than you must set the value of the current image value to be equal with the index of the last image (remember that counting starts from zero).

You must insert your JavaScript code in the function back_image().

4. Learn how to use a random number generator to implement random choice.

The Rand button enables a viewer to select a random image for visualization.

function rand_image()
{
  // avoid displaying the same image twice
  do
  {
      // generate a random image index
      new_img = Math.floor(Math.random()*num_pics);
  }
  while (new_img == current_img);

  current_img = new_img;

  document[current_img_name].src = pics[ current_img ];
  document.form1.text1.value     = pics_text[ current_img ];
  document.img1.width            = pics_width[ current_img ];
  document.img1.height           = pics_height[ current_img ];
}

The first statement you should note is

new_img = Math.floor(Math.random()*num_pics);

To try to understand what is happening here, let's go through it step by step. First, Math.random() generates a random number between 0 and 1, including 0 but not including 1. (Just in case you're curious: Math is an object, like document, which you're seen before. Objects can come with their own functions (like next_image() and back_image()), which you can call by the syntax: object.function()) We then multiply this number by num_pics to scale it so that it ranges from 0 to num_pics. Then, we take this resulting number and pass it to the Math.floor() function, so it can remove the extra decimal places. Note that the index of an array must be an integer.

This structure might be new to you:

The Do-While loop

do {

  // statements here

} while( condition );

This is called a do-while loop, a method of iteration like the for loop. It first executes once the statements in the do { ... } block, and if the condition in while( condition ) is true, the statements in the do block are executed again (and again and again...) until the condition is false.

In our rand_image() function, the condition we test is whether the new index (new_img) we've generated randomly is the same as our current index. If it is, then we generate another one, and so on until the condition is no longer true, i.e. a new index has been generated.

Finally, we set the index current_img to new_img, and update the display accordingly.

5. Understand how to use an auxiliary variable to implement swapping.

Swapping the values of two variables is an important basic operation that may come handy every once in a while. To better understand how swapping is done, imagine the following scenario. You are given two glasses: one has water the other has oil. You must swap the content of the two glasses without mixing the two liquids. You are provided a third glass as a helper. To swap the content of the two glasses with liquids you need to follow a rigorous set of operations:


Figure 1: Swapping

In the same manner as described above, someone can exchange the values of two variables in JavaScript or any other programming language. Instead of a third glass, though, we create a third auxiliary variable as a temporary storage place.

Task 3: Implement the Shuffle button [2 marks]

Your third task is to implement the behavior associated with the Shuffle button. The Shuffle button allows a viewer to shuffle the order in which images will be displayed on your web page. Here is a brief description of how you may attempt to solve this problem.

for each image i {
   1. generate a random index between i and num_pics - 1
   2. swap image i with the picture at the randomly generated index
}

You must modify the JavaScript code in the function shuffle_images(). You only need to provide the swapping functionality.

6. Learn how to sort an array by swapping elements

After the pictures have been shuffled, we will now try to restore their initial increasing order. The algorithm we will use is called Selection Sort, which described here:

for each image i {
   1. find the index of the image whose name is alphabetically first
      (the "minimum" image) between indices i and num_pics - 1
   2. swap image i with this picture at this index
}

As the for-loop iterates through the pics[] array, it will set each image i to the image with the next lowest number. You might notice that this algorithm similar to the shuffle_images() function. The only difference is that in shuffle_images(), the index retrieved in the first step of the for-loop is randomly generated, whereas the one used in sort_images() is the index of the image whose name is alphabetically next. A function called find_minimum(start, end) has been implemented to aid us in this first step:

/* Finds the index of the "minimum" image in the pics[] array between
   indices start (inclusive) and end (exclusive). */
/*---------------------------------------------------*/
function find_minimum(start, end)
{
   var min = start;
   for(j = start; j < end; j++)
   {
     if( pics[j] < pics[min] )
     {
       min = j;
     }
   }
   return min;
}

At the end of this function there is a statement, return min, which causes this function to return a value (the index of the "minimum" image) every time it is called. This function takes two parameters, start and end, which are the boundary indices of the array in which we are searching. For example, find_minimum(3, 6) will search in the pics[] array from index 3 to (but not including) index 6.

Task 4: Implement the Sort button [2 marks]

Your fourth task is to implement the behavior associated with the Sort Button in the function sort_images(). (HINT: start by making a copy of your code for shuffle_images(), then figure out what you need to change to sort the images. Notice how similar the pseudocode for the two parts is! The code is also very similar.)

7. Thumbnails button (2 BONUS MARKS)

The Thumbnails button allows a viewer to display the thumbnails view of all pictures in the directory "./pictures". The thumbnail of a picture is the 'shrunken' version of the original picture.

Here, a thumbnails view can be implemented as an HTML table. Feel free to choose the number of columns in the table and height and width of the cells. In each cell of the table you can insert one picture. The width and the height of the picture may not be the same and they may also be different than the width and the height of the cells. You can adjust the width and the height of each picture to be displayed as a thumbnail, so that either their width or their height (which ever is greater) equals the width or the height of the cell. For example if the width and the height of the cell is 100 pixels and you must include in it the thumbnail of a picture of height 200 and width 150, you can set the height of the picture to be 100 and you can adjust its width so that the aspect ratio (width / height) remains unchanged, thus still being able to display a "recognizable picture" as thumbnail.

You must insert your JavaScript code in the function thumb_images().

8. Source code

The source code of this lab (my_image_viewer.html) can be found here.

The images provided in this lab must be placed in a separate directory called /pictures that is in the same location where the my_image_viewer.html file resides. The image files are:


f1.jpg

f2.jpg

f3.jpg

f4.jpg

f5.jpg

f6.jpg

f7.jpg

f8.jpg

They can also be downloaded in a zip file here.

Note: These pictures have been taken in the Butterflies Gardens, Victoria, BC. More information can be found here.

For 1 bonus mark:

Instead of using these provided images, you can create your own for this lab as long as they satisfy a few requirements. First, you must have at least 9 images, with at least one of your own and as many of the provided images as you like. The image file names must be sequentially numbered such that all characters before the numbers are identical (e.g. the ones given above all start with "f"). This is so that the order of the pictures can be determined from the file names. If you are using 10 or more pictures, make sure that the single-digit numbers (0-9) have an additional zero in front (e.g. "f09.jpg" comes before "f10.jpg"). You might need to modify the pics[] array in the source code to refer to the locations of your own pictures. Finally, your images must have sequential numbers visible on the pictures themselves, like the ones given above. This is because we need to easily distinguish between shuffled and sorted states. (If you want to add text to your pictures in GIMP, you can use Filters -> Text -> Freetype.)

After the Lab [2 marks]

Answer 2 of the following questions:

  1. This code seems similar to the for-loops we've used in this lab, but it causes a problem on the very last iteration. What's wrong with it? (Don't worry about how quickly it modifies the image currently displayed)
    for(i=0; i<=num_pics; i++){
       document[current_img_name].src = pics[i];
    }
  2. var number = Math.floor( Math.random()*10 );
    generates a random number between 0 and 9. How would you generate a random number between 11 and 35? (HINT: take a look at the code for the shuffle_images() function)
  3. There are unknown values stored in a[0], a[1], a[2]. How would you set a[0] to a[2], a[1] to a[0], and a[2] to a[1] without losing any of the values?
  4. Given:
    function sum(a, b){
       result = a + diff(b, a);
       return result;
    }
    function diff(x, y){
       return x - y;
    }
    What is returned on this function call: sum(3, -5)?
  5. Why do you think dividing up code into functions is a good idea? Give at least 2 reasons.


Deliverables


Reference Links

  1. JavaScript Tutorial
  2. JavaScript Source - Free scripts, tutorials
  3. Doc JavaScript -- JavaScript Tutorials, JavaScript Tips, and JavaScript Tools