app/assets/javascripts/ext/src/ext-core/examples/carousel/carousel.js
/*!
* Ext JS Library 3.3.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');
}
}
}
});