Remember saw Mac OS X built in features, where you can have a folder that having many pictures inside, and we can simply drag the mouse over the folder from left to right, to see all available pictures inside it. I try to somehow achieve that in a web page.

The first challenge is to get the mouse coordinate on the images itself, rather than relative to the screen. An useful codes provided by JavaScript is being handy, to attachEvent to the object.

Here is how to attach event to the respective custom function MouseMove, MouseUp and MouseDown:

IMG.attachEvent("onmousemove", MouseMove);  
IMG.attachEvent("onmouseup", MouseUp);  
IMG.attachEvent("onmousedown", MouseDown);  
IMG.attachEvent("onmouseout", MouseUp);

Which mean when ever mouse is moving on top of the IMG, it will trigger the MouseMove function.

The second challenge is to preload all the images before we can swap them on the “preview” mode. It is going to take a time to loading if we do.

function PreloadImage() {  
  for (intJ=0; intJ < PreloadImage.arguments.length; intJ++) {  
    imgPreload\[intJ\] = PreloadImage.arguments[intJ];  
  }  
  
  totalImgs = PreloadImage.arguments.length;  
  
  for (intI=0; intI < imgPreload.length; intI++) {  
    imgList[intI] = new Image();  
    imgList[intI].src = imgPreload[intI];  
  }  
}  

This is a simple function that loops all the argument passed in during calling the PreloadImage() method. Creating new image out from the path passed in as parameters, push it in to an array and ready to be used. There are some problem with the preload image, which might be able to solve using the img.onload to check for complete loading.

Here using two array, one is to keep the source path of each images, one is to keep each preloaded images. Another additional one imgIndices to be use to keep track of which image to swapped on which position.

function ExtendImage() {  
  var _Count = 0;

  IMG.attachEvent("onmousemove", MouseMove);  
  IMG.attachEvent("onmouseup", MouseUp);  
  IMG.attachEvent("onmousedown", MouseDown);  
  IMG.attachEvent("onmouseout", MouseUp);  
  imgWidth = IMG.width;  
  dragPerImg = Math.floor(imgWidth / totalImgs);  
  uBound = dragPerImg;  
  lBound = 0;

  for (intI=0; intI < totalImgs; intI++) {  
    _Count += dragPerImg;  
    
    if (intI === totalImgs-1) {
      imgIndices[imgWidth] = intI;  
    } else {
      imgIndices[_Count] = intI;  
    }
  }

  boundryWidth = _Count;  
}

Calculating the real image width, and each respective width for all preloaded image, the upper bound and lower bound of each section. Looping all images and pushing value of width and index to the array. Ex. imgIndices[768] = 2, means if the mouse x is on the 768, it will return the index 2 and retrieve preloaded images from the imgList array where it is loaded earlier.

The most important part is to calculate which X position should the changing the respective images, when dragging mouse across from left to right will swapping each preloaded images.

function MouseMove() {  
  if (mState === STATE_MOUSEDOWN) {
    mX = event.clientX;  
    mY = event.clientY;  
    flag = true;  
    
    while (flag) {  
      if (mX < uBound) {  
        if (mX > lBound) {
          imgIndex = imgIndices[uBound];  
          flag = false;  
        } else if (mX < lBound) {  
          swap = lBound;  
          uBound = lBound;  
          lBound = swap  dragPerImg;  
        } else if (mX === lBound) {  
          imgIndex = imgIndices[uBound];  
          flag = false;  
        }  
      } else if (mX > uBound) {  
        if (mX >== imgWidth) {  
          imgIndex = imgIndices[uBound];  
          flag = false;  
        } else {  
          swap = uBound;  
          uBound += dragPerImg;  
          
          if (uBound >== boundryWidth) {
            uBound = imgWidth;
          }  
          
          lBound = swap;   
        } else if (mX >= uBound) {  
          imgIndex = imgIndices[uBound];  
          flag = false;  
        }  
      }

    if (imgIndex !== prevIndex) {  
      IMG.src = imgList[imgIndex].src;  
      prevIndex = imgIndex;  
    }  
  }  
}

Because we were doing dragging to preview, so we wanted to check the mouse x only when there is dragging. To simulate dragging, check on the mouse state variable which will be assigned on each mouse event attached earlier. To get the correct x coordinate for each images, will need to get the width for each preloaded image to fit into the actual image width. For example, a image with 1024 width showing, with 4 images to be preload(including the initial one), that will be 1024/4, hence get the width for each preload image.

Slideover diagram
Slideover diagram

The diagram shows the calculation for each image width and hence we get the x point for each swapping point, 0, 256, 512, 768, and 1024. Which mean, when the mouse is dragging on the location 256-512, the image 2 will be swapped in, and so on. Floating point problem encountered, and it brings down the last image for the calculation, which need to be fixed using Math.round or Math.floor , and assigning last index of the array to 1024 instead of what have been calculated. To get correct x point (0, 256, 512, 768 and 1024) from the running mouse x position, checking and swapping of uBound and lBound value is needed.

There are bunch of cleanup should be done to increase the performance and things.