X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/2e847cf21b8ab9d15fa167b315ca5b2fa92638fc..6a7e4474cba9d8be4b2ec445e10f1691f7277c50:/src/ext-core/examples/carousel/carousel.js diff --git a/src/ext-core/examples/carousel/carousel.js b/src/ext-core/examples/carousel/carousel.js new file mode 100644 index 00000000..fff6e4fe --- /dev/null +++ b/src/ext-core/examples/carousel/carousel.js @@ -0,0 +1,333 @@ +/*! + * Ext JS Library 3.2.0 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +Ext.ns('Ext.ux'); + +Ext.ux.Carousel = Ext.extend(Ext.util.Observable, { + interval: 3, + transitionDuration: 1, + transitionType: 'carousel', + transitionEasing: 'easeOut', + itemSelector: 'img', + activeSlide: 0, + autoPlay: false, + showPlayButton: false, + pauseOnNavigate: false, + wrap: false, + freezeOnHover: false, + navigationOnHover: false, + hideNavigation: false, + width: null, + height: null, + + constructor: function(elId, config) { + config = config || {}; + Ext.apply(this, config); + + Ext.ux.Carousel.superclass.constructor.call(this, config); + + this.addEvents( + 'beforeprev', + 'prev', + 'beforenext', + 'next', + 'change', + 'play', + 'pause', + 'freeze', + 'unfreeze' + ); + + this.el = Ext.get(elId); + this.slides = this.els = []; + + if(this.autoPlay || this.showPlayButton) { + this.wrap = true; + }; + + if(this.autoPlay && typeof config.showPlayButton === 'undefined') { + this.showPlayButton = true; + } + + this.initMarkup(); + this.initEvents(); + + if(this.carouselSize > 0) { + this.refresh(); + } + }, + + initMarkup: function() { + var dh = Ext.DomHelper; + + this.carouselSize = 0; + var items = this.el.select(this.itemSelector); + this.els.container = dh.append(this.el, {cls: 'ux-carousel-container'}, true); + this.els.slidesWrap = dh.append(this.els.container, {cls: 'ux-carousel-slides-wrap'}, true); + + this.els.navigation = dh.append(this.els.container, {cls: 'ux-carousel-nav'}, true).hide(); + this.els.caption = dh.append(this.els.navigation, {tag: 'h2', cls: 'ux-carousel-caption'}, true); + this.els.navNext = dh.append(this.els.navigation, {tag: 'a', href: '#', cls: 'ux-carousel-nav-next'}, true); + if(this.showPlayButton) { + this.els.navPlay = dh.append(this.els.navigation, {tag: 'a', href: '#', cls: 'ux-carousel-nav-play'}, true) + } + this.els.navPrev = dh.append(this.els.navigation, {tag: 'a', href: '#', cls: 'ux-carousel-nav-prev'}, true); + + // set the dimensions of the container + this.slideWidth = this.width || this.el.getWidth(true); + this.slideHeight = this.height || this.el.getHeight(true); + this.els.container.setStyle({ + width: this.slideWidth + 'px', + height: this.slideHeight + 'px' + }); + + this.els.caption.setWidth((this.slideWidth - (this.els.navNext.getWidth()*2) - (this.showPlayButton ? this.els.navPlay.getWidth() : 0) - 20) + 'px') + + items.appendTo(this.els.slidesWrap).each(function(item) { + item = item.wrap({cls: 'ux-carousel-slide'}); + this.slides.push(item); + item.setWidth(this.slideWidth + 'px').setHeight(this.slideHeight + 'px'); + }, this); + this.carouselSize = this.slides.length; + if(this.navigationOnHover) { + this.els.navigation.setStyle('top', (-1*this.els.navigation.getHeight()) + 'px'); + } + this.el.clip(); + }, + + initEvents: function() { + this.els.navPrev.on('click', function(ev) { + ev.preventDefault(); + var target = ev.getTarget(); + target.blur(); + if(Ext.fly(target).hasClass('ux-carousel-nav-disabled')) return; + this.prev(); + }, this); + + this.els.navNext.on('click', function(ev) { + ev.preventDefault(); + var target = ev.getTarget(); + target.blur(); + if(Ext.fly(target).hasClass('ux-carousel-nav-disabled')) return; + this.next(); + }, this); + + if(this.showPlayButton) { + this.els.navPlay.on('click', function(ev){ + ev.preventDefault(); + ev.getTarget().blur(); + if(this.playing) { + this.pause(); + } + else { + this.play(); + } + }, this); + }; + + if(this.freezeOnHover) { + this.els.container.on('mouseenter', function(){ + if(this.playing) { + this.fireEvent('freeze', this.slides[this.activeSlide]); + Ext.TaskMgr.stop(this.playTask); + } + }, this); + this.els.container.on('mouseleave', function(){ + if(this.playing) { + this.fireEvent('unfreeze', this.slides[this.activeSlide]); + Ext.TaskMgr.start(this.playTask); + } + }, this, {buffer: (this.interval/2)*1000}); + }; + + if(this.navigationOnHover) { + this.els.container.on('mouseenter', function(){ + if(!this.navigationShown) { + this.navigationShown = true; + this.els.navigation.stopFx(false).shift({ + y: this.els.container.getY(), + duration: this.transitionDuration + }) + } + }, this); + + this.els.container.on('mouseleave', function(){ + if(this.navigationShown) { + this.navigationShown = false; + this.els.navigation.stopFx(false).shift({ + y: this.els.navigation.getHeight() - this.els.container.getY(), + duration: this.transitionDuration + }) + } + }, this); + } + + if(this.interval && this.autoPlay) { + this.play(); + }; + }, + + prev: function() { + if (this.fireEvent('beforeprev') === false) { + return; + } + if(this.pauseOnNavigate) { + this.pause(); + } + this.setSlide(this.activeSlide - 1); + + this.fireEvent('prev', this.activeSlide); + return this; + }, + + next: function() { + if(this.fireEvent('beforenext') === false) { + return; + } + if(this.pauseOnNavigate) { + this.pause(); + } + this.setSlide(this.activeSlide + 1); + + this.fireEvent('next', this.activeSlide); + return this; + }, + + play: function() { + if(!this.playing) { + this.playTask = this.playTask || { + run: function() { + this.playing = true; + this.setSlide(this.activeSlide+1); + }, + interval: this.interval*1000, + scope: this + }; + + this.playTaskBuffer = this.playTaskBuffer || new Ext.util.DelayedTask(function() { + Ext.TaskMgr.start(this.playTask); + }, this); + + this.playTaskBuffer.delay(this.interval*1000); + this.playing = true; + if(this.showPlayButton) { + this.els.navPlay.addClass('ux-carousel-playing'); + } + this.fireEvent('play'); + } + return this; + }, + + pause: function() { + if(this.playing) { + Ext.TaskMgr.stop(this.playTask); + this.playTaskBuffer.cancel(); + this.playing = false; + if(this.showPlayButton) { + this.els.navPlay.removeClass('ux-carousel-playing'); + } + this.fireEvent('pause'); + } + return this; + }, + + clear: function() { + this.els.slidesWrap.update(''); + this.slides = []; + this.carouselSize = 0; + this.pause(); + return this; + }, + + add: function(el, refresh) { + var item = Ext.fly(el).appendTo(this.els.slidesWrap).wrap({cls: 'ux-carousel-slide'}); + item.setWidth(this.slideWidth + 'px').setHeight(this.slideHeight + 'px'); + this.slides.push(item); + if(refresh) { + this.refresh(); + } + return this; + }, + + refresh: function() { + this.carouselSize = this.slides.length; + this.els.slidesWrap.setWidth((this.slideWidth * this.carouselSize) + 'px'); + if(this.carouselSize > 0) { + if(!this.hideNavigation) this.els.navigation.show(); + this.activeSlide = 0; + this.setSlide(0, true); + } + return this; + }, + + setSlide: function(index, initial) { + if(!this.wrap && !this.slides[index]) { + return; + } + else if(this.wrap) { + if(index < 0) { + index = this.carouselSize-1; + } + else if(index > this.carouselSize-1) { + index = 0; + } + } + if(!this.slides[index]) { + return; + } + + this.els.caption.update(this.slides[index].child(':first-child', true).title || ''); + var offset = index * this.slideWidth; + if (!initial) { + switch (this.transitionType) { + case 'fade': + this.slides[index].setOpacity(0); + this.slides[this.activeSlide].stopFx(false).fadeOut({ + duration: this.transitionDuration / 2, + callback: function(){ + this.els.slidesWrap.setStyle('left', (-1 * offset) + 'px'); + this.slides[this.activeSlide].setOpacity(1); + this.slides[index].fadeIn({ + duration: this.transitionDuration / 2 + }); + }, + scope: this + }) + break; + + default: + var xNew = (-1 * offset) + this.els.container.getX(); + this.els.slidesWrap.stopFx(false); + this.els.slidesWrap.shift({ + duration: this.transitionDuration, + x: xNew, + easing: this.transitionEasing + }); + break; + } + } + else { + this.els.slidesWrap.setStyle('left', '0'); + } + + this.activeSlide = index; + this.updateNav(); + this.fireEvent('change', this.slides[index], index); + }, + + updateNav: function() { + this.els.navPrev.removeClass('ux-carousel-nav-disabled'); + this.els.navNext.removeClass('ux-carousel-nav-disabled'); + if(!this.wrap) { + if(this.activeSlide === 0) { + this.els.navPrev.addClass('ux-carousel-nav-disabled'); + } + if(this.activeSlide === this.carouselSize-1) { + this.els.navNext.addClass('ux-carousel-nav-disabled'); + } + } + } +}); \ No newline at end of file