// ----- // ----- // ----- // ----- // ----- // // // this script is based on the Lightbox v2.04 script by Lokesh Dhakar... // http://www.lokeshdhakar.com // http://lokeshdhakar.com/projects/lightbox2/ // great script, go check it out sometime... // // mainly developed to accomodate specifics for Infiniti Technology... // ...or maybe I just needed a fresh challenge, to see if I could do it, // using prototype too ;P // // last updated: 24 june 2010...world cup!!! // // ----- // ----- // ----- // ----- // ----- // // our ImageBox class... var IB = Class.create(); var ImageBox = null; // proceed with the class definition information... IB.prototype = { basepath: 'http://www.gep.co.za/admin/modules/config/imagebox/', imagebox_url_collection: [], imagebox_status_collection: [], imagebox_current_index: 0, slideshow_timeout: 5, viewer_padding: 10, viewer_border: 1, slideshow_started: false, slideshow_timeout: 3, slideshow_timer: null, visible: false, status_available: false, status_height: 0, imagebox_image_loader: null, imagebox_image_next: null, imagebox_image_previous: null, imagebox_image_play: null, imagebox_image_pause: null, // initialisation function... // this is called when the script invokes the 'new ImageBox()' command... initialize: function() { if (!$('AJAX_CHILD_ELEMENT_APPENDER')) return; // let's start with the image preloading... this.imagebox_image_loader = new Image(); this.imagebox_image_loader.src = this.basepath + 'images/loader.gif'; this.imagebox_image_next = new Image(); this.imagebox_image_next.src = this.basepath + 'images/next.gif'; this.imagebox_image_previous = new Image(); this.imagebox_image_previous.src = this.basepath + 'images/previous.gif'; this.imagebox_image_play = new Image(); this.imagebox_image_play.src = this.basepath + 'images/play.gif'; this.imagebox_image_pause = new Image(); this.imagebox_image_pause.src = this.basepath + 'images/pause.gif'; var body = $$('body')[0]; // create the imagebox curtain... // basically our semi-opaque black background... var curtain = Builder.node('div', {id: 'imagebox_curtain'}); // create the imagebox viewer... // this will house the actual image that you see... var viewer = Builder.node('div', {id: 'imagebox_viewer'}, [ Builder.node('div', {id: 'imagebox_viewer_loader'}, [ Builder.node('img', {src: this.basepath + 'images/loader.gif', alt: ''}), Builder.node('div', 'loading') ]), Builder.node('div', {id: 'imagebox_viewer_image'}) ]); // create the imagebox status bar... // this will contain the caption and voting information for our file... // we need a div inside a div, since the effect we want to apply needs it... // scriptaculous is awesome... var statusBar = Builder.node('div', {id: 'imagebox_status_bar'}, [ Builder.node('div', {id: 'imagebox_status_bar_info'}) ]); // create the imagebox navigator... // this will house the previous | play/pause | next links... var navigator = Builder.node('div', {id: 'imagebox_navigator'}, [ Builder.node('a', {id: 'imagebox_previous_link', href: '', onclick: 'return false;'}), Builder.node('a', {id: 'imagebox_next_link', href: '', onclick: 'return false;'}), Builder.node('a', {id: 'imagebox_playpause_link', href: '', onclick: 'return false;', className: 'imagebox_play_link'}) ]); // finally, the little close button thingy... var close_button = Builder.node('div', {id: 'imagebox_close_button'}, [ Builder.node("div", {className: 'imagebox_close_button_content'}, [ Builder.node("span", "close window "), Builder.node("strong", "X") ]) ]); // add the elements we've created... //body.appendChild(curtain); //body.appendChild(viewer); //body.appendChild(statusBar); //body.appendChild(navigator); //body.appendChild(close_button); // update, IE bug... $('AJAX_CHILD_ELEMENT_APPENDER').appendChild(curtain); $('AJAX_CHILD_ELEMENT_APPENDER').appendChild(viewer); $('AJAX_CHILD_ELEMENT_APPENDER').appendChild(statusBar); $('AJAX_CHILD_ELEMENT_APPENDER').appendChild(navigator); $('AJAX_CHILD_ELEMENT_APPENDER').appendChild(close_button); // some adjustments... //$('imagebox_viewer_image').setStyle({marginTop: this.viewer_padding + 'px'}); // hide the elements we've created... $('imagebox_curtain').hide(); $('imagebox_viewer').hide(); $('imagebox_viewer_image').hide(); $('imagebox_status_bar').hide(); $('imagebox_navigator').hide(); $('imagebox_close_button').hide(); // create the observers... $('imagebox_curtain').observe('click', (function(){this.destroyImageBox();}).bind(this)); $('imagebox_previous_link').observe('click', (function(){this.previousClicked();}).bind(this)); $('imagebox_playpause_link').observe('click', (function(){this.playPauseClicked();}).bind(this)); $('imagebox_next_link').observe('click', (function(){this.nextClicked();}).bind(this)); $('imagebox_close_button').observe('click', (function(){this.destroyImageBox();}).bind(this)); }, // show imagebox function... // this is where the magic starts, where everything is controlled from... showImageBox: function(urls, stats, timeout, start_index) { var destroy_timer = 0; if ($('infiniti_box_background_div').visible()) { //new Effect.Fade('infiniti_box_background_div', {duration: 0.35}); //$('infiniti_box_table').hide(); //$('infiniti_box_black_back_div').hide(); //$('infiniti_box_dark_content_container').hide(); //$('infiniti_box_heavy_loader_div').hide(); //$('infiniti_box_heavy_content_div').hide(); //destroy_timer = 800; } setTimeout((function() { // validation... if (timeout == null) timeout = 5; timeout = parseInt(timeout); if (start_index == null) start_index = 0; start_index = parseInt(start_index); if (!(urls instanceof Array)) urls = Array(); if (!(stats instanceof Array)) stats = Array(); if (timeout < 1) timeout = 5; if (start_index < 0) start_index = 0; this.imagebox_url_collection = urls; this.imagebox_status_collection = stats; this.imagebox_current_index = start_index; this.slideshow_timeout = timeout; this.visible = true; // call the image handler... this.processImageBoxImage(this.imagebox_current_index); }).bind(this), destroy_timer); }, processImageBoxImage: function(index) { // display the viewer... this.showImageBoxViewer(); // drop the curtain... this.dropImageBoxCurtain(); // make sure these are hidden... $('imagebox_navigator').hide(); $('imagebox_status_bar').hide(); $('imagebox_close_button').hide(); if (isIE6) { // hide the extra piece of the curtain if it's there... this.status_height = jQuery('#imagebox_status_bar').height(); var temp_height = jQuery('#imagebox_curtain').height() - this.status_height; jQuery('#imagebox_curtain').css('height', temp_height); this.status_height = 0; } // load the image and it's data... // this function will control the calls to the viewer resizer, animations, etc... if (this.imagebox_url_collection.length > 0) { (function() { this.loadImageData(index); }).bind(this).delay(1); } }, // destroy imagebox function... // this function will gracefully close the imagebox... destroyImageBox: function() { this.visible = false; // hide the viewer image... // IE hack...had to be one somewhere... $('imagebox_viewer_image').hide(); // IE hack...had to be another one somewhere... // this didn't work: $('imagebox_navigator').hide(); new Effect.Fade('imagebox_navigator', {duration: 0.0}); // hide the viewer... $('imagebox_viewer').hide(); // hide the status info... $('imagebox_status_bar').hide(); // hide the close button... $('imagebox_close_button').hide(); // make sure the slideshow is stopped... this.stopSlideShow(); // fade the curtain... if (isIE6) { $('imagebox_curtain').hide(); $$('select').each(function(node){node.style.visibility='visible';}); } else { new Effect.Fade('imagebox_curtain', {duration:0.3, afterFinish:function() { $$('select').each(function(node){node.style.visibility='visible';}); }}); } }, // previous clicked function... // this function will process and display the previous file image... previousClicked: function() { // go to the previous image if it's available... if (this.imagebox_url_collection.length > 1) { if (this.imagebox_current_index == 0) this.imagebox_current_index = (this.imagebox_url_collection.length - 1); else this.imagebox_current_index--; this.processImageBoxImage(this.imagebox_current_index); } }, // next clicked function... // this function will process and display the next image... nextClicked: function() { // go to the next image if it's available... if (this.imagebox_url_collection.length > 1) { if (this.imagebox_current_index == (this.imagebox_url_collection.length - 1)) this.imagebox_current_index = 0; else this.imagebox_current_index++; this.processImageBoxImage(this.imagebox_current_index); } }, // play | pause clicked function... // this function is triggered whenever the play | pause button is clicked... // it will also make any relevant slideshow start / stop calls... playPauseClicked: function() { var c = $('imagebox_playpause_link').className; if (c == "imagebox_play_link") { // user is trying to play the slideshow... // change to pause button, and set timers... $('imagebox_playpause_link').className = 'imagebox_pause_link'; this.startSlideShow(); } else { // user is trying to pause the slideshow... // change to play button, and remove timers... $('imagebox_playpause_link').className = 'imagebox_play_link'; this.stopSlideShow(); } }, // play slideshow function... // this is more of a helper function, to create the imagebox, then to start the show... playSlideShow: function(urls, stats, timeout, start_index) { this.slideshow_started = true; this.showImageBox(urls, stats, timeout, start_index); }, // start slideshow function... // this function will start the slideshow, set timer, etc... startSlideShow: function() { this.slideshow_started = true; this.showImageBoxNavigator(); this.slideshow_timer = (function() { this.nextClicked(); }).bind(this).delay(this.slideshow_timeout); }, // stop slideshow function... // this function will stop the slideshow... stopSlideShow: function() { this.slideshow_started = false; this.showImageBoxNavigator(); clearTimeout(this.slideshow_timer); }, // load image data function... // this function will load the image data, and the associated caption and vote information... // it will also control the calls to the functions responsible // for viewer resizing, fading in the image, dropping the caption bar, etc... loadImageData: function(file_index) { this.status_available = false; // our image container... var img = new Image(); img.onload = (function() { this.scaleImageBoxViewer(img); }).bind(this); // first, let's get the caption information... // if we're successful, then get the image data itself... if (this.imagebox_status_collection.length > file_index && this.imagebox_status_collection[file_index] != '') { this.status_available = true; new Ajax.Updater('imagebox_status_bar_info', this.imagebox_status_collection[file_index], {method: 'get', onSuccess: (function() { img.src = this.imagebox_url_collection[file_index]; }).bind(this)}); } else img.src = this.imagebox_url_collection[file_index]; }, // scale imagebox viewer function... // this function will resize the viewer, given the containing image dimensions... scaleImageBoxViewer: function(img) { // get the necessary width and height information... img_width = img.width; img_height = img.height; // just get the slideshow timeout variable quick... // this could go somewhere else, avoid continuous checking... // this could be TODO... if ($('imagebox_slideshow_timeout')) this.slideshow_timeout = $('imagebox_slideshow_timeout').value; if (parseInt(this.slideshow_timeout) <= 0) this.slideshow_timeout = 5; // adjust the value... this.slideshow_timeout = this.slideshow_timeout * 1000; this.slideshow_timeout = this.slideshow_timeout + 500; this.slideshow_timeout = this.slideshow_timeout / 1000; // get the div and hide the loader... var div = $('imagebox_viewer') $('imagebox_viewer_loader').hide(); // adjust the new widths and heights to cater for the padding and borders... var new_width = img_width + (this.viewer_padding * 2); var new_height = img_height + (this.viewer_padding * 2) - 10; // make sure we have a min. width... if (new_width < 250) new_width = 250; var old_width = parseInt(div.style.width); var old_height = parseInt(div.style.height); width_perc = ((new_width) / old_width) * 100; height_perc = ((new_height) / old_height) * 100; var background_width_perc = ((new_width + 50) / (old_width + 50)) * 100; var background_height_perc = ((new_height + 50) / (old_height + 50)) * 100; if (width_perc != 100) { new Effect.Scale('imagebox_viewer', width_perc, { scaleY:false, scaleFromCenter:true, scaleContent:false, duration:0.5, afterFinish:(function() { if (height_perc != 100) { new Effect.Scale('imagebox_viewer', height_perc, { scaleX:false, scaleFromCenter:true, scaleContent:false, duration:0.5, scaleMode:{originalWidth: old_width, originalHeight: old_height} }); } }), scaleMode:{originalWidth: old_width, originalHeight: old_height} }); if (isIE6) { new Effect.Scale('imagebox_curtain', background_width_perc, { scaleY:false, scaleFromCenter:true, scaleContent:false, duration:0.5, afterFinish:(function() { if (height_perc != 100) { new Effect.Scale('imagebox_curtain', background_height_perc, { scaleX:false, scaleFromCenter:true, scaleContent:false, duration:0.5, scaleMode:{originalWidth: old_width + 50, originalHeight: old_height + 50} }); } }), scaleMode:{originalWidth: old_width + 50, originalHeight: old_height + 50} }); } } else if (height_perc != 100) { new Effect.Scale('imagebox_viewer', height_perc, { scaleX:false, scaleFromCenter:true, scaleContent:false, duration:0.5, scaleMode:{originalWidth: old_width, originalHeight: old_height} }); if (isIE6) { new Effect.Scale('imagebox_viewer', background_height_perc, { scaleX:false, scaleFromCenter:true, scaleContent:false, duration:0.5, scaleMode:{originalWidth: old_width + 50, originalHeight: old_height + 50} }); } } // set the delay for the image appear-ness... var delay = 150; if (width_perc != 100) delay += 500; if (height_perc != 100) delay += 500; // show the image... (function() { if (this.visible) { $('imagebox_viewer_image').setStyle({backgroundImage: "url(" +img.src+ ")", height: img.height + "px"}); new Effect.Appear('imagebox_viewer_image', {duration: 0.4, afterFinish: (function() { // load the previous / play | pause / next links... this.showImageBoxNavigator(); }).bind(this)}); } }).bind(this).delay(delay / 1000); // drop the status bar... if (this.status_available) { delay += 450; (function() { if (this.visible) { var t = parseInt(div.offsetTop) + parseInt(div.clientHeight); var l = div.offsetLeft; var w = parseInt(new_width); $('imagebox_status_bar').setStyle({top: t + 'px', left: l + 'px', width: w + 'px'}); $('imagebox_viewer').setStyle({borderBottomStyle: "none"}); new Effect.SlideDown('imagebox_status_bar', {duration: 0.4}); if (isIE6) { this.status_height = jQuery('#imagebox_status_bar').height(); var temp_height = jQuery('#imagebox_curtain').height() + this.status_height; jQuery('#imagebox_curtain').css('height', temp_height+'px'); //jQuery('#imagebox_curtain').animate({height: temp_height+'px'}, 400); } } }).bind(this).delay(delay / 1000); } // show the close button... // addition: check for slideshow, if active, process next frame, else destroy... delay += 450; (function() { if (this.visible) { // slideshow... if (this.slideshow_started) { this.slideshow_timer = (function() { //if ($('imagebox_next_file')) this.nextClicked(); //else // this.destroyImageBox(); }).bind(this).delay(this.slideshow_timeout); } // close button... this.showCloseButton(parseInt(new_width)); } }).bind(this).delay(delay / 1000); }, // get page size function... // this function will return an array containing the page's width and height... getPageSize: function() { var body = $$('body')[0]; var width = body.scrollWidth; // the above seems to work well enough... //var width = (body.offsetWidth >= body.scrollWidth ? body.offsetWidth : body.scrollWidth); var height = (body.offsetHeight >= body.scrollHeight ? body.offsetHeight : body.scrollHeight); return [width, height]; }, // get page scroll function... // this function will return the page's current left and top scroll distances respectively... getPageScroll: function() { var html = $$('html')[0]; var top = html.scrollTop; var left = html.scrollLeft; return [left, top]; }, // show imagebox viewer function... // this function will display the main viewer window the images will appear in... showImageBoxViewer: function() { // make sure the viewer is hidden... $('imagebox_viewer_image').hide(); // reset any border nonsense... $('imagebox_viewer').setStyle({borderBottomStyle: "solid"}); if ($('imagebox_viewer').style.display == "none") { // work out the center, move and display... // first, reset the viewer... this.resetImageBoxViewer(); } // make sure it's shown... $('imagebox_viewer').setStyle({display: 'block'}); $('imagebox_viewer_loader').setStyle({display: 'block'}); if (isIE6) $('imagebox_curtain').setStyle({display: 'block'}); }, // reset imagebox function... // this function will reset the viewer... resetImageBoxViewer: function() { // apply the necessary styles and whatnot... $('imagebox_viewer').setStyle({width: "200px", height: "200px"}); // now for the positioning... // first, get the page dims and scroll amounts... var scrolls = this.getPageScroll(); var dims = this.getPageSize(); // next, work out the x-coord... var x = parseInt($('imagebox_viewer').style.width); x = (-1) * parseInt(x / 2); x += parseInt(dims[0] / 2); x += parseInt(scrolls[0]); // then the y-coord... // this is worked out to cater for the maximum image size of 640x480 with some space at the top... // update: has been re-adjusted from '190' to '240' to accomodate portrait images... var y = 240; y += parseInt(scrolls[1]); // apply the style and display the viewer... $('imagebox_viewer').setStyle({left: x + 'px', top: y + 'px'}); if (isIE6) { $('imagebox_curtain').setStyle({width: "250px", height: "250px", position: "absolute"}); $('imagebox_curtain').setStyle({backgroundColor: "#333333", padding:"10px 0px 0px 0px"}); $('imagebox_curtain').setStyle({left: (x-25) + 'px', top: (y-25) + 'px'}); this.status_height = 0; } }, // drop imagebox curtain function... // this function will appear the imagebox curtain... dropImageBoxCurtain: function() { $$('select').each(function(node){node.style.visibility='hidden';}); if (!isIE6) { // adjust the necessary style properties... if ($('imagebox_curtain').style.display == "none") { var dim = this.getPageSize(); $('imagebox_curtain').style.width = '100%'; $('imagebox_curtain').style.height = '100%'; //$('imagebox_curtain').setStyle({width: dim[0], height: dim[1]}); new Effect.Appear('imagebox_curtain', {duration:0.3, from:0.0, to:0.8}); } } }, // show imagebox navigator function... // this function will size, position, and display the navigator... showImageBoxNavigator: function() { var div = $('imagebox_viewer'); var t = div.offsetTop; var l = div.offsetLeft; var w = parseInt(div.clientWidth) + (2 * parseInt(this.viewer_border)); var h = parseInt(div.clientHeight); $('imagebox_navigator').setStyle({top: t + 'px', left: l + 'px', width: w + "px", height: h + "px"}); $('imagebox_navigator').show(); $('imagebox_previous_link').hide(); $('imagebox_playpause_link').hide(); $('imagebox_next_link').hide(); $('imagebox_playpause_link').setStyle({float: "right"}); if (this.slideshow_started) { $('imagebox_playpause_link').className = "imagebox_pause_link"; $('imagebox_playpause_link').style.width = "98%"; $('imagebox_playpause_link').show(); } else { $('imagebox_playpause_link').className = "imagebox_play_link"; $('imagebox_playpause_link').style.width = "30%"; $('imagebox_playpause_link').show(); if (this.imagebox_url_collection.length > 1) { $('imagebox_next_link').show(); $('imagebox_previous_link').show(); } else //$('imagebox_playpause_link').style.width = "98%"; $('imagebox_playpause_link').hide(); } }, // show close button function... // this function will position the close button box, and appear // it if it's not visible already... showCloseButton: function(width) { var stat = null; var width = parseInt(width); if ($('imagebox_status_bar').style.display != "none") stat = $('imagebox_status_bar'); else stat = $('imagebox_viewer'); var div = $('imagebox_close_button'); var t = parseInt(stat.style.top) + parseInt(stat.clientHeight) + 3; t = parseInt($('imagebox_viewer').style.top) - 15; var l = parseInt(stat.style.left); l += width - 82; div.setStyle({top: t + 'px', left: l + 'px'}); if (div.style.display == "none") new Effect.Appear('imagebox_close_button', {duration: 0.4}); } } // helper functions... // first off, the show lightbox function... // just attach this to any onlick event to make use of the imagebox... function showImageBox(urls, stats, timeout, start_index) { ImageBox.showImageBox(urls, stats, timeout, start_index); } // now, a function to start the slideshow... // takes one parameter, the file id to start the show on... function imageboxPlaySlideShow(urls, stats, timeout, start_index) { ImageBox.playSlideShow(urls, stats, timeout, start_index); } // create the imagebox once the page has loaded... document.observe('dom:loaded', function(){ImageBox = new IB();});