X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/2e847cf21b8ab9d15fa167b315ca5b2fa92638fc..6a7e4474cba9d8be4b2ec445e10f1691f7277c50:/src/ext-core/examples/lightbox/lightbox.js diff --git a/src/ext-core/examples/lightbox/lightbox.js b/src/ext-core/examples/lightbox/lightbox.js new file mode 100644 index 00000000..86fab2c4 --- /dev/null +++ b/src/ext-core/examples/lightbox/lightbox.js @@ -0,0 +1,366 @@ +/*! + * 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.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); \ No newline at end of file