Articles Archive
Articles Search
Director Wiki
 

Creating a Digital Portfolio, Part 2

January 31, 2002
by Will Turnage

Last time, you learned how to import images into your Director movie and create thumbnails from those pictures using imaging Lingo. This week, things are going to get a bit more complicated. But when you're done, you'll be able to scroll through your thumbnails and view close ups of your images when you click on them, like this:

The first thing you should do in your portfolio is to scroll your image. All this requires is for you to attach a behavior on each of your up and down arrows. Inside these behaviors, you will send a scrollImage command to all the sprites, along with the number of pixels you want to scroll. For instance, on the up arrow, the code would look like this:

sendAllSprites (#scrollImage, -5)

And on the down arrow, the code would look like this:

sendAllSprites (#scrollImage, 5)

The next step would be to go to your main behavior and write the code for the scrollImage handler which will process the data and display the thumbnails correctly.

on scrollImage me, howMuchToScroll
  pVerticalOffset = pVerticalOffset + howMuchToScroll
  pVerticalOffset = max (0, pVerticalOffset)
  pVerticalOffset = min (pVerticalOffset, pThumbImage.height - pVisibleHeight)
  me.displayThumbnailImage ()
end

This handler starts by adding the amount you are going to scroll to the vertical offset of your thumbnail images. However, in order to prevent your thumbnails from just scrolling way off the screen, you need to add some high and low limits. You start by using the min function to make sure that the vertical offset isn't below zero, and then you use the max function to make sure that the vertical offset doesn't exceed the maximum amount you can scroll. To determine the maximum amount you can scroll, take the height of all of your thumbnails and then subtract the height of the image that the user is actually seeing.

Once your vertical offset has a new value, you call the displayThumbnailImage handler. This is a new handler in your behavior that controls the drawing of all the thumbnails on screen.

on displayThumbnailImage me
  tempImage = image(pThumbImage.width, pVisibleHeight, 16)
  imageSourceRect = rect(0, pVerticalOffset, pThumbImage.width , pVerticalOffset + pVisibleHeight)
  tempImage.copyPixels(pThumbImage, tempImage.rect, imageSourceRect)
  sprite(me.spriteNum).member.image = tempImage
  sprite(me.spriteNum).member.regPoint = point(0,0)
end

This handler starts by creating a new, empty image that is the exact width of your thumbnails but only as high as pVisibleHeight, which is a variable containing an amount you specify at during authoring. Next, you take your value for the vertical offset, and you use that to calculate the exact portion of your main thumbnail image that is going to be displayed. Once you have determined that rect, then you just copy those pixels onto your blank image, and set this new image object to be the image of the sprite on screen. The end result is that your images appear to be scrolling up and down.

The last feature you should add to your project is the ability to display larger versions of your thumbnail images when the user clicks on the thumbnail. Displaying the large image isn't too hard, but what is hard is finding out which image the user clicked on. Normally, you might have had a separate sprite for each thumbnail, in which case it would be easy to determine which thumbnail the user clicked, however, since you're using one sprite and imaging Lingo, you have to search through a list of rects to find out what the user clicked.

clickFlag = false
    repeat with i = 1 to pRectList.count
      if (the clickLoc - sprite(me.spriteNum).loc).inside(pRectList[i].offset(0, - pVerticalOffset)) then
        clickFlag = true
        exit repeat
      end if
    end repeat

This code starts by setting a local flag variable to false. Next, it goes through a list of thumbnail rects and checks to see if the location you clicked on the screen is inside the rect of a thumbnail. The trick here is that you have to take into account the vertical offset from your scrollbars in order to make sure that your detection is accurate. If you find that the user did click inside an image, then you exit the repeat loop and set your clickFlag variable to true.

If the user did click within a graphic then you need to display the image so that it takes up a large part of the screen. The code for that handler looks like this:

if clickFlag then
      tempImage = image(pThumbImage.width, pVisibleHeight, 16)
      
      if pImageList[i].width > pImageList[i].height then
        newHeight = (pImageList[i].height * pFullScreenHeightOrWidth) / pImageList[i].width
        heightOffset = (tempImage.height - newHeight) / 2
        newWidthOffset = (tempImage.width - pFullScreenHeightOrWidth) / 2
        destRect = rect(newWidthOffset, heightOffset, newWidthOffset + pFullScreenHeightOrWidth, heightOffset + newHeight)
      else
        newWidth = (pImageList[i].width * pFullScreenHeightOrWidth) / pImageList[i].height
        widthOffset = (tempImage.width - newWidth) / 2
        newHeightOffset = (tempImage.height - pFullScreenHeightOrWidth) / 2
        destRect = rect(widthOffset, newHeightOffset, widthOffset + newWidth, newHeightOffset + pFullScreenHeightOrWidth)
      end if
      
      tempImage.copyPixels(pImageList[i], destrect, pImageList[i].rect)
      sprite(me.spriteNum).member.image = tempImage
      sprite(me.spriteNum).member.regPoint = point(0,0)

      pFullImage = true
    end if

This code starts by creating a new image that's the same size as the visible region of your thumbnails. Next, it determines if the image that it's going to display is portrait- or landscape-oriented. Depending on the results, you calculate the on-screen rect that will stretch the image to your specified size, while ensuring that the image proportions remain intact and that it is centered on the screen. Once you're done calculating the rect, then you copy the image so that it fills the screen.

The last step is to set the pFullImage variable to true. This is used so that when the user clicks on the full screen image, it will toggle back to the thumbnail display. So in your behavior, you would say

on mouseDown me
   if pFullImage then
    me.displayThumbnailImage()
    pFullImage = false
  else
     -- the thumbnails are showing so display the closeup image

This way, when you click on the image gallery, if a full image is being displayed, it will automatically display the thumbnail image. However, if the thumbnails are showing, then it will go into the code you just wrote in the previous section.

And that's all there is to scrolling the thumbnails and displaying full screen images. Next time, you'll learn how to display information about your photos.

A sample Director 8 movie and images are available for download in ZIP (500K) or HQX (600K) archive format.

Will Turnage is a multimedia programmer based in New York City. In addition to his weekly role as Director Online's Multimedia Handyman, he is also the Technology Director for Sony Music's Client Side Technologies Group. You can read more about his work at http://will.turnage.com/.

Copyright 1997-2017, Director Online. Article content copyright by respective authors.