/*!
* Ext JS Library 3.3.1
* Copyright(c) 2006-2010 Sencha Inc.
* [email protected]
* http://www.sencha.com/license
*/
Ext.ns('Ext.ux');
Ext.ux.Lightbox = (function(){
var els = {},
images = [],
activeImage,
initialized = false,
selectors = [];
return {
overlayOpacity: 0.85,
animate: true,
resizeSpeed: 8,
borderSize: 10,
labelImage: "Image",
labelOf: "of",
init: function() {
this.resizeDuration = this.animate ? ((11 - this.resizeSpeed) * 0.15) : 0;
this.overlayDuration = this.animate ? 0.2 : 0;
if(!initialized) {
Ext.apply(this, Ext.util.Observable.prototype);
Ext.util.Observable.constructor.call(this);
this.addEvents('open', 'close');
this.initMarkup();
this.initEvents();
initialized = true;
}
},
initMarkup: function() {
els.shim = Ext.DomHelper.append(document.body, {
tag: 'iframe',
id: 'ux-lightbox-shim'
}, true);
els.overlay = Ext.DomHelper.append(document.body, {
id: 'ux-lightbox-overlay'
}, true);
var lightboxTpl = new Ext.Template(this.getTemplate());
els.lightbox = lightboxTpl.append(document.body, {}, true);
var ids =
['outerImageContainer', 'imageContainer', 'image', 'hoverNav', 'navPrev', 'navNext', 'loading', 'loadingLink',
'outerDataContainer', 'dataContainer', 'data', 'details', 'caption', 'imageNumber', 'bottomNav', 'navClose'];
Ext.each(ids, function(id){
els[id] = Ext.get('ux-lightbox-' + id);
});
Ext.each([els.overlay, els.lightbox, els.shim], function(el){
el.setVisibilityMode(Ext.Element.DISPLAY)
el.hide();
});
var size = (this.animate ? 250 : 1) + 'px';
els.outerImageContainer.setStyle({
width: size,
height: size
});
},
getTemplate : function() {
return [
'',
'
',
'
',
'
',
'
',
'
',
'
',
'
',
'
',
'
'
];
},
initEvents: function() {
var close = function(ev) {
ev.preventDefault();
this.close();
};
els.overlay.on('click', close, this);
els.loadingLink.on('click', close, this);
els.navClose.on('click', close, this);
els.lightbox.on('click', function(ev) {
if(ev.getTarget().id == 'ux-lightbox') {
this.close();
}
}, this);
els.navPrev.on('click', function(ev) {
ev.preventDefault();
this.setImage(activeImage - 1);
}, this);
els.navNext.on('click', function(ev) {
ev.preventDefault();
this.setImage(activeImage + 1);
}, this);
},
register: function(sel, group) {
if(selectors.indexOf(sel) === -1) {
selectors.push(sel);
Ext.fly(document).on('click', function(ev){
var target = ev.getTarget(sel);
if (target) {
ev.preventDefault();
this.open(target, sel, group);
}
}, this);
}
},
open: function(image, sel, group) {
group = group || false;
this.setViewSize();
els.overlay.fadeIn({
duration: this.overlayDuration,
endOpacity: this.overlayOpacity,
callback: function() {
images = [];
var index = 0;
if(!group) {
images.push([image.href, image.title]);
}
else {
var setItems = Ext.query(sel);
Ext.each(setItems, function(item) {
if(item.href) {
images.push([item.href, item.title]);
}
});
while (images[index][0] != image.href) {
index++;
}
}
// calculate top and left offset for the lightbox
var pageScroll = Ext.fly(document).getScroll();
var lightboxTop = pageScroll.top + (Ext.lib.Dom.getViewportHeight() / 10);
var lightboxLeft = pageScroll.left;
els.lightbox.setStyle({
top: lightboxTop + 'px',
left: lightboxLeft + 'px'
}).show();
this.setImage(index);
this.fireEvent('open', images[index]);
},
scope: this
});
},
setViewSize: function(){
var viewSize = this.getViewSize();
els.overlay.setStyle({
width: viewSize[0] + 'px',
height: viewSize[1] + 'px'
});
els.shim.setStyle({
width: viewSize[0] + 'px',
height: viewSize[1] + 'px'
}).show();
},
setImage: function(index){
activeImage = index;
this.disableKeyNav();
if (this.animate) {
els.loading.show();
}
els.image.hide();
els.hoverNav.hide();
els.navPrev.hide();
els.navNext.hide();
els.dataContainer.setOpacity(0.0001);
els.imageNumber.hide();
var preload = new Image();
preload.onload = (function(){
els.image.dom.src = images[activeImage][0];
this.resizeImage(preload.width, preload.height);
}).createDelegate(this);
preload.src = images[activeImage][0];
},
resizeImage: function(w, h){
var wCur = els.outerImageContainer.getWidth();
var hCur = els.outerImageContainer.getHeight();
var wNew = (w + this.borderSize * 2);
var hNew = (h + this.borderSize * 2);
var wDiff = wCur - wNew;
var hDiff = hCur - hNew;
var afterResize = function(){
els.hoverNav.setWidth(els.imageContainer.getWidth() + 'px');
els.navPrev.setHeight(h + 'px');
els.navNext.setHeight(h + 'px');
els.outerDataContainer.setWidth(wNew + 'px');
this.showImage();
};
if (hDiff != 0 || wDiff != 0) {
els.outerImageContainer.shift({
height: hNew,
width: wNew,
duration: this.resizeDuration,
scope: this,
callback: afterResize,
delay: 50
});
}
else {
afterResize.call(this);
}
},
showImage: function(){
els.loading.hide();
els.image.fadeIn({
duration: this.resizeDuration,
scope: this,
callback: function(){
this.updateDetails();
}
});
this.preloadImages();
},
updateDetails: function(){
var detailsWidth = els.data.getWidth(true) - els.navClose.getWidth() - 10;
els.details.setWidth((detailsWidth > 0 ? detailsWidth : 0) + 'px');
els.caption.update(images[activeImage][1]);
els.caption.show();
if (images.length > 1) {
els.imageNumber.update(this.labelImage + ' ' + (activeImage + 1) + ' ' + this.labelOf + ' ' + images.length);
els.imageNumber.show();
}
els.dataContainer.fadeIn({
duration: this.resizeDuration/2,
scope: this,
callback: function() {
var viewSize = this.getViewSize();
els.overlay.setHeight(viewSize[1] + 'px');
this.updateNav();
}
});
},
updateNav: function(){
this.enableKeyNav();
els.hoverNav.show();
// if not first image in set, display prev image button
if (activeImage > 0)
els.navPrev.show();
// if not last image in set, display next image button
if (activeImage < (images.length - 1))
els.navNext.show();
},
enableKeyNav: function() {
Ext.fly(document).on('keydown', this.keyNavAction, this);
},
disableKeyNav: function() {
Ext.fly(document).un('keydown', this.keyNavAction, this);
},
keyNavAction: function(ev) {
var keyCode = ev.getKey();
if (
keyCode == 88 || // x
keyCode == 67 || // c
keyCode == 27
) {
this.close();
}
else if (keyCode == 80 || keyCode == 37){ // display previous image
if (activeImage != 0){
this.setImage(activeImage - 1);
}
}
else if (keyCode == 78 || keyCode == 39){ // display next image
if (activeImage != (images.length - 1)){
this.setImage(activeImage + 1);
}
}
},
preloadImages: function(){
var next, prev;
if (images.length > activeImage + 1) {
next = new Image();
next.src = images[activeImage + 1][0];
}
if (activeImage > 0) {
prev = new Image();
prev.src = images[activeImage - 1][0];
}
},
close: function(){
this.disableKeyNav();
els.lightbox.hide();
els.overlay.fadeOut({
duration: this.overlayDuration
});
els.shim.hide();
this.fireEvent('close', activeImage);
},
getViewSize: function() {
return [Ext.lib.Dom.getViewWidth(), Ext.lib.Dom.getViewHeight()];
}
}
})();
Ext.onReady(Ext.ux.Lightbox.init, Ext.ux.Lightbox);