1/** 2 * Class for loading and displaying a gallery using XHR. 3 * @author Jeff Fohl 4 * @copyright Godengo Inc., 2009 5 * 6 * * Updated: 2012 7 * by Peter Scannell for Godengo-Texterity 8 * 9 * DEPENDENCIES: 10 * jQuery 11 * 12 **/ 13 14var slideshowGalleryObjects = []; 15 16function SlideshowGallery(galleryContainer, galleryId, options) { 17 this.initialize(galleryContainer, galleryId, options); 18} 19 20function resizeSlideshowGalleryContents() { 21 rjQuery.each(slideshowGalleryObjects, function() { 22 this.setGalleryContainerHeight(); 23 this.setContentContainerHeight(); 24 this.setNavigationMenu("resize"); 25 }); 26} 27 28 29SlideshowGallery.prototype = { 30 initialize: function(galleryContainer, galleryID, options) { 31 // parameters. these are the default values. 32 this.options = rjQuery.extend({ 33 increment : 2, // seconds between fades 34 fadeSpeed : 0.5, // duration of fade in seconds 35 aspectRatio : 1, // aspect ratio (width/height) 36 mouseActuation: "click", // type of mouse interaction: "click" or "hover" 37 fixNavMenu: false // adjust navigation menu - for horizontal menu only 38 }, options || {}); 39 40 this.galleryContainer = rjQuery("#"+galleryContainer); 41 42 this.playSpeed = this.options.increment*1000; // time in seconds before start of next fade 43 this.fadeSpeed = (this.options.fadeSpeed*1000)/20; // time in seconds divided by the number of fade increments 44 this.slideIncrement = null; // holds the setTimeout for the next slide 45 46 // these value initialized in initImages 47 this.currentSlide = 0; // the slide that is now visible 48 this.nextSlide = 0; // the next slide to be shown 49 this.first = 0; // the first slide 50 this.last = 0; // the last slide 51 this.firstVisibleMenuItem = 0; 52 53 this.play = true; // play or stop 54 this.playDirection = "forwards"; 55 56 this.initControls(); 57 this.initMenu(); 58 this.initContents(); 59 this.initImages(); 60 61 // after creation setup contents 62 this.setGalleryContainerHeight(); 63 this.setContentContainerHeight(); 64 this.setNavigationMenu("resize"); 65 66/* TODO: Make sure that we don't need this with picturefill 67 // the following parameter tells us if we are using IE 6,7, or 8 so that we can turn on image cache busting if necessary 68 // to avoid Stack overflow bug in IE. See Mantis ticket #23191. - JF 69 this.cacheBust = (Prototype.Browser.IE) && (this.slides.length > 11); 70 this.randomNumber = ''; 71*/ 72 73 slideshowGalleryObjects.push(this); 74 }, 75 76 initImages: function() { 77 this.galleryImages = this.galleryContainer.find(".galleryImage"); 78 this.first = 0; 79 this.last = this.galleryImages.length - 1; 80 this.currentSlide = this.first; 81 this.nextSlide = this.first; // reset in next call 82 // setup current slide, slides opacity/xOpacity, slides to hide/show 83 this.setCurrentSlideFromNext(); 84 }, 85 86 initMenu: function() { 87 this.menuItems = []; 88 var galleryMenu = this.galleryContainer.find(".galleryMenu"); 89 if (galleryMenu.length > 0) { 90 this.menuItems = this.galleryContainer.find(".galleryMenuItem"); 91 this.menuItems.filter(":first").addClass("selected"); 92 93 var that = this; 94 // default event is click 95 if (this.options.mouseActuation == "hover") { 96 rjQuery(galleryMenu).on("hover", ".galleryMenuItem", function(event) { 97 // inArray gives array position for menu item 98 that.playSlide(rjQuery.inArray(this, that.menuItems)); 99 }); 100 } else { 101 rjQuery(galleryMenu).on("click", ".galleryMenuItem", function(event) { 102 // inArray gives array position for menu item 103 that.playSlide(rjQuery.inArray(this, that.menuItems)); 104 }); 105 } 106 } 107 }, 108 109 initContents: function() { 110 this.contents = []; 111 if (this.galleryContainer.find(".contentContainer").length > 0) { 112 this.contents = this.galleryContainer.find(".galleryContent"); 113 if (rjQuery.support.opacity) { 114 this.contents.css({ 115 "opacity": 0, 116 "filter": "alpha(opacity=0)", 117 "visibility": "hidden" 118 }); 119 this.contents.filter(":first") 120 .addClass("selected") 121 .css({ 122 "opacity": 1, 123 "filter": "alpha(opacity=100)", 124 "visibility": "visible" 125 }); 126 } else { 127 this.hideContent(); 128 this.showContent(this.first); 129 } 130 } 131 }, 132 133 initControls: function() { 134 var that = this; 135 this.controls = []; 136 if (this.galleryContainer.find(".controls").length > 0) { 137 this.controls = this.galleryContainer.find("button"); 138 rjQuery(this.controls.siblings(".previous")).on("click", function() { 139 that.playPreviousSlide(); 140 }); 141 rjQuery(this.controls.siblings(".next")).on("click", function() { 142 that.playNextSlide(); 143 }); 144 rjQuery(this.controls.siblings(".playpause")).on("click", function() { 145 that.playPause(); 146 }); 147 this.playPauseButton = rjQuery(this.controls.siblings(".playpause")); 148 rjQuery(this.playPauseButton).find(".play").hide(); 149 rjQuery(this.playPauseButton).find(".pause").show(); 150 this.play = true; // play or stop 151 } 152 // enable next/previous buttons for gallery menu 153 rjQuery(this.galleryContainer.find(".galleryMenu button.btn.previous")).on("click", function() { 154 that.playPreviousSlide(); 155 }); 156 rjQuery(this.galleryContainer.find(".galleryMenu button.btn.next")).on("click", function() { 157 that.playNextSlide(); 158 }); 159 rjQuery(this.galleryContainer.find(".galleryMenuNavigation.previous")).on("click", function() { 160 that.playPreviousSlide(); 161 }); 162 rjQuery(this.galleryContainer.find(".galleryMenuNavigation.next")).on("click", function() { 163 that.playNextSlide(); 164 }); 165 166 }, 167 168 hideSlides: function(slideNum) { 169 if (typeof slideNum == "undefined") { 170 this.galleryImages.hide(); 171 } else { 172 rjQuery(this.galleryImages[slideNum]).hide(); 173 } 174 }, 175 176 showSlides: function(slideNum) { 177 slideNum = typeof slideNum != "undefined" ? slideNum : 0; 178 rjQuery(this.galleryImages[slideNum]).show(); 179 }, 180 181 hideContent: function(slideNum) { 182 if (this.contents.length > 0) { 183 if (typeof slideNum == "undefined") { 184 rjQuery(this.contents).css("visibility","hidden"); 185 } else { 186 rjQuery(this.contents[slideNum]).css("visibility","hidden"); 187 } 188 } 189 }, 190 showContent: function(slideNum) { 191 if (this.contents.length > 0) { 192 slideNum = typeof slideNum != "undefined" ? slideNum : 0; 193 rjQuery(this.contents[slideNum]).css("visibility","visible"); 194 } 195 }, 196 197 incrementGalleryMenu: function() { 198 if (this.menuItems.length > 0) { 199 rjQuery(this.menuItems[this.previousSlide]).removeClass("selected"); 200 rjQuery(this.menuItems[this.currentSlide]).addClass("selected"); 201 } 202 }, 203 204 incrementContents: function() { 205 if (this.contents.length > 0) { 206 rjQuery(this.contents[this.previousSlide]).removeClass("selected"); 207 rjQuery(this.contents[this.currentSlide]).addClass("selected"); 208 } 209 }, 210 211 // Gallery xFade function // 212 xFade: function() { 213 var thisGallery = this; 214 215 // make sure no older fades are hanging around 216 for (var index = thisGallery.first; index < thisGallery.last; index++) { 217 if (index != thisGallery.currentSlide && index != thisGallery.nextSlide) { 218 thisGallery.hideSlides(index); 219 thisGallery.hideContent(index); 220 } 221 } 222 223 var $currentSlide = rjQuery(this.galleryImages[this.currentSlide]); 224 var currentOpacity = Math.round(($currentSlide.prop("xOpacity") - 0.05)*100)/100; 225 var nextOpacity = Math.round((1 - currentOpacity)*100)/100; 226 227 this.showSlides(this.nextSlide); 228 if (rjQuery.support.opacity) { 229 this.showContent(this.nextSlide); 230 } 231 this.setOpacity(this.currentSlide, currentOpacity); 232 this.setOpacity(this.nextSlide, nextOpacity); 233 $currentSlide.prop("xOpacity", currentOpacity); 234 235 if (currentOpacity <= 0) { 236 this.setCurrentSlideFromNext(); 237 if (this.play === true) { 238 this.slideIncrement = window.setTimeout( function(){ thisGallery.xFade() }, this.playSpeed); 239 } 240 } else { 241 this.slideIncrement = window.setTimeout( function(){ thisGallery.xFade() }, this.fadeSpeed); 242 } 243 }, 244 245 // reset xopacity of all slides to 0 246 resetxOpacity : function() { 247 rjQuery(this.galleryImages).prop("xOpacity", 0); 248 }, 249 250 setCurrentSlideFromNext : function() { 251 var $nextSlide = rjQuery(this.galleryImages[this.nextSlide]); 252 this.resetxOpacity(); 253 $nextSlide.prop("xOpacity", 1); 254 this.hideSlides(); 255 this.showSlides(this.nextSlide); 256 this.hideContent(this.currentSlide); 257 this.showContent(this.nextSlide); 258 this.setOpacity(this.nextSlide, 1); 259 this.previousSlide = this.currentSlide; 260 this.currentSlide = this.nextSlide; 261 this.nextSlide = (this.currentSlide + 1) <= this.last ? (this.currentSlide + 1) : this.first; 262 this.incrementContents(); 263 this.incrementGalleryMenu(); 264 this.setNavigationMenu("slide"); 265 }, 266 267 // set the opacity of slides // 268 setOpacity: function (slideNum, opacity) { 269 opacity = typeof opacity != "undefined" ? opacity : 0; 270 rjQuery(this.galleryImages[slideNum]).css({ 271 "opacity": opacity, 272 "filter": "alpha(opacity=" + (opacity*100) + ")" 273 }); 274 if (this.contents.length > 0) { 275 if (rjQuery.support.opacity) { 276 rjQuery(this.contents[slideNum]).css({ 277 "opacity": opacity, 278 "filter": "alpha(opacity=" + (opacity*100) + ")" 279 }); 280 } 281 } 282 }, 283 284 playPreviousSlide: function() { 285 window.clearTimeout(this.slideIncrement); 286 this.play = false;
287 this.playDirection = "backwards"; 288 if (this.controls.length > 0) { 289 rjQuery(this.playPauseButton).find(".pause").hide(); 290 rjQuery(this.playPauseButton).find(".play").show(); 291 } 292 this.nextSlide = this.currentSlide - 1; 293 if (this.nextSlide < 0) { 294 this.nextSlide = this.last; 295 } 296 this.xFade(); 297 }, 298 299 playNextSlide : function() { 300 window.clearTimeout(this.slideIncrement); 301 this.play = false; 302 this.playDirection = "forwards"; 303 if (this.controls.length > 0) { 304 rjQuery(this.playPauseButton).find(".pause").hide(); 305 rjQuery(this.playPauseButton).find(".play").show(); 306 } 307 this.nextSlide = this.currentSlide + 1; 308 if (this.nextSlide >= this.galleryImages.length) { 309 this.nextSlide = this.first; 310 } 311 this.xFade(); 312 }, 313 314 playSlide : function(slideNum) { 315 slideNum = typeof slideNum != "undefined" ? slideNum : 0; 316 this.play = false; 317 window.clearTimeout(this.slideIncrement); 318 if (this.controls.length > 0) { 319 rjQuery(this.playPauseButton).find(".pause").hide(); 320 rjQuery(this.playPauseButton).find(".play").show(); 321 } 322 this.nextSlide = slideNum; 323 if (slideNum == this.currentSlide) { 324 this.setCurrentSlideFromNext(); 325 } else { 326 this.xFade(); 327 } 328 }, 329 330 playPause : function() { 331 if (this.play === true) { 332 window.clearTimeout(this.slideIncrement); 333 this.play = false; 334 this.playDirection = null; 335 if (this.controls.length > 0) { 336 rjQuery(this.playPauseButton).find(".pause").hide(); 337 rjQuery(this.playPauseButton).find(".play").show(); 338 } 339 } else { 340 window.clearTimeout(this.slideIncrement); 341 this.play = true; 342 this.playDirection = "forward"; 343 if (this.controls.length > 0) { 344 rjQuery(this.playPauseButton).find(".play").hide(); 345 rjQuery(this.playPauseButton).find(".pause").show(); 346 } 347 this.xFade(); 348 } 349 }, 350 351 setGalleryContainerHeight : function () { 352 var imageContainer = this.galleryContainer.find(".imageContainerSpace"); 353 var galleryContainer = this.galleryContainer.find(".galleryMenuSpace"); 354 var containerHeight = imageContainer.width() / this.options.aspectRatio; 355 imageContainer.css({"min-height":containerHeight}); 356 galleryContainer.css({"min-height":containerHeight}); 357 }, 358 359 setContentContainerHeight : function() { 360 if (0 != this.galleryContainer.find(".contentContainerSpace").length) { 361 var heights = new Array(); 362 var galleryContents = this.galleryContainer.find(".galleryContent"); 363 rjQuery.each(galleryContents,function(key,value) { 364 heights.push(rjQuery(value).height()); 365 }); 366 var max = Math.max.apply(Math,heights); 367 var contentContainer = this.galleryContainer.find(".contentContainerSpace, .contentContainer"); 368 contentContainer.css({"height":max}); 369 // special case for sg-splash-right-menu 370 if (rjQuery(this.galleryContainer).hasClass("sg-splash-right-menu")) { 371 // set the controls to have a bottom value equal to the height of the content container 372 var contentContainerSpaceHeight = this.galleryContainer.find(".contentContainerSpace").innerHeight(); 373 var controls = this.galleryContainer.find(".controls"); 374 controls.css({"bottom":contentContainerSpaceHeight}); 375 } 376 } 377 }, 378 379 /** 380 * Setup the navigation menu at the bottom of the slides. 381 * If the space available to the menu is enough for all the menu items, 382 * then show the menu without left and right arrows. 383 * If the space available to the menu is too small for all the menu items, 384 * then show the menu with left and right arrows and truncate the menu 385 * to fit into the available space. 386 * 387 * If the current menu item is out of the range of the visible menu items, 388 * then set the visible menu items to show the current menu item. 389 * 390 * @params calledFrom 391 * "resize" - called as a result of a resize event 392 * "slide" - called as a result of a change slide action 393 */ 394 setNavigationMenu : function(calledFrom) { 395 if (this.options.fixNavMenu != true) { 396 return; 397 } 398 calledFrom = typeof calledFrom != "undefined" ? calledFrom : "resize"; 399 var $galleryMenuSpace = this.galleryContainer.find(".galleryMenuSpace"); 400 var $galleryMenu = this.galleryContainer.find(".galleryMenu"); 401 if ($galleryMenuSpace.length == 0 || 402 $galleryMenu.length == 0 || 403 this.menuItems.length == 0) { 404 return; 405 } 406 var $nextMenu = $galleryMenuSpace.find(".galleryMenuNavigation.next"); 407 var $prevMenu = $galleryMenuSpace.find(".galleryMenuNavigation.previous"); 408 409 var menuWidth = $galleryMenuSpace.width(); 410 var menuItemWidth = this.menuItems.outerWidth(true); 411 var spaceAvail = parseInt((menuWidth/menuItemWidth), 10); 412 if (spaceAvail < this.menuItems.length) { 413 $nextMenu.show(); 414 $prevMenu.show(); 415 // recalculate spaceAvail with left and right arrows visible 416 var navSlidesWidth = $nextMenu.outerWidth(true) + $prevMenu.outerWidth(true); 417 spaceAvail = parseInt(((menuWidth - navSlidesWidth)/menuItemWidth), 10);
418 var lastVisibleMenuItem = (this.firstVisibleMenuItem + spaceAvail) - 1; 419 if (calledFrom == "resize") { 420 this.firstVisibleMenuItem = (this.currentSlide - spaceAvail) + 1; 421 this.firstVisibleMenuItem = this.firstVisibleMenuItem > this.first ? this.firstVisibleMenuItem : this.first; 422 } else if (this.currentSlide < this.firstVisibleMenuItem || this.currentSlide > lastVisibleMenuItem) { 423 if (this.playDirection == "forwards") { 424 if (this.currentSlide == this.first) { 425 this.firstVisibleMenuItem = this.first; 426 } else { 427 this.firstVisibleMenuItem = (++this.firstVisibleMenuItem < this.last) ? this.firstVisibleMenuItem : this.first; 428 } 429 } else if (this.playDirection == "backwards") { 430 if (this.currentSlide == this.last) { 431 this.firstVisibleMenuItem = this.last - (spaceAvail - 1); 432 } else { 433 this.firstVisibleMenuItem = (--this.firstVisibleMenuItem >= this.first) ? this.firstVisibleMenuItem : this.last; 434 } 435 } 436 } 437 438 var last = this.firstVisibleMenuItem + spaceAvail; 439 this.menuItems.hide(); 440 for (var i = this.firstVisibleMenuItem; i < last; i++) { 441 rjQuery(this.menuItems[i]).show(); 442 } 443 } else { 444 $nextMenu.hide(); 445 $prevMenu.hide(); 446 this.menuItems.show(); 447 } 448 } 449 450}; 451 452 453 454WindowResizeResponder.register({ 455 "method": resizeSlideshowGalleryContents, 456 "when": "load" 457}); 458 459 460/* 461 * Run when everything has loaded, to start slideshow. 462 * Wait for the playSpeed increment before starting 463 * the slideshow to give time for the first slide to 464 * display. 465 * 466 */ 467rjQuery(window).load(function(event) { 468 rjQuery.each(slideshowGalleryObjects, function() { 469 var gallery = this; 470 window.setTimeout(function() { 471 gallery.xFade(); 472 }, gallery.playSpeed); 473 }); 474}); 475
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.