0byt3m1n1
Path:
/
data
/
applications
/
aps
/
gallery
/
2.2-08
/
htdocs
/
themes
/
ajaxian
/
javascript
/
[
Home
]
File: thumbnail-functions.js
/* * Gallery - a web based photo album viewer and editor * Copyright (C) 2000-2007 Bharat Mediratta * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* Global Variables */ var thumbnails; /* array of thumbnails */ var currentImageIndex; /* index into thumbnails array */ var mainPhoto; /* The central image */ var photoScalingInterval; /* scaling animation tracker */ var showLoadingTimeout; /* Cancel the loading message display */ var showImageDataFadeTimeout /* Fade in image data block */ var MAIN_PHOTO_WIDTH = 460; /* Width each image is resized to when first loaded */ var PHOTO_MINIMISED = 300; /* Width each image is resized down to when clicked */ var SCALE_DOWN_FACTOR = 12; /* Pixels that an image scales down by at each step */ var SCALE_UP_FACTOR = 18; /* Pixels that an image scales *up* by at each step */ /* @REVISIT: For preloading... */ fullsizePhotos = new Array(); fullsizeCount = 0; /* Initialisation */ addEvent(window, 'load', init, false); function init() { if (!document.getElementById) { /* Required functionality for even the most basic DHTML. */ return; } /* Set up thumbnails */ var thumbholder = document.getElementById('gsThumbMatrix'); if (!thumbholder) { setupBackToAlbumLink(); /* Not an album page */ return; } thumbnails = thumbholder.getElementsByTagName('img'); for (var i = 0; i < thumbnails.length; i++) { thumbnails[i].thumbIndex = i; addEvent(thumbnails[i], 'click', activateThumbnail, false); thumbnails[i].onclick = cancelEventSafari; } /* * If the user has just come from a photo page, they may have a cookie set that holds the index * of the image that was active in the show when they left. Now they can rejoin at that point. */ if (readCookie('slideshowOffset') != null && Number(readCookie('slideshowOffset')) < thumbnails.length) { currentImageIndex = Number(readCookie('slideshowOffset')); eraseCookie('slideshowOffset'); addMessage('Restarting slideshow at index ' + currentImageIndex); } else { currentImageIndex = 0; } if (slideshowImages.length > 0) { setupMainImage(); switchImages(currentImageIndex, true); } setupSubAlbums(); } /* Called each time a new image is switched to */ function setupMainImage() { mainPhoto = document.getElementById('main-image'); if (slideshowImageWidths[currentImageIndex] < 0 || MAIN_PHOTO_WIDTH <= slideshowImageWidths[currentImageIndex]) { mainPhoto.style.width = MAIN_PHOTO_WIDTH + 'px'; } else { /* * The image is below our ideal slideshow width, so we don't want to stretch it * horizontally. Instead we center the image that we have a little better. */ mainPhoto.style.width = slideshowImageWidths[currentImageIndex] + 'px'; mainPhoto.style.left = parseInt(getElementStyle(mainPhoto.id, 'left')) + ((MAIN_PHOTO_WIDTH - slideshowImageWidths[currentImageIndex])/2) + 'px'; } mainPhoto.style.height = 'auto'; /* @REVISIT - Safari doesn't play nice with this */ mainPhoto.origWidth = parseInt(getElementStyle(mainPhoto.id, 'width')); mainPhoto.origLeft = parseInt(getElementStyle(mainPhoto.id, 'left')); mainPhoto.galleryimg = 'no'; /* Disables IE's image toolbar, which was causing flicker */ addEvent(mainPhoto, 'click', showPhotoDetails, false); } function activateThumbnail(e) { /* Find the source element through varying levels of browser support */ var targetElement = window.event ? window.event.srcElement : e ? e.target : null; if (!targetElement) { return; } knackerEvent(e); switchImages(targetElement.thumbIndex); targetElement.blur(); /* Remove focus halo */ } function switchImages(thumbIndex, firstLoad) { removeImageDataBlock(); if (currentImageIndex == thumbIndex && !firstLoad) { addMessage("That image is already selected."); return; } /* Wrap around */ if (thumbIndex < 0) { thumbIndex = thumbnails.length - 1; } else if (thumbIndex == thumbnails.length) { thumbIndex = 0; } if (slideshowImageWidths[thumbIndex] < 0) { /* This item is not a photo.. redirect to view it */ if (!firstLoad) { location = slideshowImages[thumbIndex]; } else { hideLoadingMessage(); } return; } highlightCurrentThumb(thumbIndex); updateItemTitle(thumbIndex); hideLoadingMessage(); var newImageSrc = slideshowImages[thumbIndex]; var newImage = document.createElement('img'); mainPhoto.id = null; /* Isn't enough in some browsers */ mainPhoto.removeAttribute('id'); newImage.id = 'main-image'; addEvent(newImage, 'load', bigPhotoLoad, false); addEvent(newImage, 'error', bigPhotoFail, false); if (slideshowState == PLAYING) { pause(); returnToPlaying = true; } /* Avoid showing loading message if its going to be fast */ showLoadingTimeout = setTimeout("showLoadingMessage()", 600); addMessage("Swapping " + currentImageIndex + ", and " + thumbIndex + "..."); currentImageIndex = thumbIndex; newImage.src = newImageSrc; mainPhoto.parentNode.removeChild(mainPhoto); document.getElementById('sliding-frame').getElementsByTagName('p')[0].appendChild(newImage); setupMainImage(); if (mainPhoto.state == 'downsized') { insertimagedatablock(); } } function bigPhotoLoad() { mainPhoto.style.height = 'auto'; addMessage('Photo loaded'); hideLoadingMessage(); /* * The little switcheroo below prevents a problem with IE incorrectly calculating the 'height' * property for an image that has had its width changed when set to 'auto' (they should scale * together). Should be imperceptible in other browsers. */ mainPhoto.style.height = '345px'; mainPhoto.style.height = 'auto'; if (returnToPlaying) { play(); } } function bigPhotoFail() { addMessage('FAIL: Photo failed to load...'); addMessage(mainPhoto.src); hideLoadingMessage(); if (slideshowState == PLAYING) { advanceSlideShow(); } } function showLoadingMessage() { var loadingMsg = document.createElement('div'); loadingMsg.id = 'loading'; loadingMsg.appendChild(document.createTextNode(LOADING_IMAGE)); document.getElementById('main-image-container').appendChild(loadingMsg); } function hideLoadingMessage() { clearTimeout(showLoadingTimeout); var loading = document.getElementById('loading'); if (loading && getElementStyle(loading.id, '-moz-opacity') > 0.0) { loading.style.MozOpacity = parseFloat(getElementStyle(loading.id, '-moz-opacity')) - 0.05; showLoadingTimeout = setTimeout("hideLoadingMessage()", 50); } else if (loading) { loading.parentNode.removeChild(loading); } } function highlightCurrentThumb(thumbIndex) { /* First, un-highlight the current image... */ thumbnails[currentImageIndex].className = thumbnails[currentImageIndex].className.replace(/\bcurrentImage\b/, ''); thumbnails[thumbIndex].className += ' currentImage'; } function updateItemTitle(thumbIndex) { var itemTitle = document.getElementById('item-title').firstChild; itemTitle.data = thumbnails[thumbIndex].getAttribute('alt'); } /* * Photo -scaling functions */ function showPhotoDetails(e) { addMessage('scaling image, dimensions: ' + mainPhoto.origWidth + 'x' + mainPhoto.origHeight); clearInterval(photoScalingInterval); if (slideshowState == PLAYING) { pause(); returnToPlaying = true; } if (mainPhoto.state != 'downsized') { photoScalingInterval = setInterval("downSizePhoto()", 30); mainPhoto.state = 'downsized'; } else { removeImageDataBlock(); photoScalingInterval = setInterval("upSizePhoto()", 20); mainPhoto.state = 'upsized'; } } function downSizePhoto() { if (parseInt(mainPhoto.style.width) > PHOTO_MINIMISED || parseInt(getElementStyle(mainPhoto.id, 'left')) > 40) { if (parseInt(mainPhoto.style.width) > PHOTO_MINIMISED) { mainPhoto.style.width = parseInt(mainPhoto.style.width) - SCALE_DOWN_FACTOR + 'px'; } /* REVISIT Works in everything but Safari... */ mainPhoto.style.height = 'auto'; if (parseInt(getElementStyle(mainPhoto.id, 'left')) > 40) { mainPhoto.style.left = (parseInt(getElementStyle(mainPhoto.id, 'left')) - mainPhoto.origLeft/12) + 'px'; } if (getElementStyle(mainPhoto.id, 'top') == 'auto') { mainPhoto.style.top = '0'; } if (parseInt(getElementStyle(mainPhoto.id, 'top')) < 40) { mainPhoto.style.top = (parseInt(getElementStyle(mainPhoto.id, 'top')) + 5) + 'px'; } } else { clearInterval(photoScalingInterval); addMessage('Image scaled to ' + mainPhoto.style.width + 'x' + mainPhoto.style.height); mainPhoto.state = 'downsized'; insertimagedatablock(); } } function upSizePhoto() { if (parseInt(mainPhoto.style.width) < mainPhoto.origWidth || parseInt(getElementStyle(mainPhoto.id, 'left')) < mainPhoto.origLeft) { if (parseInt(mainPhoto.style.width) < mainPhoto.origWidth-5) { mainPhoto.style.width = (parseInt(mainPhoto.style.width) + SCALE_UP_FACTOR) + 'px'; } if (parseInt(getElementStyle(mainPhoto.id, 'left')) < mainPhoto.origLeft) { mainPhoto.style.left = (parseInt(getElementStyle(mainPhoto.id, 'left')) + mainPhoto.origLeft/10) + 'px'; } if (parseInt(getElementStyle(mainPhoto.id, 'top')) > 0) { mainPhoto.style.top = (parseInt(getElementStyle(mainPhoto.id, 'top')) - 5) + 'px'; } } else { /* Clean up and reset */ clearInterval(photoScalingInterval); mainPhoto.style.width = mainPhoto.origWidth + 'px'; mainPhoto.style.height = 'auto'; mainPhoto.style.left = mainPhoto.origLeft + 'px'; mainPhoto.style.top = 'auto'; addMessage('Image scaled back to ' + mainPhoto.width + 'x' + mainPhoto.height); mainPhoto.state = 'upsized'; if (returnToPlaying) { play(); } } } function insertimagedatablock() { var dataBlock = document.createElement('div'); dataBlock.id = 'imagedatablock'; var dataBlockHeading = document.createElement('h3'); dataBlockHeading.appendChild(document.createTextNode(PHOTO_DATA)); dataBlock.appendChild(dataBlockHeading); if (thumbnails[currentImageIndex].className.match(/size:=([0-9]+)=/)) { var imageSize = Number(RegExp.$1) / 1024; var sizeInfo = document.createElement('p'); sizeInfo.appendChild( document.createTextNode(FILE_SIZE.replace(/%SIZE%/, Math.round(imageSize)))); dataBlock.appendChild(sizeInfo); } if (thumbnails[currentImageIndex].className.match(/summary:=([^=]+)=/)) { var summaryInfo = document.createElement('p'); summaryInfo.appendChild(document.createTextNode(SUMMARY + RegExp.$1)); dataBlock.appendChild(summaryInfo); } if (thumbnails[currentImageIndex].className.match(/description:=(.+)=/)) { var descriptionInfo = document.createElement('p'); descriptionInfo.appendChild(document.createTextNode(DESCRIPTION + RegExp.$1)); dataBlock.appendChild(descriptionInfo); } var fullsizeLink = document.createElement('a'); fullsizeLink.id = 'fullsizelink'; fullsizeLink.href = thumbnails[currentImageIndex].parentNode.href + (thumbnails[currentImageIndex].parentNode.href.indexOf('?') >= 0 ? '&' : '?') + 'thumbIndex=' + currentImageIndex; /* Allow a user to rejoin the slideshow at this point */ addEvent(fullsizeLink, 'click', saveCurrentImageIndex, false); fullsizeLink.appendChild(document.createTextNode(VIEW_IMAGE)); var linkPara = document.createElement('p'); linkPara.appendChild(fullsizeLink); dataBlock.appendChild(linkPara); /* In Gecko-based browsers, this'll fade the data block in smoothly. */ dataBlock.style.MozOpacity = 0.2; showImageDataFadeTimeout = setTimeout('fadeInImageDataBlock()', 50); document.getElementById('main-image-container').appendChild(dataBlock); } function fadeInImageDataBlock() { clearTimeout(showImageDataFadeTimeout); var dataBlock = document.getElementById('imagedatablock'); /* Don't bring -moz-opacity all the way to 1.0, as it causes flicker in Firefox 1.0 */ if (dataBlock && getElementStyle(dataBlock.id, '-moz-opacity') < 0.92) { dataBlock.style.MozOpacity = parseFloat(getElementStyle(dataBlock.id, '-moz-opacity')) + 0.08; showImageDataFadeTimeout = setTimeout('fadeInImageDataBlock()', 50); } } function removeImageDataBlock() { var dataBlock = document.getElementById('imagedatablock'); if (dataBlock) { dataBlock.parentNode.removeChild(dataBlock); } } /* Subalbums table */ function setupSubAlbums() { /* First check if there is a sub-album table */ if (!document.getElementById('gsSubAlbumMatrix')) { return; } var subs = document.getElementById('gsSubAlbumMatrix').getElementsByTagName('td'); for (var i = 0; i < subs.length; i++) { addEvent(subs[i], 'click', selectSubAlbum, false); var hasLink = subs[i].getElementsByTagName('a')[0]; if (hasLink) { addEvent(subs[i], 'mouseover', highlightSubAlbum, true); addEvent(subs[i], 'mouseout', unHighlightSubAlbum, true); } } } function highlightSubAlbum(e) { /* Find the source element through varying levels of browser support */ var targetElement = window.event ? window.event.srcElement : e ? e.target : null; if (!targetElement) { return; } while (targetElement.nodeName.toLowerCase() != 'td' && targetElement.nodeName.toLowerCase() != 'body') { targetElement = targetElement.parentNode; } if (targetElement.nodeName.toLowerCase() == 'body') { return; } targetElement.className += ' sahover'; } function unHighlightSubAlbum(e) { /* Find the source element through varying levels of browser support */ var targetElement = window.event ? window.event.srcElement : e ? e.target : null; if (!targetElement) { return; } while (targetElement.nodeName.toLowerCase() != 'td' && targetElement.nodeName.toLowerCase() != 'body') { targetElement = targetElement.parentNode; } if (targetElement.nodeName.toLowerCase() == 'body') { return; } targetElement.className = targetElement.className.replace(/\bsahover\b/, ''); } function selectSubAlbum(e) { /* Find the source element through varying levels of browser support */ var targetElement = window.event ? window.event.srcElement : e ? e.target : null; if (!targetElement) { return; } knackerEvent(e); while (targetElement.nodeName.toLowerCase() != 'td' && targetElement.nodeName.toLowerCase() != 'body') { targetElement = targetElement.parentNode; } if (targetElement.nodeName.toLowerCase() == 'body') { return; } eraseCookie('slideshowOffset'); var firstlink = targetElement.getElementsByTagName('a')[0]; if (firstlink) { window.location = firstlink.href; } } /* Photo page functions */ function setupBackToAlbumLink() { var pageLinks = document.getElementsByTagName('a'); for (var i = 0; i < pageLinks.length; i++) { if (pageLinks[i].className.match(/\bbacktoalbum\b/)) { addEvent(pageLinks[i], 'click', saveCurrentImageIndex, false); } } } function saveCurrentImageIndex() { if (window.location.toString().match(/thumbIndex=([0-9]+)/)) { createCookie('slideshowOffset', RegExp.$1); } else if (currentImageIndex) { createCookie('slideshowOffset', currentImageIndex); } }