1/** 2 * Slideshow - a slideshow <http://www.electricprism.com/aeron/slideshow/> and 3 * smoothslideshow <http://smoothslideshow.jondesign.net/> fusion. 4 * 5 * Copyright (c) 2007 Olmo Maldonado 6 * 7 * From version 3.0.3, fixes and enanchements from Djamil Legato 8 */ 9 10var Slideshow = new Class({ 11 12 version: '3.0.3', 13 14 options: { 15 captions: true, 16 showTitleCaption: true, 17 classes: ['prev', 'next', 'active'], 18 duration: [2000, 4000], 19 path: '/', 20 navigation: false, 21 pan: 100, 22 resize: true, 23 thumbnailre: [/\./, 't.'], 24 transition: Fx.Transitions.Sine.easeInOut, 25 type: 'fade', 26 zoom: 50, 27 loadingDiv: true, 28 removeDiv: true 29 }, 30 31 styles: { 32 caps: { 33 div: { 34 opacity: 0, 35 position: 'absolute', 36 width: '100%', 37 margin: 0, 38 left: 0, 39 bottom: 0, 40 height: 40, 41 background: '#333', 42 color: '#fff', 43 textIndent: 0 44 }, 45 46 h2: { 47 color: 'red', 48 padding: 0, 49 fontSize: '80%', 50 margin: 0, 51 margin: '2px 5px', 52 fontWeight: 'bold' 53 }, 54 55 p: { 56 padding: 0, 57 fontSize: '60%', 58 margin: '2px 5px', 59 color: '#eee' 60 } 61 } 62 }, 63 64 initialize: function(el, options) { 65 this.setOptions($merge({ 66 onClick: this.onClick.bind(this) 67 }, options)); 68 69 if(!this.options.images) return; 70 this.options.pan = this.mask(this.options.pan); 71 this.options.zoom = this.mask(this.options.zoom); 72 73 this.el = $(el).empty(); 74 75 this.caps = { 76 div: new Element('div', { 77 styles: this.styles.caps.div, 78 'class': 'captionDiv' 79 }), 80 h2: new Element('h2', { 81 styles: this.styles.caps.h2, 82 'class': 'captionTitle' 83 }), 84 p: new Element('p', { 85 styles: this.styles.caps.p, 86 'class': 'captionDescription' 87 }) 88 }; 89 90 this.fx = []; 91 92 var trash = new ImageLoader(this.el, this.options.images, { 93 loadingDiv: this.options.loadingDiv, 94 onComplete: this.start.bind(this), 95 path: this.options.path, 96 removeDiv: this.options.removeDiv 97 }); 98 }, 99 100 start: function() { 101 this.imgs = $A(arguments); 102 this.a = this.imgs[0].clone().set({ 103 styles: { 104 display: 'block', 105 position: 'absolute', 106 left: 0, 107 'top': 0, 108 zIndex: 1 109 } 110 }).injectInside(this.el); 111 112 var obj = this.a.getCoordinates(); 113 this.height = this.options.height || obj.height; 114 this.width = this.options.width || obj.width; 115 116 this.el.setStyles({ 117 display: 'block', 118 position: 'relative', 119 width: this.width 120 }); 121 122 this.el.empty(); 123 this.el.adopt((new Element('div', { 124 events: { 125 'click': this.onClick.bind(this) 126 }, 127 styles: { 128 display: 'block', 129 overflow: 'hidden', 130 position: 'relative', 131 width: this.width, 132 height: this.height 133 } 134 })).adopt(this.a)); 135 136 this.resize(this.a, obj); 137 this.b = this.a.clone().setStyle('opacity', 0).injectAfter(this.a); 138 139 this.timer = [0, 0]; 140 this.navigation(); 141 142 this.direction = 'left'; 143 this.curr = [0,0]; 144 145 $(document.body).adopt(new Element('div', { 146 id: 'hiddenDIV', 147 styles: { 148 visibility: 'hidden', 149 height: 0, 150 width: 0, 151 overflow: 'hidden', 152 opacity: 0 153 } 154 })); 155 this.loader = this.imgs[0]; 156 $('hiddenDIV').adopt(this.loader); 157 this.load(); 158 }, 159 160 load: function(fast) { 161 if ($time() > this.timer[0]) { 162 this.img = (this.curr[1] % 2) ? this.b : this.a; 163 this.img.setStyles({ 164 opacity: 0, 165 width: 'auto', 166 height: 'auto', 167 zIndex: this.curr[1] 168 }); 169 170 var url = this.options.images[this.curr[0]].url; 171 this.img.setStyle('cursor', (url != '#' && url != '') ? 'pointer' : 'default'); 172 173 this.img.setProperties({ 174 src: this.loader.src, 175 title: this.loader.title, 176 alt: this.loader.alt 177 }); 178 179 this.resize(this.img, this.loader); 180 181 if(fast){ 182 this.img.setStyles({ 183 top: 0, 184 left: 0, 185 opacity: 1 186 }); 187 188 this.captions(); 189 this.loaded(); 190 return; 191 } 192 193 this.captions(); 194 this[this.options.type.test(/push|wipe/) ? 'swipe' : 'kens'](); 195 this.loaded(); 196 } else { 197 this.timeout = this.load.delay(100, this); 198 } 199 }, 200 201 loaded: function() { 202 if(this.ul) { 203 this.ul.getElements('a[name]').each(function(a, i) { 204 a[(i === this.curr[0] ? 'add' : 'remove') + 'Class'](this.options.classes[2]); 205 }, this); 206 } 207 208 this.direction = 'left'; 209 this.curr[0] = (this.curr[0] + 1) % this.imgs.length; 210 this.curr[1]++; 211 212 this.timer[0] = $time() + this.options.duration[1] + (this.options.type.test(/fade|push|wipe/) ? this.options.duration[0] : 0); 213 this.timer[1] = $time() + this.options.duration[0]; 214 215 this.loader = this.imgs[this.curr[0]]; 216 $('hiddenDIV').empty().adopt(this.loader); 217 this.load(); 218 }, 219 220 kens: function() { 221 this.img.setStyles({ 222 bottom: 'auto', 223 right: 'auto', 224 left: 'auto', 225 top: 'auto' 226 }); 227 228 var arr = ['left top', 'right top', 'left bottom', 'right bottom'].getRandom().split(' '); 229 arr.each(function(p) { 230 this.img.setStyle(p, 0); 231 }, this); 232 233 var zoom = this.options.type.test(/zoom|combo/) ? this.zoom() : {}; 234 var pan = this.options.type.test(/pan|combo/) ? this.pan(arr) : {}; 235 236 this.fx.push(this.img.effect('opacity', {duration: this.options.duration[0]}).start(1)); 237 this.fx.push(this.img.effects({duration: this.options.duration[0] + this.options.duration[1]}).start($merge(zoom, pan))); 238 }, 239 240 zoom: function() { 241 var n = Math.max(this.width / this.loader.width, this.height / this.loader.height); 242 var z = (this.options.zoom === 'rand') ? Math.random() + 1 : (this.options.zoom.toInt() / 100.0) + 1; 243 244 var eh = Math.ceil(this.loader.height * n); 245 var ew = Math.ceil(this.loader.width * n); 246 247 var sh = (eh * z).toInt(); 248 var sw = (ew * z).toInt(); 249 250 return {height: [sh, eh], width: [sw, ew]}; 251 }, 252 253 pan: function(arr) { 254 var ex = this.width - this.img.width, ey = this.height - this.img.height; 255 var p = this.options.pan === 'rand' ? Math.random() : Math.abs((this.options.pan.toInt() / 100) - 1); 256 var sx = (ex * p).toInt(), sy = (ey * p).toInt(); 257 258 var x = this.width / this.loader.width > this.height / this.loader.height; 259 var obj = {}; 260 obj[arr[x ? 1 : 0]] = x ? [sy, ey] : [sx, ex]; 261 return obj;
262 }, 263 264 swipe: function() { 265 var arr, p0 = {}, p1 = {}, x; 266 this.img.setStyles({ 267 left: 'auto', 268 right: 'auto', 269 opacity: 1 270 }).setStyle(this.direction, this.width); 271 272 if(this.options.type === 'wipe') { 273 this.fx.push(this.img.effect(this.direction, { 274 duration: this.options.duration[0], 275 transition: this.options.transition 276 }).start(0)); 277 } else { 278 arr = [this.img, this.curr[1] % 2 ? this.a : this.b]; 279 p0[this.direction] = [this.width, 0]; 280 p1[this.direction] = [0, -this.width]; 281 282 if(arr[1].getStyle(this.direction) === 'auto') { 283 x = this.width - arr[1].getStyle('width').toInt(); 284 285 arr[1].setStyle(this.direction, x); 286 arr[1].setStyle(this.direction === 'left' ? 'right' : 'left', 'auto'); 287 288 p1[this.direction][0] = x; 289 } 290 291 this.fx.push(new Fx.Elements(arr, { 292 duration: this.options.duration[0], 293 transition: this.options.transition 294 }).start({ 295 '0': p0, 296 '1': p1 297 })); 298 } 299 }, 300 301 captions: function(img) { 302 img = img || this.img; 303 if(!this.options.captions || (!img.title && !img.alt)) return; 304 305 this.el.getFirst().adopt(this.caps.div.adopt(this.caps.h2, this.caps.p)); 306 307 (function () { 308 if (this.options.showTitleCaption) this.caps.h2.setHTML(img.title); 309 this.caps.p.setHTML(img.alt); 310 this.caps.div.setStyle('zIndex', img.getStyle('zIndex')*2 || 10); 311 312 this.capsHeight = this.capsHeight || this.options.captionHeight || this.caps.div.offsetHeight; 313 314 var fx = this.caps.div.effects().set({'height': 0}).start({ 315 opacity: 0.7, 316 height: this.capsHeight 317 }); 318 319 (function(){ 320 fx.start({ 321 opacity: 0, 322 height: 0 323 }); 324 }).delay(1.00*(this.options.duration[1] - this.options.duration[0])); 325 }).delay(0.75*(this.options.duration[0]), this); 326 }, 327 328 navigation: function() { 329 if(!this.options.navigation) return; 330 var i, j, atemp; 331 var fast = this.options.navigation.test(/fast/) ; 332 this.ul = new Element('ul'); 333 var li = new Element('li'), a = new Element('a'); 334 335 if (this.options.navigation.test(/arrows/)) { 336 this.ul.adopt(li.clone() 337 .adopt(a.clone() 338 .addClass(this.options.classes[0]) 339 .addEvent('click', function() { 340 if (fast || $time() > this.timer[1]) { 341 $clear(this.timeout); 342 343 // Clear the FX array only for fast navigation since this stops combo effects 344 if(fast) { 345 this.fx.each(function(fx) { 346 fx.time = 0; 347 fx.options.duration = 0; 348 fx.stop(true); 349 });
350 } 351 352 this.direction = 'right'; 353 this.curr[0] = (this.curr[0] < 2) ? this.imgs.length - (2 - this.curr[0]) : this.curr[0] - 2; 354 this.timer = [0]; 355 356 this.loader = this.imgs[this.curr[0]]; 357 this.load(fast); 358 } 359 }.bind(this)) 360 ) 361 ); 362 } 363 364 if (this.options.navigation.test(/arrows\+|thumbnails/)) { 365 for (i = 0, j = this.imgs.length; i < j; i++) { 366 atemp = a.clone().setProperty('name', i); 367 if (this.options.navigation.test(/thumbnails/)) atemp.setStyle('background-image', 'url(' + this.imgs[i].src + ')'); 368 if(i === 0) a.className = this.options.classes[2]; 369 370 atemp.onclick = function(i) { 371 if(fast || $time() > this.timer[1]) { 372 $clear(this.timeout); 373 374 if (fast) { 375 this.fx.each(function(fx) { 376 fx.time = 0; 377 fx.options.duration = 0; 378 fx.stop(true); 379 }); 380 } 381 382 this.direction = (i < this.curr[0] || this.curr[0] === 0) ? 'right' : 'left'; 383 this.curr[0] = i; 384 this.timer = [0]; 385 386 this.loader = this.imgs[this.curr[0]]; 387 this.load(fast); 388 } 389 }.pass(i, this); 390 391 this.ul.adopt(li.clone().adopt(atemp)); 392 } 393 } 394 395 if (this.options.navigation.test(/arrows/)) { 396 this.ul.adopt(li.clone() 397 .adopt(a.clone() 398 .addClass(this.options.classes[1]) 399 .addEvent('click', function() { 400 if (fast || $time() > this.timer[1]) { 401 $clear(this.timeout); 402 403 // Clear the FX array only for fast navigation since this stops combo effects 404 if (fast) { 405 this.fx.each(function(fx) { 406 fx.time = 0; 407 fx.options.duration = 0; 408 fx.stop(true); 409 });
410 } 411 412 this.timer = [0]; 413 414 this.load(fast); 415 } 416 }.bind(this)) 417 ) 418 ); 419 } 420 421 this.ul.injectInside(this.el); 422 }, 423 424 onClick: function(e) { 425 e = new Event(e).stop(); 426 var cur = this.curr[1] % this.imgs.length; 427 var index = this.curr[1] == 0 ? 1 : cur == 0 ? this.imgs.length : cur; 428 var url = this.options.images[index - 1].url; 429 if(url == '#' || url == '') return; 430 window.location.href = url; 431 }, 432 433 mask: function(val, set, lower, higher) { 434 if(val != 'rand') { 435 val = val.toInt(); 436 val = isNaN(val) || val < lower || val > higher ? set : val; 437 } 438 439 return val; 440 }, 441 442 resize: function(obj, to) { 443 var n; 444 if(this.options.resize) { 445 n = Math.max(this.width / to.width, this.height / to.height); 446 obj.setStyles({ 447 height: Math.ceil(to.height*n), 448 width: Math.ceil(to.width*n) 449 }); 450 } 451 } 452}); 453Slideshow.implement(new Options); 454 455/** 456 * ImageLoader, Image preloader with progress reporting, with small 457 * changes by Olmo Maldonado, <http://olmo-maldonado.com/> (denoted by 458 * // at the end of the line) 459 * 460 * 461 * @author tomocchino, <http://www.tomocchino.com/> 462 * 463 */ 464var ImageLoader = new Class({ 465 466 version:'.5-olmo-ver', 467 468 options: { 469 loadingDiv : false, 470 loadingPrefix : 'loading images: ', 471 loadingSuffix : '', 472 path : '', 473 removeDiv : true 474 }, 475 476 initialize: function(container, sources, options){ 477 this.setOptions(options); 478 this.loadingDiv = (this.options.loadingDiv) ? $(container) : false; 479 this.images = []; 480 this.index = 0; 481 this.total = sources.length; 482 483 if(this.loadingDiv) { 484 this.loadingText = new Element('div').injectInside(this.loadingDiv); 485 this.progressBar = new Element('div', { 486 styles: { 487 width: 100, 488 padding: 1, 489 margin: '5px auto', 490 textAlign: 'left', 491 overflow: 'hidden', 492 border: 'solid 1px #333' 493 } 494 }).adopt(new Element('div', { 495 styles: { 496 width: '0%', 497 height: 10, 498 backgroundColor: '#333' 499 } 500 })).injectInside(this.loadingDiv); 501 } 502 503 this.loadImages.delay(200, this, [sources]); 504 }, 505 506 reset: function() { 507 this.index = 0; 508 if(this.loadingDiv) { 509 this.progressBar.getFirst().setStyle('width', '0%'); 510 this.loadingText.setHTML(this.options.loadingPrefix); 511 } 512 }, 513 514 loadImages: function(sources) { 515 var self = this; 516 this.reset(); 517 this.images = []; 518 this.sources = sources; 519 520 this.timer = setInterval(this.loadProgress.bind(this), 100); 521 for(var i = 0, j = sources.length; i < j; i++) { 522 this.images[i] = new Asset.image((this.sources[i].path || this.options.path) + this.sources[i].file, { 523 title: self.sources[i].title, 524 alt: self.sources[i].desc, 525 'onload' : function(){ self.index++; }, 526 'onerror' : function(){ self.index++; self.images.splice(i,1); }, 527 'onabort' : function(){ self.index++; self.images.splice(i,1); } 528 }); 529 } 530 }, 531 532 loadProgress: function() { 533 if(this.loadingDiv) { 534 this.loadingText.setHTML(this.options.loadingPrefix + this.index + '/' + this.total + this.options.loadingSuffix); 535 this.progressBar.getFirst().setStyle('width', (!this.total ? 0 : this.index.toInt()*100 / this.total) + '%'); 536 } 537 538 if(this.index >= this.total) { 539 this.loadComplete(); 540 } 541 }, 542 543 loadComplete: function(){ 544 $clear(this.timer); 545 if(this.loadingDiv) { 546 this.loadingText.setHTML('Loading Complete'); 547 548 if(this.options.removeDiv) { 549 this.loadingText.empty().remove(); 550 this.progressBar.empty().remove(); 551 } 552 } 553 this.fireEvent('onComplete', this.images); 554 }, 555 556 cancel: function(){ 557 $clear(this.timer); 558 } 559 560}); 561 562ImageLoader.implement(new Events, new Options);
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.