/* # Slip-n-slide photo gallery # Version: 0.1 # Author: Nick Grossman # URL: http://wrkng.net/slip-n-slide # License: GPL 3 http://www.gnu.org/licenses/gpl-3.0.html */ /* Requires EXT Javascript framework 2.0 */ /* SlipNSlide Photo Gallery # # @extEl: an Ext Element object. # */ SlipNSlide = function(extEl) { // get refs var container = extEl; var list = Ext.get(Ext.query('UL', container.dom)[0]); var listItems = Ext.select(Ext.query('LI', list.dom)); var images = Ext.select(Ext.query('IMG', container.dom)); var firstItem = Ext.get(listItems.elements[0]); var lastItem = Ext.get(listItems.elements[listItems.elements.length - 1]); var selectedImage; var prev = Ext.get(Ext.query('.js-prev-photos')[0]); var next = Ext.get(Ext.query('.js-next-photos')[0]); var main; /* will become ext element for main image */ var selectedAbsolutePosition = 0; /* select first image to start */ var selectedRelativePosition = 0; if (!container || !list || !images) { return false; } // initialize _init(this); function _init(context) { // create main image main = container.insertHtml('afterBegin', '', true); // create next and prev buttons // set images buttons display mode listItems.setVisibilityMode(Ext.Element.DISPLAY); // load first image into main pane. selectedImage = images.elements[0]; _loadImage({}, selectedImage, {}); // update source list (hide all but first 3) _initializeSourceList(); // attach handlers images.on('click', _loadImage, this); next.on('click', _nextClick, this, {preventDefault: true}); prev.on('click', _prevClick, this, {preventDefault: true}); images.on('mouseover', _imageMouseover, this); images.on('mouseout', _imageMouseout, this); } function _imageMouseover(e, el, o) { Ext.get(el).addClass('hover'); } function _imageMouseout(e, el, o) { Ext.get(el).removeClass('hover'); } function _loadImage(e, el, o) { selectedImage = Ext.get(el); // set main image to full-size version of thumb main.hide(); main.dom.src = el.src.replace('/thumbs', ''); main.fadeIn(); // remove highlighting from all listitems images.removeClass('selected'); // highlight selected item in list selectedImage.addClass('selected'); // update current position selectedAbsolutePosition = _findAbsolutePosition(selectedImage); selectedRelativePosition = _findRelativePosition(selectedImage); } function _initializeSourceList() { var start = selectedAbsolutePosition; var end = selectedAbsolutePosition + 2; _updateSourceList(start,end); } function _prevClick() { var start; var end; // make sure clicking next moves you to the prev group of 3 switch (selectedRelativePosition) { case 0: start = selectedAbsolutePosition - 3; end = selectedAbsolutePosition - 1; break; case 1: start = selectedAbsolutePosition - 4; end = selectedAbsolutePosition - 2 ; break; case 2: start = selectedAbsolutePosition - 5; end = selectedAbsolutePosition - 3; break; } // if (!firstItem.isDisplayed()) { // update source list _updateSourceList(start,end); // load image _loadImage({}, images.elements[end], {}); } } function _nextClick() { var start; var end; // make sure clicking next moves you to the next group of 3 switch (selectedRelativePosition) { case 0: start = selectedAbsolutePosition + 3; end = selectedAbsolutePosition + 5; break; case 1: start = selectedAbsolutePosition + 2; end = selectedAbsolutePosition + 4 ; break; case 2: start = selectedAbsolutePosition + 1; end = selectedAbsolutePosition + 3; break; } // only update source list if last image isn't already on screen if (!lastItem.isDisplayed()) { // update source list _updateSourceList(start,end); // load image _loadImage({}, images.elements[start], {}); } } function _updateSourceList(start, end) { // loop through list of LIs and hide if they're not // in the range listItems.each(function(extEl, list, i) { if (i < start || i > end) { extEl.hide(); } else if (extEl.dom.id == selectedImage.dom.parentNode.id) { // don't fade in currently selected image. extEl.show(); } else { // fade in new images extEl.fadeIn(); } }); // disable next / prev buttons if (lastItem.isDisplayed()) { next.addClass('disabled'); } else { next.removeClass('disabled'); } if (firstItem.isDisplayed()) { prev.addClass('disabled'); } else { prev.removeClass('disabled'); } } function _findAbsolutePosition(selection) { // loop through list of photos, return the position of the // currently selected photo var counter = 0; var position; images.each(function(extEl) { if(selection.dom.id == extEl.dom.id) { position = counter; } counter++; }); return position; } function _findRelativePosition(selection) { // loop through list of _visible_ photos, return the position of the // currently selected photo var counter = 0; var position; images.each(function(extEl) { if(selection.dom.id == extEl.dom.id) { position = counter; } if (Ext.get(extEl.dom.parentNode).isVisible()) { counter++; } }); return position; } return this; }