/** * MooFlow - Image gallery * * Dependencies: MooTools 1.2 * * @version 0.2.1 * * @license MIT-style license * @author Tobias Wetzel * @copyright Author * @docmentation http://outcut.de/MooFlow/Docmentation.html */ var MooFlow = new Class({ Implements: [Events, Options], options: { onStart: $empty, onClickView: $empty, onAutoPlay: $empty, onAutoStop: $empty, onRequest: $empty, onResized: $empty, onEmptyinit: $empty, reflection: 0.3, heightRatio: 0.7, height:355, offsetY: -12, startIndex: 0, interval: 4000, factor: 155, bgColor: '#000', bgImage: 'url(img/featured/feature_back.png)', bgTrans: 'url(img/featured/transparent.gif)', useCaption: false, useResize: false, useSlider: false, useWindowResize: false, useMouseWheel: false, useKeyInput: false, useViewer: false }, initialize: function(element, options){ this.MooFlow = element; this.setOptions(options); this.foc = 150; this.factor = this.options.factor; this.offY = this.options.offsetY; this.isFull = false; this.isAutoPlay = true; this.isLoading = false; this.inMotion = true; this.MooFlow.addClass('mf').setStyles({ 'overflow':'hidden', 'background-image':this.options.bgImage, 'background-repeat':'no-repeat', 'background-position':'center top', 'position':'relative', 'height':this.options.height, 'opacity':0 }); if(this.options.useWindowResize) window.addEvent('resize', this.update.bind(this, 'init')); if(this.options.useMouseWheel || this.options.useSlider) this.MooFlow.addEvent('mousewheel', this.wheelTo.bind(this)); if(this.options.useKeyInput) document.addEvent('keydown', this.keyTo.bind(this)); this.getElements(this.MooFlow); }, clearInit: function(){ this.fireEvent('emptyinit'); }, getElements: function(el){ this.master = {'images':[]}; var els = el.getChildren(); if(!els.length) {this.clearInit(); return;} $$(els).each(function(el){ var hash = $H(el.getElement('img').getProperties('src','title','alt','longdesc')); if(el.get('tag') == 'a') hash.combine(el.getProperties('href','rel','target')); this.master['images'].push(hash.getClean()); el.dispose(); }, this); this.clearMain(); }, clearMain: function(){ if(this.cap){this.cap.fade(0);} if(this.nav){ new Fx.Tween(this.nav, { 'onComplete': function(){ this.MooFlow.empty(); this.createAniObj(); }.bind(this) }).start('bottom', -50); } if(!this.nav && !this.cap){ this.MooFlow.empty(); this.createAniObj(); } }, getMooFlowElements: function(key){ var els = []; this.master.images.each(function(el){ els.push(el[key]); }); return els; }, createAniObj: function(){ this.aniFx = new Fx.Value({ 'transition': Fx.Transitions.Expo.easeOut, 'link': 'cancel', 'duration': 750, onMotion: this.process.bind(this), 'onStart': this.flowStart.bind(this), 'onComplete': this.flowComplete.bind(this) }); this.addLoader(); }, addLoader: function(){ this.MooFlow.store('height', this.MooFlow.getSize().y); this.loader = new Element('div',{'class':'loader'}).inject(this.MooFlow); new Fx.Tween(this.MooFlow, { 'duration': 800, 'onComplete': this.preloadImg.bind(this) }).start('opacity', 1); }, preloadImg: function(){ this.loadedImages = new Asset.images(this.getMooFlowElements('src'), { 'onComplete': this.loaded.bind(this), 'onProgress': this.createMooFlowElement.bind(this) }); }, createMooFlowElement: function(counter, i){ var obj = this.getCurrent(i); var img = this.loadedImages[i]; obj['width'] = img.width; obj['height'] = img.height; img.removeProperties('width','height'); obj['div'] = new Element('div').setStyles({ 'position':'absolute', 'display':'none', 'height': this.MooFlow.getSize().y }).inject(this.MooFlow); obj['con'] = new Element('div').inject(obj['div']); img.setStyles({'vertical-align':'bottom', 'width':'100%', 'height':'53%'}); img.addEvents({'click': this.clickTo.bind(this, i), 'dblclick': this.viewCallBack.bind(this, i)}); img.inject(obj['con']); new Element('div').reflect({ 'img': img, 'ref': this.options.reflection, 'height': obj.height, 'width': obj.width, 'color': this.options.bgColor }).setStyles({'width':'100%','height':'30%','background-image': this.options.bgTrans,'background-repeat':'repeat'}).inject(obj['con']); this.loader.set('text', (counter+1) + ' / ' + this.loadedImages.length); }, loaded: function(){ this.index = this.options.startIndex; this.iL = this.master.images.length-1; new Fx.Tween(this.loader, { 'duration': 800, 'onComplete': this.createUI.bind(this) }).start('opacity', 0); }, createUI: function(){ this.loader.dispose(); if(this.options.useCaption){ this.cap = new Element('div').addClass('caption').set('opacity',0).inject(this.MooFlow); } this.nav = new Element('div').addClass('mfNav').setStyle('bottom','-50px'); this.autoPlayCon = new Element('div').addClass('autoPlayCon'); this.sliderCon = new Element('div').addClass('sliderCon'); this.resizeCon = new Element('div').addClass('resizeCon'); if(this.options.useAutoPlay){ this.autoPlayCon.adopt( new Element('a',{'class':'stop','events': {'click':this.stop.bind(this)}}), new Element('a',{'class':'play','events': {'click':this.play.bind(this)}}) ); } if(this.options.useSlider){ this.sliPrev = new Element('a',{'class':'sliderNext','events': {'click':this.prev.bind(this)}}); this.sliNext = new Element('a',{'class':'sliderPrev','events': {'click':this.next.bind(this)}}); this.knob = new Element('div',{'class':'knob'}); this.knob.adopt(new Element('div',{'class':'knobleft'})); this.slider = new Element('div',{'class':'slider'}).adopt(this.knob); this.sliderCon.adopt(this.sliPrev,this.slider,this.sliNext); this.slider.store('parentWidth', this.sliderCon.getSize().x-this.sliPrev.getSize().x-this.sliNext.getSize().x); } if(this.options.useResize){ this.resizeCon.adopt(new Element('a',{'class':'resize','events': {'click':this.setScreen.bind(this)}})); } this.MooFlow.adopt(this.nav.adopt(this.autoPlayCon, this.sliderCon, this.resizeCon)); this.showUI(); }, showUI: function(){ if(this.cap) this.cap.fade(1); this.nav.tween('bottom', 20); this.fireEvent('start'); this.update(); this.play(); }, update: function(e){ if(e == 'init') return; this.oW = this.MooFlow.getSize().x; this.sz = this.oW * 0.5; if(this.options.useSlider){ this.slider.setStyle('width',this.slider.getParent().getSize().x-this.sliPrev.getSize().x-this.sliNext.getSize().x-1); this.knob.setStyle('width',(this.slider.getSize().x/this.iL)); this.sli = new SliderEx(this.slider, this.knob, {steps: this.iL}).set(this.index); this.sli.addEvent('onChange', this.glideTo.bind(this)); } this.glideTo(this.index); this.isLoading = false; }, setScreen: function(){ if(this.isFull = !this.isFull){ this.holder = new Element('div').inject(this.MooFlow,'after'); this.MooFlow.wraps(new Element('div').inject(document.body)); this.MooFlow.setStyles({'position':'absolute','z-index':'100','top':'0','left':'0','width':window.getSize().x,'height':window.getSize().y}); if(this.options.useWindowResize){ this._initResize = this.initResize.bind(this); window.addEvent('resize', this._initResize); } } else { this.MooFlow.wraps(this.holder); window.removeEvent('resize', this._initResize); delete this.holder, this._initResize; this.MooFlow.setStyles({'position':'relative','z-index':'','top':'','left':'','width':'','height':this.MooFlow.retrieve('height')}); this.slider.setStyle('width',this.slider.retrieve('parentWidth')); } this.fireEvent('resized', this.isFull); this.update(); }, initResize: function(){ this.MooFlow.setStyles({'width':window.getSize().x,'height':window.getSize().y}); this.update(); }, getCurrent: function(index){ return this.master.images[$chk(index) ? index : this.index]; }, loadJSON: function(url){ if(!url || this.isLoading) return; this.isLoading = true; new Request.JSON({ 'onComplete': function(data){ if($chk(data)){ this.master = data; this.clearMain(); this.fireEvent('request', data); } }.bind(this) }, this).get(url); }, loadHTML: function(url, filter){ if(!url || !filter || this.isLoading) return; this.isLoading = true; new Request.HTML({ 'onSuccess': function(tree, els, htm){ var result = new Element('div', {'html': htm}).getChildren(filter); this.getElements(result); this.fireEvent('request', result); }.bind(this) }, this).get(url); }, flowStart: function(){ this.inMotion = true; }, flowComplete: function(){ this.inMotion = true; }, viewCallBack: function(index){ if(this.index != index || this.inMotion) return; var el = $H(this.getCurrent()); var returnObj = {}; returnObj['coords'] = el.div.getElement('img').getCoordinates(); el.each(function(v, k){ if($type(v) == 'number' || $type(v) == 'string') returnObj[k] = v; }, this); this.fireEvent('clickView', returnObj); }, prev: function(){ if(this.index > 0) this.clickTo(this.index-1); }, next: function(){ if(this.index < this.iL) this.clickTo(this.index+1); }, stop: function(){ $clear(this.autoPlay); this.isAutoPlay = false; this.fireEvent('autoStop'); }, play: function(){ this.autoPlay = this.auto.periodical(this.options.interval, this); this.isAutoPlay = true; this.fireEvent('autoPlay'); }, auto: function(){ if(this.index < this.iL) this.next(); else if(this.index == this.iL) this.clickTo(0); }, keyTo: function(e){ switch (e.code){ case 37: e.stop(); this.prev(); break; case 39: e.stop(); this.next(); } }, wheelTo: function(e){ if(e.wheel > 0) this.prev(); if(e.wheel < 0) this.next(); e.stop().preventDefault(); }, clickTo: function(index){ if(this.index == index) return; //this.aniFx.cancel(); if(this.sli) this.sli.set(index); this.glideTo(index); }, glideTo: function(index){ this.index = index; this.aniFx.start(this.aniFx.get(), index*-this.foc); if(this.cap) this.cap.set('html', this.getCurrent().title); }, process: function(x){ var z,W,H,zI=this.iL,foc=this.foc,f=this.factor,sz=this.sz,oW=this.oW,offY=this.offY,div,elh,elw; this.master.images.each(function(el){ div = el.div.style; elw = el.width; elh = el.height; if(x>-foc*6 && x= elw * 0.5) {W = round(f / z * sz);} div.left = round(((x / z * sz) + sz) - (f * 0.5) / z * sz) + 'px'; div.top = round(oW * 0.4 - H) + offY + 'px'; } el.con.style.height = H*2 + 'px'; div.width = W + 'px'; div.zIndex = x < 0 ? zI++ : zI--; div.display = 'block'; } else { div.display = 'none'; } x += foc; }); } }); var SliderEx = new Class({ Extends: Slider, set: function(step){ this.step = Math.round(step); this.fireEvent('tick', this.toPosition(this.step)); return this; }, clickedElement: function(event){ var dir = this.range < 0 ? -1 : 1; var position = event.page[this.axis] - this.element.getPosition()[this.axis] - this.half; position = position.limit(-this.options.offset, this.full -this.options.offset); this.step = Math.round(this.min + dir * this.toStep(position)); this.checkStep(); this.fireEvent('tick', position); } }); Fx.Value = new Class({ Extends: Fx, compute: function(from, to, delta){ this.value = Fx.compute(from, to, delta); this.fireEvent('motion', this.value); return this.value; }, get: function(){ return this.value || 0; } }); Element.implement({ reflect: function(arg){ i = arg.img.clone(); if(Browser.Engine.trident){ i.style.filter = 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity=20, style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy='+100*arg.ref+')'; i.setStyles({'width':'100%', 'height':'100%'}); return new Element('div').adopt(i); } else { var can = new Element('canvas').setProperties({'width':arg.width, 'height':arg.height}); if(can.getContext){ var ctx = can.getContext("2d"); ctx.save(); ctx.translate(0,arg.height-1); ctx.scale(1,-1); ctx.drawImage(i, 0, 0, arg.width, arg.height); ctx.restore(); ctx.globalCompositeOperation = "destination-out"; ctx.fillStyle = arg.color; ctx.fillRect(0, arg.height*0.5, arg.width, arg.height); var gra = ctx.createLinearGradient(0, 0, 0, arg.height*arg.ref); gra.addColorStop(1, "rgba(255, 255, 255, 1.0)"); gra.addColorStop(0, "rgba(255, 255, 255, "+(1-arg.ref)+")"); ctx.fillStyle = gra; ctx.rect(0, 0, arg.width, arg.height); ctx.fill(); delete ctx, gra; } return can; } } }); window.addEvent('domready', function(){ $$('.MooFlowieze').each(function(mooflow){ new MooFlow(mooflow); }); });