Javascript, From thumbnail to fullsize image on the same page.
Important references
As with many scripts and DOM effects you will find here at Cass-Hacks, the best way to arrive at an understanding of the core prinicples involved is to visit related topics at Quirksmode. Quirksmode's article on determining the true position of any element on a given page makes a large number of DOM effects possible.
Although the process described in the linked to article is not central to the functioning of this project's core features, this project wouldn't be able to function without the method described, which basically amounts to travelling up the offsetParent tree adding each one's offsets until one runs out of offsetParents.
Important note : You will definitely want to check out the article at Quirksmode to find under what conditions the determination of a given element's true position may fail using the techniques listed at Quirksmode as well as those used in the download sample available at the end of the code section of this project although it might be of interest to note as well that the script actually used on this site's example pages compensates for some of those conditions.
So, please go check out PPK's article to get an understanding of what his process does and what features it provides and then come back here to see the concepts put into use.
"Car 54, where are you?"
But for this project, not only do we need to know precisely the position of a given element on a page, we also need to know information about the "page" a target element is being displayed in.
Or more precisely, know where we are in a given page and know how much realestate we have to work with if/when the full expansion process is run.
To that end, we again go to the source for all things Javascript, Quirksmode to see what PPK has to say about window propeties and how to determine them with any hope of coming up with the right properties and the right values of those properties.
The birth of the World Wide Web
Some would say, and I couldn't argue against, that the World Wide Web was born the second that it was made possible to combine images with text in presenting information over the newly created Internet.
Up to that point, the Internet had primarily been used for the simple transfer of files from one place to another but being able to display the contents of some of those files as well as being able to connect text to images, millions of possibilities instantly opened up.
There has to be a better way!
One of the possibilities instantly realized was that sending pictures all over the 'net could end up consuming a lot of bandwdith only to transfer data for images that one might not even be interested in viewing.
A way was needed to in effect, give one one's cake and allow one to eat it too, to be able to get enough of an idea from a scaled down version of something in order to be able to tell if one wanted to access the more detailed version. At that point, the concept of using thumbnails was created.
There STILL, has to be a better way!
Thumbnail galleries are great, one gets to see smaller compressed versions of the full size images giving one the ability to pick and choose what they are most interested in viewing saving on bandwidth, loading time and page realestate.
But, having to always open the full size image in a new or the same window, forcing the user to contiually to have to click back to get back to viewing the entire set gets rather tedious for both user as well as the server.
There IS a better way!
Using DOM and CSS manipulation, (geek-talk = "DOM Scripting") one can transform the size of just about any element on the page in just about any way that one can imagine. One could, for example, show a small image and then have that image grow appreciably when one mouses over the image.
The image, in its rest state, could actually be too small to be clearly visible but could grow to a more reasonable size when one shows an interest in the image simply by mousing over it.
One could even add an effect to the slightly expanded image so that when one then clicks on the expanded image, it grows even more, up to full resolution and size, or up to the space available in the current browser viewport.
At this point it might be convenient to refer to this last expansion as a major expansion of the image while considering the mouseover expansion effect to be a minor expansion.
In any event, by using information regarding the positioning of a given element on the page, the image in question, from the DOM and manipulating that imformation using scripted style alterations, one could relatively easily control the positioning of the image all throughout its expanding on viewing and contracting on being moved away from.
Thumbnails in Web 2.0
What this project ends up providing is a way to make targeted images expand slightly in place on mouseover, minor expansion, and then expanding to center and fill the screen as much as possible on clicking the minor expansion version, major expansion.
Then, to go back, a simple click on the major expansion version begins it's collapse to the minor expansion version and from there, assuming one is not still mousing over it, collapsing back to it's original in-page display size and position.
Would this be a good point in time to give a demonstration of what I actually mean?
You get what you pay for?
The slight expansion on mouseover accomplishes two things, first, it allows the image actually included in the page, in its rest state, to not only be smaller than it might normally be but even smaller than might normally be acceptable because it can easily be expanded on a simple mouseover when one shows an interest.
Secondly, the slight expansion makes one aware that there are special features associated with the image and that it is not just a static image sitting there in the page.
The old and the new
While viewing full versions of thumbnailed images using the traditional method often leads one to having to scroll the page just to see all the parts of the full image thereby reducing the usefulness of displaying the full image, this method almost can guarantee that 100% of the fully expanded image is viewable.
"Almost" in that the full image size must be chosen so as to fit on the average screen. The script could be modified to make it possible for any size image to be guarenteed to fit but since it is easier just to edit the images to a reasonable size, going further will be left as an exercise for the reader.
It should also be noted however that while the fully expanded image is at least guarenteed to be centered on the screen and assuming one has chosen one's fully expanded image size correctly, should also be within the borders of the available browser viewport without the need for scrolling the same can not be said, at least in this project, for the minor expansion image.
On the other hand, one could again modify the code to account for and correct for this but that will be left as another exercise for the reader needing it as it doesn't seem to be all that big of a problem as most page viewers will generally "mouse search" for active material in the center to top portion of a given page any way.
(I did mentiont that this site wasn't going to be doing any spoon feeding, right?)
All this is of course at the possible expense of not being able to view a given image at true full size but then again, how often is it absolutely necessary that images be viewed at extreme sizes anyway and as already mentioned, does it really do any good to have a huge image if one has to scroll around just to see all of it?
Gilding the lily
But, while we are playing around with the DOM and CSS programatically, why not add other useful features into the process as well?
A borderless image expanding over a background of a page filled with different types of content could lead to a bit of a confusion and distraction along the border of the expanding image.
What would be nice would be to have a way to provide some separation between the expanding image itself and the background against which it is expanding.
The complicated made easy
Fortunately the measured expansion of the image itself provides us with a great opportunity to improve the features provided by this project but at a very little cost. One can simply provide a border around the image as it expands.
But, were the border to instantly pop into being at its full width, the jumping of the percieved image size would be distracting so since we are expanding the image size over a period of cycles already, we can just as easily ramp up the width of the border at the same time. Two terradactyls with one club.
Color me bored
However, since a solid white, or any solid color border around the image would look boring, why not add an expanding drop shadow effect at the same time?
Even better, how about in addition to that, since we want to focus more attention on the expanding image, why not "dim" the background at the same time as well?
[ED commentary: I know there is a kitchen sink laying around here somewhere but I think we'll leave at least that out of this.]
Break it down
Although each of the individual processes involved in creating the total effect are rather simple within themselves, the number of processes involved can seem to make the total effect complicated.
But, by breaking the total effect down into its constituent elemental parts, it is easier to see how each part works in isolation as well as how all the pieces work together.
Starting simple
So that we don't end up with an excessive amount of javascript included in the page iteslf, we'll use "triggers" to identify which page elements/images are to be handled as well as how they are to be handled.
Then, as each targeted image is mousedover, we set up parameters for not only the initial slight expansion, but to save time and processing, we'll initialize all the parameters we can for the entire process.
Three element process
If we break the process down into three basic steps, things can be explained and hopefully understood more easily. The three primary steps I find most convenient to identify are:
- Slight expansion of thumbnail image.
- Full expansion of target image.
- Increasing transparency of background while performing full expansion.
Step 1
When the mouseover event of a targeted image is triggered, we perform a number of initial steps to collect and generate a number of parameters needed throughout the slight expansion process and then initiate the timer to put in motion the slight expansion itself.
A brief list of the paramters and processes needed is as follows:
- Identify the area considered the background to the epanding image and which will slowly become more transparent during the full expansion phase.
- Identify the starting height and width of the in-page thumbnail. This is the point from which we will be expanding and the point we will then return to upon collapse.
- IMPORTANT! Identify the size the image should reach when it has attained its full semi-expansion size.
- Identify the center of the in-page thumbnail around which the slight expanding image will expand and the full expanding image will start from.
- Create a new page element to contain the slightly expanding image but with a css position of "absolute" so that it may expand without effecting any surrounding elements.
- Set the new expanding image element's img source to be the same as the in-page thumbnail.
- Set the amount the expanding image will grow on each firing of the expansion timer. This saves us from have to determine what the new size should be each time. All we have to do is add the amount of the "step" each time and when completed, we will have reached our goal.
- Similarly, set the amount the drop shadow will expand during each iteration of the slight expansion process.
- Set the expansion process timer and let it go.
A slave to the timer
Until completed, we perform the following steps each time the expansion timer fires:
- If set, kill the expansion timer to make sure that additional events don't get triggered when we don't want them to.
- Add the required amount to the height and width variables used to store the current size of the expanding image.
- Determine
- Set the height/width of the expanding image to the new values.
- Position the top/left of the image to keep it centered on the thumbnail's center.
- Increment the drop shadow width variable.
- Add the padding, based on the drop shadow variable, needing to be added to the right and the bottom to simulate the expansion of the shadow in proportion to the expansion of the image itself. Rather clever, that.
- Check to see if the image has attained its full semi-expansion size and if it hasn't, set the timer for the next expansion go-round and go off and write a sonnet or something in the 50milliseconds or so remaining until it is time to execute the expansion process again.
"I'm melting!!!!"
At some point, the user is going to mouseout of the slight expansion which should in turn, cause the slight expansion image to collapse.
If one does click on the expanded thumbnail, causing a full expansion, we would want the expanded thumbnail to disappear any way in order to give the illusion that the full expansion image is growing out of the expanded thumb.
But, the methods used for each, causing the expaned thumb to collapse and hiding the expanded thumb during full expansion are totally different.
In any event however, we will at some point need to undo what we did and take the expanded thumb back down to its in-page size and position.
Back "to where we belong."
To undo the slight expansion process what is required is fairly trivial. One need only reverse the exact process one used to get to the expanded thumb point, i.e. :
- Remove a "padding step" of padding to further the process of hiding the drop shadow,
- Remove a "height/width step" from the height and width.
- Recenter the collapsing image onto the center of the in-page thumbnail.
- If the collapsing thumb has not returned to its initial in-page thumbnail size, set the timer and then write the answer to life, the universe and everything while waiting to do it all again.
Half way there?
So, now we have an in-page thumbnail that virtually screams "DO ME, DO ME!!!".
As one mouses one's way around a given page as one is often found to do in search of active elements, one is instantly attracted to any image having the expansion functionality by it expanding in place and then collapsing as one mouses out.
In fact, one could use this effect totally by itself and not provide the additional major expansion effect but, since we can, we will for this discussion.
So, now we will tackle the last half and only very slightly more complicated portion of this project.
Similar yet different
The major expansion process runs along similar lines as the minor expansion :
- Begin by loading the required image into a Javascript:image object setting the image object's onload() handler to be the contiuation of the major expansion process.
- Create a container to hold the major expansion image and populate it with the image loaded in the previous step along with the drop shadow elements.
- Using the current width of the drop shadow padding for the minor expansion image, set the padding and hence the amount of the drop shadow visible to the same value helping portray the impression that the major expansion image is growing directly from the minor expansion image.
- Determine the full size height and width to be used as a final target size for the major expansion image.
- Set the size of the major expansion image to equal the current size of the minor expansion image.
- Use Quirksmode's process to determine the available screen area.
- Set the top and left of the major expansion image to equal the position of the minor expansion image.
- Using the start height/width and the ending height/width, determine the "height/width step size". These will simply be added to the current size on each iteration of the expansion process.
- Similar to the previous step, do the same, except for the background's "opacity step size".
- Run the timer triggered iterative expansion process.
- Once full size has been attained, stop expanding.
- When the fully expanded image is clicked on, reverse the expansion process and collapse the expanded image.
- When the major expansion image is fully collapsed, remove it from the document and begin the minor expansion collapse process.
How to use
- Create a thumbnail image with a width of between 110px to 120px. The inter_size_width, described on the code page for this project, will then define the minor expansion size.
- Create a "full size" image that is slightly less than the maximum page height you expect to be available. The script should ensure that any image used is displayed at a size that will fit the available page size but if it is much larger, bandwidth is wasted as images end up being scaled to size.
- To use the demo script without modification, assign the same name to both thumbnail and full size image, including file extension except add "thmb" and "full" to the thumbnail and full size image filenames respectively. See the code explanation page for details.
- Create a div element in the page with an ID of "opaqued". This element will not only contain all the thumbnails to be treated using this expansion process but will also contain any other page elements you wish to have dimmed during the major expansion process. You can apply whatever styling you wish to this element. This may vary from only containing the images themselves all the way to containing the entire page and is totally up to the user.
- Include the thumbnail in the page HTML within the div element mentioned above and assign it a CSS class name of "expando".
- Add the images used to create the drop shadow effect to a directory named "images" one level below the directory in which the HTML for the page is found. The location of these images may be changed in the CSS style information associated with the use of this script.
- Include the CSS style information in a style sheet in a directory one level below the directory in which the HTML for the page is found. This and the previous step are interdependant and either or both may be changed as long as their relative locations are maintained.
- Reference/load the Javascript source file in the HTML header.
Now for the real mess
The processes, when broken down, seem simple enough. Unfortunately my implementation does not seem to reflect the simplicity.
Following on to the next section, the implementation, you'll see that I don't document all the code but instead, document basically what I covered here as well as some small important points that may not necessarily be part of the general processes.
So, without further delay, on to the implementation!








