Loading Remote Images into the Slider

In the previous example, we looked at loading images that were locally available. This time, we will look at loading images from a remote location. The main difference in this scenario is that we will need to preload the images before setting the castmember fileName (otherwise the image of the linked file will not be available).

View Demo | Download Source

Like the previous example, the first step is to get a list of files to load. However, unlike the local file example, this cannot be done by shockwave: We need to create a server-side script (in PHP, ASPX etc) to return that list and use some net lingo to get the list. Here is an example PHP script to lists the images in a directory:

[PHP SCRIPT]
$rootpath = "/Path/to/SliderImages";
$url = "http://URL/to/SliderImage";
$listableExts = array('jpg','gif','png','jpeg');
$dir = opendir($rootpath);
$out = "[";
while ($thisfile = readdir($dir)) {
  $fname = "$rootpath/$thisfile";
  if (is_file($fname)) {
    if(strpos($thisfile,'.')!==false){
      $ext = explode('.',$thisfile);
      if(in_array(strtolower($ext[count($ext)-1]), $listableExts)){
        $out .="\"$url/$thisfile\",";
      }
    }
  }
}
closedir($dir);
$out = rtrim($out, ","). "]";
echo $out;

If you dont have access to any server side scripts, you could just use a text file that contains a list of all the images. If you want to add more images, simply edit the text file.

To retreive this list of images, we will need to use an object to handle a Network operation. Once we have the list of files, we need to go through a preload each file.

Diagram of interacting objects
Main objects involved in retrieving a list of images, preloading them and then loading the images into the slider

Here is the behaviour that inherits the "HorizontalSlider.class" discussed previously. As part of its initialise process, it creates an "imageLoader" object and tells this imageLoader the URL to get the list of images from.

-- create an Object to load up the images
  -- #### CHANGE THIS TO YOUR SERVER ADDRESS ####
  imageListSource = "http://vs4/GetImageList.php?"; 
  imageLoaderDaemon = script("ImageLoader.NET").new()
  imageLoaderDaemon.loadImagesTo(me,imageListSource)

The imageLoaderDaemon is created and sent a "loadImagesTo" message where we specify what object the Daemon should try and load images into. We also specify the URL that it uses to collect the list of images.

The "loadImagesTo" method of the imageLoaderDaemon looks like this:

on loadImagesTo (me, theTargetObject, URL)
  
  myTarget = theTargetObject
  -- query the url for the list of files
  netOp = script("NetOP.GetText").new(URL)
  netOp.addListener(me)
end

Basically, all that happens here is the imageLoaderDaemon keeps a reference to the object it will load images into, and then it starts a GetNetText operation to get the list of images.

Once the imageLoaderDaemon has this list, it then loops through the list preloading each image using a "NetOp.Preloader" object (discussed in the Preloading tutorial). This preloader object will report the status of the preload back to the imageLoaderDaemon, so the imageLoaderDaemon will use a ProgressBar widget to draw a progress bar into the tile. Once the image has been fully downloaded, the imageLoaderDaemon then inserts the image into the slider object, and starts downloading the next image in the list.

Here is the full HorizontalImageSlider.Behaviour script:

HorizontalImageSlider.Behaviour

property ancestor
property myMidH, myShift, myAlpha, myOffset
property myTrackingFlag, myStartH
property mySlideLeftRect, mySlideRightRect

on beginSprite me
  
  thisSprite = sprite(me.spriteNum)
  thisRect = thisSprite.rect
  thisMember = thisSprite.member
  thisCanvas = thisMember.image
  thisCanvas.fill(thisCanvas.rect, rgb("#000000"))
  
  --
  myOffset = point(thisRect.left, thisRect.top)
  myMidH = thisSprite.left + (thisSprite.width/2)
  
  
  -- create the slider object
  ancestor = script("HorizontalImageSlider.Class").new()
  me.Initialise(thisCanvas, thisCanvas.rect)
  
  -- create an Object to load up the images
  -- #### CHANGE THIS TO YOUR SERVER ADDRESS ####
  imageListSource = "http://vs4/GetImageList.php?" 
  imageLoaderDaemon = script("ImageLoader.NET").new()
  imageLoaderDaemon.loadImagesTo(me,imageListSource)
  
  -- create the 'hot spots' for sliding
  mySlideLeftRect = rect(thisSprite.left, thisSprite.top, \
  thisSprite.left + (thisSprite.width/3), thisSprite.bottom)
  mySlideRightRect = rect(thisSprite.right-(thisSprite.width/3),\
  thisSprite.top, thisSprite.right, thisSprite.bottom)
  
end

on endSprite (me)
  -- clean up the canvas 
  thisSprite = sprite(me.spriteNum)
  thisMember = thisSprite.member
  thisCanvas = thisMember.image
  thisCanvas.fill(thisCanvas.rect, rgb("#000000"))
