Be the first to write a review
An Image Viewer with the DMXzone Universal CSS Transforms Library
The power of the Universal CSS Transforms Library for jQuery
With this article Dan will introduce you the power of the Universal CSS Transforms Library for jQuery that was recently released to open source by the DMXzone team.
Styling the page
Now we can add the style sheet required for this example; in a new page in your text editor add the following CSS:
#viewer {
width:763px; height:578px; margin:auto;
position:relative;
background:url(../img/viewer.jpg)
no-repeat;
}
#window {
width:468px; height:468px; margin:52px 0 0
60px; position:relative;
float:left; overflow:hidden;
}
#ui { width:151px; margin:96px 36px 0 0;
float:right; }
#ui ul { padding:0; margin:0;
list-style-type:none; }
#ui li {
height:42px; margin-bottom:44px;
background-image:url(../img/labels.png);
}
#ui li a {
display:block; height:100%;
overflow:hidden; text-indent:-5000px;
}
#image2 { background-position:0 -43px; }
#image3 { background-position:0 -86px; }
#image4 { background-position:0 -130px; }
#image5 { background-position:0 -174px; }
#ui span { display:none; }
#cog {
width:79px; height:78px;
position:absolute; top:141px; right:-32px; z-index:-1;
background:url(../img/cog.png) no-repeat 0
0;
}
#over {
width:208px; height:89px;
position:absolute; top:137px; right:-8px;
background:url(../img/over.png) no-repeat
0 0;
}
Save this file as css-transforms-viewer.css in the css folder. This is all pretty straight-forward; we size up the collection of elements and position them according to the design, as well as setting some background images where appropriate. The most important thing is that the #window element is sized to the same dimensions as an individual image, and that it is set to overflow:hidden so that the images, which naturally stack up on top of each other, are not all visible, only a single image is visible at any one time.
At this point we should take stock of how the page already behaves, without us having added any additional functionality at all; we can already click on any of the labels and that will cause the corresponding image to be displayed, without any JavaScript at all, which makes the page perfectly accessible to any browser that has JS disabled. Additionally, when a label is clicked, the href of the image is added to the URL of the page, which means that the page can be loaded and have a specific image displayed by default, which is quite useful. This functionality works in all popular browsers.
Adding the JavaScript
To make the example work with our CSS transitions we need to add some script; at the bottom of the page, where we left the comment, add the following code:
$("#ui").find("div").attr("id", "over");
$("#window").wrapInner("<div id=\"wrapper\">");
var
imgPositions = { image1: 0, image2: -472,
image3: -945, image4: -1417, image5: -1890 },
overPositions = { image1: 0, image2: 75, image3:
152, image4: 230, image5: 310 },
cogPositions = { image1: 5, image2: 80, image3:
154, image4: 235, image5: 310 },
previousCogPosition = 0;
We first have to do a little prep work; we give our un-attributed <div> and id so that it picks up the styling – we do this with JavaScript because the over state is useless if JS is disabled, so it should only be visible is JS is available. We also wrap all of the images within the window part of the viewer in a wrapper <div> so that we only have to animate one element instead of each individual image. Finally we create an object that is used to store the positions of the images, the cog and the over state so that we can move all of these elements with ease by referring to the object to set their position later in the script. We also define a previousCogPosition variable that we'll use to determine how the cog should be rotated.
Next we can define a function that will handle the actual animations:
function animator(pointer, notImg) {
if (!notImg) {
$("#wrapper").animate({
"translateY":
parseInt(imgPositions[pointer])
});
}
$("#cog").animate({
"translateY":
parseInt(cogPositions[pointer]),
"rotate":
(parseInt(cogPositions[pointer]) < previousCogPosition) ? "-=365" : "+=365"
}, function() {
previousCogPosition = cogPositions[pointer];
});
$("#over").animate({
"translateY":
parseInt(overPositions[pointer])
});
}
This function will receive several arguments, a pointer that tells the animation functions which values to retrieve from the position objects, and a switch that tells the function whether to animate the main images in the window or not. If the notImg argument is omitted (or if false is supplied) the image wrapper will not be animated, but the over element and cog still will be. This is necessary in case someone accesses the page the viewer runs on with a hash in the URL, e.g. viewer.html#image3 – when this happens, the third image will be displayed by the browser automatically , so the over state and cog should be moved so that they are in the correct positions.
The elements are animated using the translateY function to alter their position, and additionally the cog will also spin using the rotate function. Notice that we check where the cog was previously by looking at our previousCogPositon variable (we'll populate this shortly, but it is given an initial value of 0) so that we can rotate the cog the right way – if the cog moves down it will rotate clockwise, if it moves up it rotate anti-clockwise.
We now need to actually check for whether the URL contains a hash and make some additional changes if it is detected:
if (window.location.hash) {
var hash = window.location.hash.split("#")[1],
target = $("a[href=" + hash + "]");
if (hash === "image2") {
imgPositions = { image1: 472,
image2: 0, image3: -472, image4: -945, image5: -1417 }
} else if (hash === "image3") {
imgPositions = { image1: 945,
image2: 472, image3: 0, image4: -472, image5: -945 }
} else if (hash === "image4") {
imgPositions = { image1: 1417,
image2: 945, image3: 472, image4: 0, image5: -472 }
} else if (hash === "image5") {
imgPositions = { image1: 1890,
image2: 1417, image3: 945, image4: 472, image5: 0 }
}
animator(hash, true);
}
If the hash is detected we need to rewrite one of our position objects so that the correct image is displayed when its corresponding link is clicked. The translateY function will always detect the wrapper as starting out at 0, even if the last image is displayed on page load (such as when a hash is used in the URl to access the page), so rewriting the imgPositions object ensures the viewer still works as intended.
Finally, we just need to wire up the links in out UI structure so that when one is clicked the correct image is displayed:
$("#ui a").click(function(e) {
e.preventDefault();
var pointer = $(this).attr("href").split("#")[1];
animator(pointer);
});
We simply stop the default behaviour (i.e. to focus the correct image) and call our animator function. The pointer is obtained by splitting the href attribute of the link that was clicked. This is then passed into the animator function.
Dan Wellman
Dan Wellman is an author and web developer based in the UK. Dan has written three books so far; the latest, jQuery UI 1.7: The User Interface Library for jQuery, was released at the end of 2009.
Dan has been writing web development tutorials for over 5 years and works by day for a local digital media agency in his home town of Southampton.