$(document).ready(function() { /* * The display is not yet object oriented. It's procedural code * broken off into functions. It makes use of libphotofloat's * PhotoFloat class for the network and management logic. * * All of this could potentially be object oriented, but presently * it should be pretty readable and sufficient. The only thing to * perhaps change in the future would be to consolidate calls to * jQuery selectors. And perhaps it'd be nice to move variable * declarations to the top, to stress that JavaScript scope is * for an entire function and always hoisted. * * None of the globals here polutes the global scope, as everything * is enclosed in an anonymous function. * */ /* Globals */ var currentAlbum = null; var currentPhoto = null; var currentPhotoIndex = -1; var previousAlbum = null; var previousPhoto = null; var originalTitle = document.title; var photoFloat = new PhotoFloat(); /* Entry point for most events */ function hashParsed(album, photo, photoIndex) { undie(); $("#loading").hide(); if (album == currentAlbum && photo == currentPhoto) return; previousAlbum = currentAlbum; previousPhoto = currentPhoto; currentAlbum = album; currentPhoto = photo; currentPhotoIndex = photoIndex; setTitle(); showAlbum(previousAlbum != currentAlbum); if (photo != null) showPhoto(); } /* Displays */ function setTitle() { var title = ""; var documentTitle = ""; var components; if (currentAlbum.path.length == 0) components = [originalTitle]; else { components = currentAlbum.path.split("/"); components.unshift(originalTitle); } if (currentPhoto != null) documentTitle += photoFloat.trimExtension(currentPhoto.name); var last = ""; for (var i = 0; i < components.length; ++i) { if (i || currentPhoto != null) documentTitle += " \u00ab "; if (i) last += "/" + components[i]; if (i < components.length - 1 || currentPhoto != null) title += ""; title += components[i]; documentTitle += components[components.length - 1 - i]; if (i < components.length - 1 || currentPhoto != null) { title += ""; title += " » "; } } if (currentPhoto != null) title += photoFloat.trimExtension(currentPhoto.name); $("#title").html(title); document.title = documentTitle; } function showAlbum(populate) { if (currentPhoto == null && previousPhoto == null) $("html, body").stop().animate({ scrollTop: 0 }, "slow"); if (populate) { var photos = []; for (var i = 0; i < currentAlbum.photos.length; ++i) { var link = $(""); var image = $(""); link.append(image); image.get(0).photo = currentAlbum.photos[i]; photos.push(link); } var thumbsElement = $("#thumbs"); thumbsElement.empty(); thumbsElement.append.apply(thumbsElement, photos); var subalbums = []; for (var i = currentAlbum.albums.length - 1; i >= 0; --i) { var link = $(""); var image = $("
"); link.append(image); subalbums.push(link); (function(theAlbum, theImage) { photoFloat.albumPhoto(theAlbum, function(album, photo) { theImage.css("background-image", "url(" + photoFloat.photoPath(album, photo, 150, true) + ")"); }); })(currentAlbum.albums[i], image); } var subalbumsElement = $("#subalbums"); subalbumsElement.empty(); subalbumsElement.append.apply(subalbumsElement, subalbums); } if (currentPhoto == null) { $("#thumbs img").removeClass("current-thumb"); $("#album-view").removeClass("photo-view-container"); $("#subalbums").show(); $("#photo-view").hide(); } setTimeout(scrollToThumb, 1); } function getDecimal(fraction) { if (fraction[0] < fraction[1]) return fraction[0] + "/" + fraction[1]; return (fraction[0] / fraction[1]).toString(); } function scaleImage() { var image = $("#photo"); if (image.get(0) == this) $(window).bind("resize", scaleImage); var container = $("#photo-view"); if (image.css("width") != "100%" && container.height() * image.width() / image.height() > container.width()) image.css("width", "100%").css("height", "auto"); else if (image.css("height") != "100%") image.css("height", "100%").css("width", "auto"); } function showPhoto() { var maxSize = 800; var width = currentPhoto.size[0]; var height = currentPhoto.size[1]; if (width > height) { height = height / width * maxSize; width = maxSize; } else { width = width / height * maxSize; height = maxSize; } $(window).unbind("resize", scaleImage); var photoSrc = photoFloat.photoPath(currentAlbum, currentPhoto, maxSize, false); $("#photo") .attr("width", width).attr("height", height) .attr("src", photoSrc) .attr("alt", currentPhoto.name) .attr("title", currentPhoto.date) .load(scaleImage); $("head").append(""); var previousPhoto = currentAlbum.photos[ (currentPhotoIndex - 1 < 0) ? (currentAlbum.photos.length - 1) : (currentPhotoIndex - 1) ]; var nextPhoto = currentAlbum.photos[ (currentPhotoIndex + 1 >= currentAlbum.photos.length) ? 0 : (currentPhotoIndex + 1) ]; $.preloadImages(photoFloat.photoPath(currentAlbum, nextPhoto, maxSize, false), photoFloat.photoPath(currentAlbum, previousPhoto, maxSize, false)); var nextLink = "#!/" + photoFloat.photoHash(currentAlbum, nextPhoto); $("#next-photo").attr("href", nextLink); $("#next").attr("href", nextLink); $("#back").attr("href", "#!/" + photoFloat.photoHash(currentAlbum, previousPhoto)); $("#original-link").attr("target", "_blank").attr("href", photoFloat.originalPhotoPath(currentAlbum, currentPhoto)); var text = "Camera Maker | " + currentPhoto.make + " |
Camera Model | " + currentPhoto.model + " |
Time Taken | " + currentPhoto.date + " |
Resolution | " + currentPhoto.size[0] + " x " + currentPhoto.size[1] + " |
Aperture | f/" + getDecimal(currentPhoto.aperture) + " |
Focal Length | " + getDecimal(currentPhoto.focalLength) + " mm |
ISO | " + currentPhoto.iso + " |
Exposure Time | " + getDecimal(currentPhoto.exposureTime) + " sec |
Exposure Program | " + currentPhoto.exposureProgram + " |
Exposure Compensation | " + getDecimal(currentPhoto.exposureCompensation) + " |
Spectral Sensitivity | " + currentPhoto.spectralSensitivity + " |
Flash | " + currentPhoto.flash + " |
Orientation | " + currentPhoto.orientation + " |