$(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(); var maxSize = 800; /* Displays */ function setTitle() { var title = "", documentTitle = "", last = "", components, i; if (!currentAlbum.path.length) components = [originalTitle]; else { components = currentAlbum.path.split("/"); components.unshift(originalTitle); } if (currentPhoto !== null) documentTitle += photoFloat.trimExtension(currentPhoto.name); for (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 scrollToThumb() { var photo, thumb; photo = currentPhoto; if (photo === null) { photo = previousPhoto; if (photo === null) return; } $("#thumbs img").each(function() { if (this.photo === photo) { thumb = $(this); return false; } }); if (typeof thumb === "undefined") return; if (currentPhoto !== null) { var scroller = $("#album-view"); scroller.stop().animate({ scrollLeft: thumb.position().left + scroller.scrollLeft() - scroller.width() / 2 + thumb.width() / 2 }, "slow"); } else $("html, body").stop().animate({ scrollTop: thumb.offset().top - $(window).height() / 2 + thumb.height() }, "slow"); if (currentPhoto !== null) { $("#thumbs img").removeClass("current-thumb"); thumb.addClass("current-thumb"); } } function showAlbum(populate) { var i, link, image, photos, thumbsElement, subalbums, subalbumsElement; if (currentPhoto === null && previousPhoto === null) $("html, body").stop().animate({ scrollTop: 0 }, "slow"); if (populate) { photos = []; for (i = 0; i < currentAlbum.photos.length; ++i) { link = $(""); image = $(""); if (currentAlbum.photos[i].mediaType == "video") image.css("background-image", "url(" + image.attr("src") + ")").attr("src", "img/video-icon.png"); image.get(0).photo = currentAlbum.photos[i]; link.append(image); photos.push(link); (function(theLink, theImage, theAlbum) { theImage.error(function() { photos.splice(photos.indexOf(theLink), 1); theLink.remove(); theAlbum.photos.splice(theAlbum.photos.indexOf(theImage.get(0).photo), 1); }); })(link, image, currentAlbum); } thumbsElement = $("#thumbs"); thumbsElement.empty(); thumbsElement.append.apply(thumbsElement, photos); subalbums = []; for (i = currentAlbum.albums.length - 1; i >= 0; --i) { link = $(""); image = $("
"); link.append(image); subalbums.push(link); (function(theContainer, theAlbum, theImage, theLink) { photoFloat.albumPhoto(theAlbum, function(album, photo) { theImage.css("background-image", "url(" + photoFloat.photoPath(album, photo, 150, true) + ")"); }, function error() { theContainer.albums.splice(currentAlbum.albums.indexOf(theAlbum), 1); theLink.remove(); subalbums.splice(subalbums.indexOf(theLink), 1); }); })(currentAlbum, currentAlbum.albums[i], image, link); } subalbumsElement = $("#subalbums"); subalbumsElement.empty(); subalbumsElement.append.apply(subalbumsElement, subalbums); if (currentAlbum.albums.length > 1) subalbumsElement.insertBefore(thumbsElement); else thumbsElement.insertBefore(subalbumsElement); } if (currentPhoto === null) { $("#thumbs img").removeClass("current-thumb"); $("#album-view").removeClass("photo-view-container"); $("#subalbums").show(); $("#photo-view").hide(); $("#video")[0].pause() } 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, container; image = $("#photo"); if (image.get(0) === this) $(window).bind("resize", scaleImage); container = $("#photo-view"); if (image.css("width") !== "100%" && container.height() * image.attr("ratio") > container.width()) image.css("width", "100%").css("height", "auto").css("position", "absolute").css("bottom", 0); else if (image.css("height") !== "100%") image.css("height", "100%").css("width", "auto").css("position", "").css("bottom", ""); } function scaleVideo() { var video, container; video = $("#video"); if (video.get(0) === this) $(window).bind("resize", scaleVideo); container = $("#photo-view"); if (video.attr("width") > container.width() && container.height() * video.attr("ratio") > container.width()) video.css("width", container.width()).css("height", container.width() / video.attr("ratio")).parent().css("height", container.width() / video.attr("ratio")).css("margin-top", - container.width() / video.attr("ratio") / 2).css("top", "50%"); else if (video.attr("height") > container.height() && container.height() * video.attr("ratio") < container.width()) video.css("height", container.height()).css("width", container.height() * video.attr("ratio")).parent().css("height", "100%").css("margin-top", "0").css("top", "0"); else video.css("height", "").css("width", "").parent().css("height", video.attr("height")).css("margin-top", - video.attr("height") / 2).css("top", "50%"); } function showPhoto() { var width, height, photoSrc, videoSrc, previousPhoto, nextPhoto, nextLink, text; if (currentPhoto.mediaType == "video") { width = currentPhoto.size[0]; height = currentPhoto.size[1]; $(window).unbind("resize", scaleVideo); $(window).unbind("resize", scaleImage); videoSrc = photoFloat.videoPath(currentAlbum, currentPhoto); $("#video") .attr("width", width).attr("height", height).attr("ratio", currentPhoto.size[0] / currentPhoto.size[1]) .attr("src", videoSrc) .attr("alt", currentPhoto.name) .on('loadstart', scaleVideo); $("head").append(""); $("#video-box-inner").css('height', height + 'px').css('margin-top', - height / 2); $("#photo-box").hide(); $("#video-box").show(); } else { width = currentPhoto.size[0]; height = currentPhoto.size[1]; if (width > height) { height = height / width * maxSize; width = maxSize; } else { width = width / height * maxSize; height = maxSize; } $(window).unbind("resize", scaleVideo); $(window).unbind("resize", scaleImage); photoSrc = photoFloat.photoPath(currentAlbum, currentPhoto, maxSize, false); $("#photo") .attr("width", width).attr("height", height).attr("ratio", currentPhoto.size[0] / currentPhoto.size[1]) .attr("src", photoSrc) .attr("alt", currentPhoto.name) .attr("title", currentPhoto.date) .load(scaleImage); $("head").append(""); $("#video")[0].pause() $("#video-box").hide(); $("#photo-box").show(); } previousPhoto = currentAlbum.photos[ (currentPhotoIndex - 1 < 0) ? (currentAlbum.photos.length - 1) : (currentPhotoIndex - 1) ]; nextPhoto = currentAlbum.photos[ (currentPhotoIndex + 1 >= currentAlbum.photos.length) ? 0 : (currentPhotoIndex + 1) ]; $.preloadImages(photoFloat.photoPath(currentAlbum, nextPhoto, maxSize, false), photoFloat.photoPath(currentAlbum, previousPhoto, maxSize, false)); 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)); 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 |
Subject Distance Range | " + currentPhoto.subjectDistanceRange + " |
ISO | " + currentPhoto.iso + " |
Scene Capture Type | " + currentPhoto.sceneCaptureType + " |
Exposure Time | " + getDecimal(currentPhoto.exposureTime) + " sec |
Exposure Program | " + currentPhoto.exposureProgram + " |
Exposure Compensation | " + getDecimal(currentPhoto.exposureCompensation) + " |
Spectral Sensitivity | " + currentPhoto.spectralSensitivity + " |
Sensing Method | " + currentPhoto.sensingMethod + " |
Light Source | " + currentPhoto.lightSource + " |
Flash | " + currentPhoto.flash + " |
Orientation | " + currentPhoto.orientation + " |