end	


on enterframe (me)
  if myTrackingFlag then
    -- the mouse was clicked on this sprite
    if not (the mouseDown) then 
      -- stop tracking
      myTrackingFlag = 0
    else
      -- 'drag' the slider to the current mouse location
      mH = the mouseH
      amt = myStartH - mH
      myStartH = mH
      me.Slide(amt)
    end if
  else
    p = the mouseLoc
    if inside(p, mySlideLeftRect) then
      proposedAmt =  myShift -1
      myShift = Max(-10, proposedAmt)
      
    else  if inside(p, mySlideRightRect) then
      proposedAmt =  myShift + 1
      myShift = Min(10, proposedAmt)
      
    else
      -- slow down to a stop
      myShift = myShift * 0.75
      if abs(myShift) < 2 then myShift = 0
    end if
    me.Slide(myShift)
  end if
  
  
on mouseDown (me)
  ClickedTile = me.GetTileIDAtPoint(the mouseLoc - myOffset)
  if voidP(ClickedTile) then return 
  myTrackingFlag = 1
  myShift= 0
  myStartH = the mouseH
  me.SelectTileByID(ClickedTile, (the shiftDown))
  sendAllSprites(#ImageSelected, ClickedTile)
end

The 'imageLoaderDaemon' script is detailed next. It uses the "NetOP.GetText" script discussed elsewhere to ask the server for a list of images. Once it has the list, it loops through the list and downloads each image:

-- loads images from a remote directory (for shockwave)
property myTempBitmap, mySlider, myIndx, myImagesToLoad
property myTarget
property myProgressBarObj


on new (me)
  
  myTempBitmap = member("ImageLoader.net.bitmap")
  if myTempBitmap.type <> #bitmap then 
    myTempBitmap = new(#bitmap)
    myTempBitmap.name = "ImageLoader.net.bitmap"
  end if
  return me
end

on Destroy (me)
  -- erase the bitmap
  if myTempBitmap.ilk = #member then erase myTempBitmap
  -- void our reference to the slider
  myTarget = VOID
end

on stopMovie (me)
  -- will get this message if the timeout is active
  me.Destroy()
end

on loadImagesTo (me, theTargetObject, URL)
  
  myTarget = theTargetObject
  -- query the url for the list of files
  netOp = script("NetOP.GetText").new(URL)
  netOp.addListener(me)
end

-- messages sent by the getText netOP


on LoadNetText (me, netOp, args)
  if args.error = 0 then 
    -- set what the server returned
    imageFiles = value(args.text)
    if imageFiles.ilk = #List then 
      -- we successfully interepretted it as a lingo list
      
      -- now load some temporary images into the slider
      myImagesToLoad = [:]
      repeat with aFilePath in imageFiles
        myImagesToLoad.addProp(aFilePath, member("SliderLoadingImage").image)
      end repeat
      myTarget.LoadImages(myImagesToLoad)
      -- now start loading the real images
      myIndx = 0
      me._LoadNextImage()
    else
      alert "Error getting file list - received a " & imageFiles.ilk
    end if
  end if
  
end

-- messages sent by the preloader

on PreloadStatusUpdate (me, netOp, statusList)
  --  this is sent by the preloader object. We will use the information
  -- to animate a progress bar widget
  if statusList.state = "InProgress" then
    myProgressBarObj.ShowProgress(statusList.fractionDone)
  else myProgressBarObj.ShowWorking()
end

on PreloadFinished (me, netOp, errorNum)
  if errorNum <> 0 then 
    -- get a description of the error 
    description = netOp.GetErrorDescription()
    netOp.Destroy()
    alert "Network Error!" & return & description
  else 
    
    whichFile = netOp.URL
    myTempBitmap.filename = whichFile
    -- replace the 'loading' image with the real one
    myTarget.UpdateImage(myTempBitmap.image, whichFile)
    netOp.Destroy()
    -- now preload the next
    me._LoadNextImage()
  end if
end


------------


on _LoadNextImage (me)
  if myIndx <  myImagesToLoad.count then 
    -- still more images to preload.
    myIndx = myIndx + 1
    whichFile = myImagesToLoad.getPropAt(myIndx)
    netop = script("NetOp.Preloader").new(whichFile)
    netop.addListener(me)
    myTileCurrentlyLoading = myTarget.GetTile(whichFile)
    myProgressBarObj = script("Widget.ProgressBar").new()
    myProgressBarObj.Initialise(myTileCurrentlyLoading.image, rect(5,20,80,28))
    --    put "Loading " & whichFile
  else
    --    put "All Done"
  end if
end
Last updated 29th of March, 2006

© 2006 MeccaMedialight. Site Powered by Wrangler 8.