2 This file is part of JonDesign's SmoothGallery v1.0.1.
4 JonDesign's SmoothGallery is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 JonDesign's SmoothGallery is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with JonDesign's SmoothGallery; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 Main Developer: Jonathan Schemoul (JonDesign: http://www.jondesign.net/)
20 - Christian Ehret (bugfix)
22 - Valerio from Mad4Milk for his great help with the carousel scrolling and many other things.
23 - Archie Cowan for helping me find a bugfix on carousel inner width problem.
25 - The mootools team for the great mootools lib, and it's help and support throughout the project.
29 var $removeEvents = function (object, type)
31 if (!object.events) return object;
33 if (!object.events[type]) return object;
34 for (var fn in object.events[type]) object.removeEvent(type, fn);
35 object.events[type] = null;
37 for (var evType in object.events) object.removeEvents(evType);
44 // declaring the class
45 var gallery = new Class({
46 initialize: function(element, options) {
51 showDescription: false,
62 elementSelector: "div.imageElement",
64 subtitleSelector: "p",
65 descriptionSelector: "div",
66 linkSelector: "a.open",
67 imageSelector: "img.full",
68 thumbnailSelector: "img.thumbnail",
69 slideInfoZoneOpacity: 0.7,
70 carouselMinimizedOpacity: 0.4,
71 carouselMinimizedHeight: 20,
72 carouselMaximizedOpacity: 0.7,
73 destroyAfterPopulate: true,
74 baseClass: 'jdGallery',
75 withArrowsClass: 'withArrows',
76 textShowCarousel: 'Pictures',
77 useThumbGenerator: false,
78 thumbGenerator: 'resizer.php'
80 this.fireEvent('onInit');
84 this.galleryElement = element;
85 this.galleryData = this.options.manualData;
87 this.galleryElements = Array();
88 this.thumbnailElements = Array();
89 this.galleryElement.addClass(this.options.baseClass);
90 if (this.options.populateData)
92 element.style.display="block";
94 if (this.options.embedLinks)
96 this.currentLink = new Element('a').addClass('open').setProperties({
99 }).injectInside(element);
100 if ((!this.options.showArrows) && (!this.options.showCarousel))
101 this.galleryElement = element = this.currentLink;
103 this.currentLink.setStyle('display', 'none');
106 this.constructElements();
107 if ((data.length>1)&&(this.options.showArrows))
109 var leftArrow = new Element('a').addClass('left').addEvent(
111 this.prevItem.bind(this)
112 ).injectInside(element);
113 var rightArrow = new Element('a').addClass('right').addEvent(
115 this.nextItem.bind(this)
116 ).injectInside(element);
117 this.galleryElement.addClass(this.options.withArrowsClass);
119 this.loadingElement = new Element('div').addClass('loadingElement').injectInside(element);
120 if (this.options.showInfopane) this.initInfoSlideshow();
121 if (this.options.showCarousel) this.initCarousel();
124 populateData: function() {
125 currentArrayPlace = this.galleryData.length;
126 options = this.options;
127 data = this.galleryData;
128 this.galleryElement.getElements(options.elementSelector).each(function(el) {
130 image: el.getElement(options.imageSelector).getProperty('src'),
131 number: currentArrayPlace
133 if ((options.showInfopane) | (options.showCarousel))
134 Object.extend(elementDict, {
135 title: el.getElement(options.titleSelector).innerHTML,
136 description: el.getElement(options.subtitleSelector).innerHTML
138 if ((options.showDescription))
139 Object.extend(elementDict, {
140 outsideDescription: el.getElement(options.descriptionSelector).innerHTML
142 if (options.embedLinks)
143 Object.extend(elementDict, {
144 link: el.getElement(options.linkSelector).href||false,
145 linkTitle: el.getElement(options.linkSelector).title||false
147 if ((!options.useThumbGenerator) && (options.showCarousel))
148 Object.extend(elementDict, {
149 thumbnail: el.getElement(options.thumbnailSelector).src
151 else if (options.useThumbGenerator)
152 Object.extend(elementDict, {
153 thumbnail: 'resizer.php?imgfile=' + elementDict.image + '&max_width=' + options.thumbWidth + '&max_height=' + options.thumbHeight
156 data[currentArrayPlace] = elementDict;
158 if (this.options.destroyAfterPopulate)
161 this.galleryData = data;
162 this.fireEvent('onPopulated');
164 constructElements: function() {
165 el = this.galleryElement;
166 this.maxIter = this.galleryData.length;
168 for(i=0;i<this.galleryData.length;i++)
170 var currentImg = new Fx.Style(
171 new Element('div').addClass('slideElement').setStyles({
172 'position':'absolute',
177 'backgroundImage':"url('" + this.galleryData[i].image + "')",
178 'backgroundPosition':"center center",
182 {duration: this.options.fadeDuration}
184 this.galleryElements[parseInt(i)] = currentImg;
187 destroySlideShow: function(element) {
188 var myClassName = element.className;
189 var newElement = new Element('div').addClass('myClassName');
190 element.parentNode.replaceChild(newElement, element);
192 startSlideShow: function() {
193 this.fireEvent('onStart');
194 this.loadingElement.style.display = "none";
195 this.lastIter = this.maxIter - 1;
196 this.currentIter = 0;
197 this.galleryInit = 0;
198 this.galleryElements[parseInt(this.currentIter)].set(1);
199 if (this.options.showInfopane)
200 this.showInfoSlideShow.delay(1000, this);
202 if (this.options.embedLinks)
203 this.makeLink(this.currentIter);
205 nextItem: function() {
206 this.fireEvent('onNextCalled');
207 this.nextIter = this.currentIter+1;
208 if (this.nextIter >= this.maxIter)
210 this.galleryInit = 0;
211 this.goTo(this.nextIter);
213 prevItem: function() {
214 this.fireEvent('onPreviousCalled');
215 this.nextIter = this.currentIter-1;
216 if (this.nextIter <= -1)
217 this.nextIter = this.maxIter - 1;
218 this.galleryInit = 0;
219 this.goTo(this.nextIter);
221 goTo: function(num) {
223 if (this.options.embedLinks)
225 if (this.options.showInfopane)
227 this.slideInfoZone.clearChain();
228 this.hideInfoSlideShow().chain(this.changeItem.pass(num, this));
230 this.changeItem.delay(500, this, num);
231 if (this.options.embedLinks)
233 if (this.options.showDescription)
234 this.showDescription(num);
236 /*if (this.options.showCarousel)
237 this.clearThumbnailsHighlights();*/
239 changeItem: function(num) {
240 this.fireEvent('onStartChanging');
241 this.galleryInit = 0;
242 if (this.currentIter != num)
244 for(i=0;i<this.maxIter;i++)
246 if ((i != this.currentIter)) this.galleryElements[i].set(0);
248 if (num > this.currentIter) this.galleryElements[num].custom(1);
251 this.galleryElements[num].set(1);
252 this.galleryElements[this.currentIter].custom(0);
254 this.currentIter = num;
256 this.doSlideShow.bind(this)();
257 this.fireEvent('onChanged');
259 clearTimer: function() {
260 if (this.options.timed)
263 prepareTimer: function() {
264 if (this.options.timed)
265 this.timer = this.nextItem.delay(this.options.delay, this);
267 doSlideShow: function(position) {
268 if (this.galleryInit == 1)
270 imgPreloader = new Image();
271 imgPreloader.onload=function(){
272 this.startSlideShow.delay(10, this);
274 imgPreloader.src = this.galleryData[0].image;
276 if (this.options.showInfopane)
278 if (this.options.showInfopane)
280 this.showInfoSlideShow.delay((500 + this.options.fadeDuration), this);
282 if (this.options.showCarousel)
283 this.centerCarouselOn(position);
287 initCarousel: function () {
288 var carouselContainerElement = new Element('div').addClass('carouselContainer').injectInside(this.galleryElement);
289 this.carouselContainer = new Fx.Styles(carouselContainerElement, {transition: Fx.Transitions.expoOut});
290 this.carouselContainer.normalHeight = carouselContainerElement.offsetHeight;
291 this.carouselContainer.set({'opacity': this.options.carouselMinimizedOpacity, 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight)});
293 this.carouselBtn = new Element('a').addClass('carouselBtn').setProperties({
294 title: this.options.textShowCarousel
295 }).setHTML(this.options.textShowCarousel).injectInside(carouselContainerElement);
297 this.carouselBtn.addEvent(
300 this.carouselContainer.clearTimer();
301 this.toggleCarousel();
304 this.carouselActive = false;
306 var carouselElement = new Element('div').addClass('carousel').injectInside(carouselContainerElement);
307 this.carousel = new Fx.Styles(carouselElement);
309 this.carouselLabel = new Element('p').addClass('label').injectInside(this.carousel.element);
310 this.carouselWrapper = new Element('div').addClass('carouselWrapper').injectInside(this.carousel.element);
311 this.carouselInner = new Element('div').addClass('carouselInner').injectInside(this.carouselWrapper);
313 this.carouselWrapper.scroller = new Scroller(this.carouselWrapper, {
318 this.carouselWrapper.elementScroller = new Fx.Scroll(this.carouselWrapper, {
320 onStart: this.carouselWrapper.scroller.stop.bind(this.carouselWrapper.scroller),
321 onComplete: this.carouselWrapper.scroller.start.bind(this.carouselWrapper.scroller)
324 this.constructThumbnails();
326 this.carouselInner.style.width = ((this.maxIter * (this.options.thumbWidth + this.options.thumbSpacing)) - this.options.thumbSpacing + this.options.thumbWidth) + "px";
328 toggleCarousel: function() {
329 if (this.carouselActive)
334 showCarousel: function () {
335 this.fireEvent('onShowCarousel');
336 this.carouselContainer.custom({
337 'opacity': this.options.carouselMaximizedOpacity,
339 }).addEvent('onComplete', function() { this.carouselActive = true; this.carouselWrapper.scroller.start(); }.bind(this));
341 hideCarousel: function () {
342 this.fireEvent('onHideCarousel');
343 this.carouselContainer.custom({
344 'opacity': this.options.carouselMinimizedOpacity,
345 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight)
346 }).addEvent('onComplete', function() { this.carouselActive = false; this.carouselWrapper.scroller.stop(); }.bind(this));
348 constructThumbnails: function () {
349 element = this.carouselInner;
350 for(i=0;i<this.galleryData.length;i++)
352 var currentImg = new Fx.Style(new Element ('div').addClass("thumbnail").setStyles({
353 backgroundImage: "url('" + this.galleryData[i].thumbnail + "')",
354 backgroundPosition: "center center",
355 backgroundRepeat: 'no-repeat',
356 marginLeft: this.options.thumbSpacing + "px",
357 width: this.options.thumbWidth + "px",
358 height: this.options.thumbHeight + "px"
359 }).injectInside(element), "opacity", {duration: 200}).set(0.2);
360 currentImg.element.addEvents({
361 'mouseover': function (myself) {
364 $(this.carouselLabel).setHTML('<span class="number">' + (myself.relatedImage.number + 1) + "/" + this.maxIter + ":</span> " + myself.relatedImage.title);
365 }.pass(currentImg, this),
366 'mouseout': function (myself) {
369 }.pass(currentImg, this),
370 'click': function (myself) {
371 this.goTo(myself.relatedImage.number);
372 }.pass(currentImg, this)
375 currentImg.relatedImage = this.galleryData[i];
376 this.thumbnailElements[parseInt(i)] = currentImg;
379 clearThumbnailsHighlights: function()
381 for(i=0;i<this.galleryData.length;i++)
383 this.thumbnailElements[i].clearTimer();
384 this.thumbnailElements[i].custom(0.2);
387 centerCarouselOn: function(num) {
388 var carouselElement = this.thumbnailElements[num];
389 var position = carouselElement.element.offsetLeft + (carouselElement.element.offsetWidth / 2);
390 var carouselWidth = this.carouselWrapper.offsetWidth;
391 var carouselInnerWidth = this.carouselInner.offsetWidth;
392 var diffWidth = carouselWidth / 2;
393 var scrollPos = position-diffWidth;
394 this.carouselWrapper.elementScroller.scrollTo(scrollPos,0);
396 initInfoSlideshow: function() {
397 /*if (this.slideInfoZone.element)
398 this.slideInfoZone.element.remove();*/
399 this.slideInfoZone = new Fx.Styles(new Element('div').addClass('slideInfoZone').injectInside($(this.galleryElement))).set({'opacity':0});
400 var slideInfoZoneTitle = new Element('h2').injectInside(this.slideInfoZone.element);
401 var slideInfoZoneDescription = new Element('p').injectInside(this.slideInfoZone.element);
402 this.slideInfoZone.normalHeight = this.slideInfoZone.element.offsetHeight;
403 this.slideInfoZone.element.setStyle('opacity',0);
405 changeInfoSlideShow: function()
407 this.hideInfoSlideShow.delay(10, this);
408 this.showInfoSlideShow.delay(500, this);
410 showInfoSlideShow: function() {
411 this.fireEvent('onShowInfopane');
412 this.slideInfoZone.clearTimer();
413 element = this.slideInfoZone.element;
414 element.getElement('h2').setHTML(this.galleryData[this.currentIter].title);
415 element.getElement('p').setHTML(this.galleryData[this.currentIter].description);
416 this.slideInfoZone.custom({'opacity': [0, this.options.slideInfoZoneOpacity], 'height': [0, this.slideInfoZone.normalHeight]});
417 if (this.options.showCarousel)
418 this.slideInfoZone.chain(this.centerCarouselOn.pass(this.currentIter, this));
419 return this.slideInfoZone;
421 hideInfoSlideShow: function() {
422 this.fireEvent('onHideInfopane');
423 this.slideInfoZone.clearTimer();
424 this.slideInfoZone.custom({'opacity': 0, 'height': 0});
425 return this.slideInfoZone;
427 makeLink: function(num) {
428 this.currentLink.setProperties({
429 href: this.galleryData[num].link,
430 title: this.galleryData[num].linkTitle
432 if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
433 this.currentLink.setStyle('display', 'block');
435 showDescription: function(num) {
436 var descObj = document.getElementById('DescriptionDiv');
438 descObj.setHTML(this.galleryData[num].outsideDescription);
440 clearLink: function() {
441 this.currentLink.setProperties({href: '', title: ''});
442 if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
443 this.currentLink.setStyle('display', 'none');
446 gallery.implement(new Events);
447 gallery.implement(new Options);
449 /* All code copyright 2006 Jonathan Schemoul */