/* * Onionlab * Alfonso Ruzafa * * JS slideshows utils * * $Id: slideshows.js,v 1.10 2008/11/29 11:24:28 superruzafa Exp $ */ var IMAGE_SINGLE_SHOW_DURATION = 5; var IMAGE_MULTIPLE_SHOW_DURATION = 0.5; var TRANSITION_INTERVAL = 0.05; var TRANSITION_OPACITY_INCREMENT = 0.2; var TRANSITIONS_PER_ITERATION = 1; var RANDOM_TRANSITIONS = false; var SlideshowContainer = Class.create ({ initialize: function () { this.slideshows = []; this.slideshows_order = []; this.current_slideshow = 0; }, add: function (slideshow) { this.slideshows.push(slideshow); }, start: function () { if (this.slideshows.length < 1 || (this.slideshows.size() == 1 && this.slideshows[0].images.size() <= 1)) { return; } var i = 0; this.slideshows_order = []; this.current_slideshow = 0; for (i = 0; i < this.slideshows.length; i++) { if (RANDOM_TRANSITIONS) { pos = parseInt(Math.random() * this.slideshows.length); while (this.slideshows_order[pos] != undefined) { pos = (pos + 1) % this.slideshows.length; } this.slideshows_order[pos] = i; } else { this.slideshows_order[i] = i; } } var duration = this.slideshows.size() == 1 ? IMAGE_SINGLE_SHOW_DURATION : IMAGE_MULTIPLE_SHOW_DURATION; /* Using a modifier version of prototype.js. * It's needed to add a param to PeriodicalExecuter constructor * to pass an object what will be passed later to function through * pe. */ new PeriodicalExecuter( function (pe) { var parent = pe.object; var i = 0; var max_transitions_per_iteration = Math.min(TRANSITIONS_PER_ITERATION, parent.slideshows.size()); for (i = 0; i < max_transitions_per_iteration; i++) { parent.slideshows[parent.slideshows_order[parent.current_slideshow]].transition(); parent.current_slideshow = (parent.current_slideshow + 1) % parent.slideshows_order.size(); } }, duration, this); } }); var Slideshow = Class.create ({ initialize: function (id) { this.images = []; this.links = []; this.z_index = 10000; this.top_image_index = 0; this.id = id; }, add: function (image, link) { Element.extend(image); this.images.push(image); image.style.zIndex = this.z_index--; image.style.visibility = "visible"; image.setOpacity(1.0); image.opacity = 1.0; image.index = this.images.length - 1; image.slideshow = this; image.observe("click", this.move_to_next); if (link != null && link != undefined) { Element.extend(link); this.links.push(link); link.index = this.images.length - 1; link.slideshow = this; link.observe("click", this.move_to); } }, transition: function () { if (this.images.size() < 1) return; /* Using a modifier version of prototype.js. * It's needed to add a param to PeriodicalExecuter constructor * to pass an object what will be passed later to function through * pe. */ new PeriodicalExecuter ( function (pe) { var parent = pe.object; var image = parent.images[parent.top_image_index]; image.opacity -= TRANSITION_OPACITY_INCREMENT; if (image.opacity <= 0.0) { image.style.zIndex -= parent.images.length; image.opacity = 1.0; image.setOpacity(1.0); if (parent.links[parent.top_image_index] != null && parent.links[parent.top_image_index] != undefined) { parent.links[parent.top_image_index].removeClassName("selected"); parent.top_image_index = (parent.top_image_index + 1) % parent.images.length; parent.links[parent.top_image_index].addClassName("selected"); } else { parent.top_image_index = (parent.top_image_index + 1) % parent.images.length; } pe.stop(); } else { image.setOpacity(image.opacity); } }, TRANSITION_INTERVAL, this); }, start: function (event) { if (this.images.size() > 0) { /* Using a modifier version of prototype.js. * It's needed to add a param to PeriodicalExecuter constructor * to pass an object what will be passed later to function through * pe. */ new PeriodicalExecuter ( function (pe) { pe.object.transition(); }, IMAGE_SHOW_DURATION, this); } }, move_to: function (event) { var image = Event.element(event); var slideshow = image.slideshow; while (slideshow.top_image_index != image.index) { slideshow.links[slideshow.top_image_index].removeClassName("selected"); slideshow.images[slideshow.top_image_index].style.zIndex -= slideshow.images.length; slideshow.images[slideshow.top_image_index].style.opacity = 1.0; slideshow.images[slideshow.top_image_index].setOpacity(1.0); slideshow.top_image_index = (slideshow.top_image_index + 1) % slideshow.images.size(); } slideshow.links[slideshow.top_image_index].addClassName("selected"); Event.stop(event); }, move_to_next: function (event) { var image = Event.element(event); var slideshow = image.slideshow; slideshow.transition(); // Event.stop(event); } }); slideshow_load = function (event) { var slideshow_containers = $$("div.slideshow-container"); var i, j; var slideshows_container = new SlideshowContainer(); for (i = 0; i < slideshow_containers.length; i++) { slideshow = new Slideshow(i); var slideshow_images = slideshow_containers[i].getElementsByTagName("img"); var slideshow_links = slideshow_containers[i].getElementsByTagName("a"); for (j = 0; j < slideshow_images.length; j++) { slideshow.add(slideshow_images.item(j), slideshow_links.item(j)); } slideshows_container.add(slideshow); } slideshows_container.start(); } Event.observe(window, "load", slideshow_load);