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