var Floom = new Class({ Implements: [Events, Options], options: { slides: [], prefix: 'floom_', amount: 24, animation: 60, interval: 8000, axis: 'vertical', progressbar: true, captions: true, captionsFxOut: $empty, captionsFxIn: $empty, sliceFxIn: {top: 20}, onSlideChange: $empty, onPreload: $empty }, initialize: function(wrapper, slides, options) { this.setOptions(options); this.options.slides = slides; wrapper = $(wrapper); new Element("div").wraps(wrapper).adopt(new Element("div").setStyle("height", "1em")); new Element("div").wraps(wrapper); this.wrapper = { el: wrapper, width: wrapper.getSize().x, height: wrapper.getSize().y }; this.slices = { els: [], width: (this.options.axis == 'vertical' ? this.wrapper.width / this.options.amount : this.wrapper.width).toInt(), height: (this.options.axis == 'vertical' ? this.wrapper.height : this.wrapper.height / this.options.amount).toInt() }; this.current = { slide: -1, overlay: 0, counter: 0 }; this.preloadImgs = []; this.container = new Element('div', { 'class': this.options.prefix + 'container', 'styles': { 'height': this.wrapper.height, 'width': this.wrapper.width } }).adopt(this.info = new Element("div").addClass(this.options.prefix + "info").hide()).inject(this.wrapper.el, "bottom"); this.info.setStyle("width", this.wrapper.width - (this.info.getStyle("padding").toInt() * 2)); if(this.options.progressbar) { this.progressbar = new Element('div', { 'class': this.options.prefix + 'progressbar', 'morph': { 'duration': this.options.interval - (this.options.animation * this.options.amount), 'transition': 'linear' } }); this.progressbar.inject(this.wrapper.el); } if(this.options.captions) { this.wrapper.el.grab(this.captions = new Element('div', { 'class': this.options.prefix + 'caption', 'html': 'caption', 'styles': { 'opacity': 0 } }), "top"); } this.options.slides.each(function(o) { this.preloadImgs.push(o.image); }, this); var preloadbar, preloadprogress = new Element("div", {"class": this.options.prefix + "preload"}).grab(preloadbar = new Element("div")).inject(wrapper, "top"); new Asset.images(this.preloadImgs, { onProgress: function(i) { preloadbar.setStyle("width", ((i + 1) * preloadprogress.getStyle('width').toInt()) / this.preloadImgs.length).set("text", i + 1 + " of " + this.preloadImgs.length); }.bind(this), onComplete: function() { preloadprogress.set("tween", { onComplete: function() { preloadprogress.dispose(); this.animateBlinds().periodical(this.options.interval, this); this.fireEvent("onPreload", this.options.slides[this.current.slide]); }.bind(this) }).fade("out"); }.bind(this) }); }, horizontal: function() { return { 'background-position': '0 -' + (this.slices.height * this.current.counter) + 'px' }; }, vertical: function() { return { 'background-position': '-' + (this.slices.width * this.current.counter) + 'px 0' }; }, createBlinds: function(idx){ this.current.counter = idx; this.slices.els[idx] = new Element('div', { 'class': this.options.prefix + 'slice ' + this.options.prefix + this.options.axis, 'tween': { 'duration': this.options.animation * 4 }, 'styles': $merge({ 'opacity': 0, 'width': this.slices.width, 'height': this.slices.height, 'background-image': 'url(' + this.options.slides[this.current.slide].image + ')' }, this[this.options.axis]()) }).inject(this.container); this.slices.els[idx].morph($merge({ 'opacity': 1 }, this.options.sliceFxIn)); if (idx == this.options.amount - 1) this.step.delay(this.options.animation, this); }, animateBlinds: function(){ this.current.slide++; if(this.current.slide > this.options.slides.length - 1) this.current.slide = 0; for(var idx = 0; idx < this.options.amount; idx++) this.createBlinds.delay(this.options.animation * idx, this, idx); this.info.fade("out"); if(this.options.progressbar) this.progressbar.fade('out'); if(this.options.captions) { this.captions.morph($merge({ 'opacity': 0 }, this.options.captionsFxOut)); } return this.animateBlinds; }, step: function(){ this.container.set('styles', { 'cursor': 'pointer', 'background-image': 'url(' + this.options.slides[this.current.slide].image + ')' }).addEvent("click", function() { window.location.href = this.options.slides[this.current.slide].resource; }.bind(this)); this.slices.els.each(function(slice){ slice.destroy(); }); if (this.options.progressbar) { this.progressbar.morph({ 'width': [0, this.container.getSize().x - (this.progressbar.getStyles('margin-left')['margin-left'].toInt() * 2)] }); this.progressbar.fade('in'); } if(this.options.captions) { this.info.set("text", this.options.slides[this.current.slide].info).show().fade("in"); this.captions.set("text", this.options.slides[this.current.slide].caption); this.captions.morph($merge({ 'opacity': 1 }, this.options.captionsFxIn)); } this.info.set("text", this.options.slides[this.current.slide].info).fade("in"); this.fireEvent('onSlideChange', this.options.slides[this.current.slide]); } }); Element.implement({ floom: function(slides, options) { return new Floom(this, slides, options); } }); Element.Properties.activated = { get: function() { return this.activated; }, set: function(value) { this.activated = !!value; this.setAttribute('activated', !!value); } }; Array.implement({ shuffle : function() { for (var i = 0; i < this.length; i++) { var j = i; while (j == i) { j = Math.floor(Math.random() * this.length); } var contents = this[i]; this[i] = this[j]; this[j] = contents; } return this; } }); var MatrixTransitions = new Class({ Implements : [Options], keys : [], elements : [], current : [], boxes : [], stop : false, rows : 0, columns : 0, changed : { fade : false, duration : false }, options : { autoStart : true, width : 20, height : 20, duration : 1000, delay : 40, // also know as fps images : [], wait : 10000, fade : false, index : 0, gobble : 'random', sweep : [ 'random', 'random'], blinds : 'random', effect : 'random', disolve : 'random' }, initialize : function(el,options){ this.container = $(el); this.setOptions(options); new Asset.images(this.options.images); this.container.setStyle('background', 'url('+this.options.images[this.options.index]+')'); var size = this.container.getSize(); this.rows = Math.ceil(size.y / this.options.height); this.columns = Math.ceil(size.x / this.options.width); this.index = this.options.index + 1; this.fade = this.changed.fade = this.options.fade; this.changed.duration = this.options.duration; var opacity = (this.fade) ? 0 : 1; var display = (this.fade) ? 'block' : 'none'; var idx = 0; (this.rows).times(function(row){ this.boxes[row] = []; (this.columns).times(function(col){ this.boxes[row][col] = idx; this.elements.push(new Element('div',{ 'activated' : false, 'styles' : { 'position' : 'absolute', 'overflow' : 'hidden', 'top' : this.options.height * row, 'left' : this.options.width * col, 'width' : this.options.width, 'height' : this.options.height, 'background-image' : 'url('+this.options.images[this.index]+')', 'background-position' : '-'+(this.options.width * col)+'px -'+(this.options.height * row)+'px', 'padding' : '0px 0px 0px 0px', 'margin' : '0px 0px 0px 0px', 'opacity' : opacity, 'display' : display } }).set('morph',{ duration : this.options.duration }).inject(this.container)); this.keys.push(idx); idx++; },this); },this); if(this.options.autoStart) this.start.delay(this.options.wait,this); }, start : function(){ this.stop = false; if(this.options.effect == 'random') var effect = ['disolve','sweep','blinds','gobble'][Math.floor(Math.random()*4)]; else effect = this.options.effect; switch(effect){ case 'disolve' : this.current = $A(this.keys).shuffle(); var disolveCount = (this.options.disolve == 'random') ? [3,5,7,10][Math.floor(Math.random()*4)] : this.options.disolve; this.intervalID = this.disolve.periodical(this.options.delay,this,disolveCount); break; case 'sweep' : var sweep = $A(this.options.sweep); if(sweep[0] == 'random') sweep[0] = Math.floor(Math.random()*this.rows); if(sweep[1] == 'random') sweep[1] = Math.floor(Math.random()*this.columns); this.totalTiles = this.rows * this.columns; this.sweepCount = 0; this.sweep(sweep[0],sweep[1]); break; case 'blinds' : this.blindState = { t : 0, l : 0, r: this.columns-1, b : this.rows-1 }; if(this.options.blinds == 'random') dir = ['l','r','t','b'][Math.floor(Math.random()*4)]; else dir = this.options.blinds; this.blinds(dir); break; case 'gobble' : if(this.options.gobble == 'random') size = [2,4][Math.floor(Math.random()*2)]; else size = this.options.gobble; this.gobble('+',0,0,size); break; } }, stop : function(){ this.stop = true; }, finished : function(){ this.container.setStyle('background', 'url('+this.options.images[this.index]+')'); this.index = (this.index+1 < this.options.images.length) ? this.index+1 : 0; if(this.fade != this.changed.fade) this.fade = this.changed.fade; var opacity = (this.fade) ? 0 : 1; var display = (this.fade) ? 'block' : 'none'; this.elements.each(function(el){ el.set({ 'activated' : false, 'styles' : { 'opacity' : opacity, 'display' : display, 'background-image' : 'url('+this.options.images[this.index]+')' } }); if(this.options.duration != this.changed.duration) el.set('morph',{ duration : this.changed.duration }); },this); if(this.options.duration != this.changed.duration) this.options.duration = this.changed.duration; if(!this.stop) this.start.delay(this.options.wait,this); }, setFade : function(value){ if(this.fade != value) { this.changed.fade = value; } }, setDuration : function(value){ if(this.options.duration != value) this.changed.duration = value; }, disolve : function(disolveCount){ var len = this.current.length; if(len == 0){ $clear(this.intervalID); this.finished.delay(this.options.duration+100,this); return false; } var cnt = (len >= disolveCount) ? disolveCount : len; for(i = 1; i<= cnt; i++){ var idx = this.current.shift(); var el = this.elements[idx]; if(this.fade) el.morph({ 'opacity' : 1 }); else el.setStyle('display', 'block'); } }, sweep : function(row,col){ var el = this.elements[ this.boxes[row][col] ]; if( el.get('activated')) return false; el.set('activated', true); if(this.fade) el.morph({ 'opacity' : 1 }); else el.setStyle('display', 'block'); this.sweepCount += 1; [{ r : row-1 , c : col }, { r : row , c : col-1 }, { r : row , c : col+1 }, { r : row+1 , c : col }].each(function(sibling){ if( sibling.r < 0 || sibling.r >= this.rows || sibling.c < 0 || sibling.c >= this.columns) return false; if(this.elements[this.boxes[sibling.r][sibling.c]].get('activated') != true) this.sweep.delay(this.options.delay,this,[sibling.r, sibling.c]); },this); if( this.sweepCount >= this.totalTiles ) this.finished.delay(this.options.duration+100,this); }, blinds : function(dir){ if(dir == 't' || dir == 'b'){ for(i = this.blindState.l; i <= this.blindState.r; i++ ){ var el = this.elements[ this.boxes[this.blindState[dir]][i] ]; if(this.fade) el.morph({ 'opacity' : 1 }); else el.setStyle('display', 'block'); } if(dir == 't') this.blindState.t++; else this.blindState.b--; } if(dir == 'l' || dir == 'r'){ for(i = this.blindState.t; i <= this.blindState.b; i++){ var el =this.elements[ this.boxes[i][this.blindState[dir]] ]; if(this.fade) el.morph({ 'opacity' : 1 }); else el.setStyle('display', 'block'); } if(dir == 'l') this.blindState.l++; else this.blindState.r--; } if( ((this.blindState.b - this.blindState.t) >= 0) && ((this.blindState.r - this.blindState.l) >= 0) ) this.blinds.delay(this.options.delay,this,dir); else this.finished.delay(this.options.duration+100,this); }, gobble : function(sign,row,col,size){ for(r = 0; r < size; r++){ for(c = 0; c < size; c++){ if( ( (row+r) < this.rows) && ( (col+c) < this.columns) ){ var el = this.elements[ this.boxes[row+r][col+c] ]; if(this.fade) el.morph({ 'opacity' : 1 }); else el.setStyle('display', 'block'); } } } if( sign == '+' ){ col += size; if ( col >= this.columns ){ col -= size; sign = '-'; row += size; } } else { col -= size; if( col < 0 ){ col += size; sign = '+'; row += size; } } if ( row < this.rows ) this.gobble.delay(this.options.delay,this,[sign,row,col,size]); else this.finished.delay(this.options.duration+100,this); } });