/* galleryview - jquery content gallery plugin author: jack anderson version: 3.0 development see readme.txt for instructions on how to markup your html */ // make sure object.create is available in the browser (for our prototypal inheritance) // courtesy of douglas crockford if (typeof object.create !== 'function') { object.create = function (o) { function f() {} f.prototype = o; return new f(); }; } (function ($) { // custom image object var gvimage = function (img) { this.src = { panel: img.attr('src'), frame: img.data('frame') || img.attr('src') }; this.scale = { panel: null, frame: null }; this.height = 0; this.width = 0; this.attrs = { title: img.attr('title') || img.attr('alt'), description: img.data('description') }; this.href = null; this.dom_obj = null; return this; }, // utility function wrapper gv = { getint: function(i) { i = parseint(i, 10); return isnan(i) ? 0 : i; }, innerwidth: function(elem) { return this.getint(elem.css('width')) || 0; }, outerwidth: function(elem) { return this.innerwidth(elem) + this.extrawidth(elem); }, extrawidth: function(elem) { return this.getint(elem.css('paddingleft')) + this.getint(elem.css('paddingright')) + this.getint(elem.css('borderleftwidth')) + this.getint(elem.css('borderrightwidth')); }, innerheight: function(elem) { return this.getint(elem.css('height'))|| 0; }, outerheight: function(elem) { return this.innerheight(elem) + this.extraheight(elem); }, extraheight: function(elem) { return this.getint(elem.css('paddingtop')) + this.getint(elem.css('paddingbottom')) + this.getint(elem.css('bordertopwidth')) + this.getint(elem.css('borderbottomwidth')); } }, /* galleryview - object the main gallery class */ galleryview = { // array of dom elements elems: [ '.gv_gallerywrap', '.gv_gallery', '.gv_panelwrap', '.gv_panel', 'img.gv_image', '.gv_infobar', '.gv_filmstripwrap', '.gv_filmstrip', '.gv_frame', '.gv_thumbnail', '.gv_caption', 'img.gv_thumb', '.gv_navwrap', '.gv_navnext', '.gv_navprev', '.gv_navplay', '.gv_panelnavnext', '.gv_panelnavprev', '.gv_overlay', '.gv_showoverlay', '.gv_imagestore' ], // create a jquery element and apply attributes createelem: function(attrs,elem) { elem = document.createelement(elem); var $elem = $(elem); return $elem.attr(attrs); }, // get the position of an element with respect // to the gallery wrapper getpos: function (el) { var self = this, dom = this.dom, el = el[0], el_id = el.id, left = 0, top = 0, gpos, gleft, gtop; if (!el) { return { top: 0, left: 0 }; } if (el.offsetparent) { do { left += el.offsetleft; top += el.offsettop; } while (el = el.offsetparent); } //if we want the position of the gallery itself, return it if (el_id === self.id) { return { left: left, top: top }; } //otherwise, get position of element relative to gallery else { gpos = self.getpos(dom.gallerywrap); gleft = gpos.left; gtop = gpos.top; return { left: left - gleft, top: top - gtop }; } }, // determine if mouse is within the boundary of the gallery wrapper mouseisovergallery: function (x, y) { var self = this, dom = this.dom, pos = this.getpos(dom.gv_gallerywrap), top = pos.top, left = pos.left; return x > left && x < left + gv.outerwidth(dom.gv_gallerywrap) && y > top && y < top + gv.outerheight(dom.gv_gallerywrap); }, // determine if mouse is within the boundary of the panel mouseisoverpanel: function (x, y) { var self = this, dom = this.dom, pos = this.getpos(dom.gv_panelwrap), gpos = this.getpos(dom.gv_gallerywrap), top = pos.top + gpos.top, left = pos.left + gpos.left; return x > left && x < left + gv.outerwidth(dom.gv_panelwrap) && y > top && y < top + gv.outerheight(dom.gv_panelwrap); }, // create gvimage objects for each image in gallery storeimages: function() { var self = this; this.sourceimgs = $('li>img',this.$el); this.numimages = this.sourceimgs.length; this.gvimages = []; this.sourceimgs.each(function(i,img) { self.gvimages[i] = new gvimage($(img)); }); }, setdimensions: function() { var self = this, dom = this.dom, widths = { prev: gv.innerwidth(dom.gv_navprev), play: gv.innerwidth(dom.gv_navplay), next: gv.innerwidth(dom.gv_navnext), filmstrip: this.opts.frame_width, fsmax: 0, fsfull: 0 }, heights = { prev: gv.innerheight(dom.gv_navprev), play: gv.innerheight(dom.gv_navplay), next: gv.innerheight(dom.gv_navnext), filmstrip: this.opts.frame_height + (this.opts.show_captions ? gv.outerheight(dom.gv_caption) : 0), fsmax: 0, fsfull: 0 }, panels = []; // nav if(this.filmstriporientation === 'horizontal') { dom.gv_navwrap.css({ width: widths.prev + widths.play + widths.next, height: math.max(heights.prev,heights.play,heights.next) }); } else { if(this.opts.filmstrip_style === 'scroll' && this.opts.frame_width < (widths.prev + widths.play + widths.next)) { dom.gv_navwrap.css({ width: math.max(widths.prev, widths.play, widths.next), height: heights.prev + heights.play + heights.next }); } else { dom.gv_navwrap.css({ width: widths.prev + widths.play + widths.next, height: math.max(heights.prev,heights.play,heights.next) }); } } if(this.filmstriporientation === 'vertical' && widths.filmstrip < (widths.prev + widths.play + widths.next)) { dom.gv_navwrap.css({ width: math.max(widths.prev, widths.play, widths.next), height: heights.prev + heights.play + heights.next }); } else { dom.gv_navwrap.css({ width: widths.prev + widths.play + widths.next, height: math.max(heights.prev,heights.play,heights.next) }); } // panels dom.gv_panel.css({ width: this.opts.panel_width, height: this.opts.panel_height }); dom.gv_panelwrap.css({ width: gv.outerwidth(dom.gv_panel), height: gv.outerheight(dom.gv_panel) }); dom.gv_overlay.css({ width: this.opts.panel_width }); $.each(this.gvimages,function(i,img) { dom.gv_panelwrap.append(dom.gv_panel.clone(true)); }); dom.gv_panels = dom.gv_panelwrap.find('.gv_panel'); dom.gv_panels.remove(); // filmstrip dom.gv_thumbnail.css({ width: this.opts.frame_width, height: this.opts.frame_height }); dom.gv_frame.css({ width: gv.outerwidth(dom.gv_thumbnail), height: gv.outerheight(dom.gv_thumbnail) + (this.opts.show_captions ? gv.outerheight(dom.gv_caption) : 0), marginright: this.opts.frame_gap, marginbottom: this.opts.frame_gap }); if(this.filmstriporientation === 'horizontal') { this.filmstripsize = math.floor((gv.outerwidth(dom.gv_panelwrap) - gv.outerwidth(dom.gv_navwrap)) / (gv.outerwidth(dom.gv_frame) + this.opts.frame_gap)); widths.fsmax = this.filmstripsize * (gv.outerwidth(dom.gv_frame) + this.opts.frame_gap); widths.fsfull = this.gvimages.length * (gv.outerwidth(dom.gv_frame) + this.opts.frame_gap); widths.filmstrip = math.min(widths.fsmax,widths.fsfull); if(this.opts.filmstrip_style !== 'scroll') { heights.filmstrip = (math.ceil(this.gvimages.length / this.filmstripsize) * (gv.outerheight(dom.gv_frame) + this.opts.frame_gap)) - this.opts.frame_gap; } } else { this.filmstripsize = math.floor((gv.outerheight(dom.gv_panelwrap) - gv.outerheight(dom.gv_navwrap)) / (gv.outerheight(dom.gv_frame) + this.opts.frame_gap)); heights.fsmax = this.filmstripsize * (gv.outerheight(dom.gv_frame) + this.opts.frame_gap); heights.fsfull = this.gvimages.length * (gv.outerheight(dom.gv_frame) + this.opts.frame_gap); heights.filmstrip = math.min(heights.fsmax,heights.fsfull); if(this.opts.filmstrip_style !== 'scroll') { widths.filmstrip = (math.ceil(this.gvimages.length / this.filmstripsize) * (gv.outerwidth(dom.gv_frame) + this.opts.frame_gap)) - this.opts.frame_gap; } } dom.gv_filmstripwrap.css({ width: widths.filmstrip, height: heights.filmstrip }); // gallery if(this.opts.show_filmstrip) { if(this.filmstriporientation === 'horizontal') { dom.gv_gallery.css({ width: gv.outerwidth(dom.gv_panelwrap), height: gv.outerheight(dom.gv_panelwrap) + this.opts.frame_gap + (this.opts.show_filmstrip ? math.max(gv.outerheight(dom.gv_filmstripwrap),gv.outerheight(dom.gv_navwrap)) : gv.outerheight(dom.gv_filmstripwrap)) }); } else { dom.gv_gallery.css({ width: gv.outerwidth(dom.gv_panelwrap) + this.opts.frame_gap + (this.opts.show_filmstrip ? math.max(gv.outerwidth(dom.gv_filmstripwrap),gv.outerwidth(dom.gv_navwrap)) : gv.outerwidth(dom.gv_filmstripwrap)), height: gv.outerheight(dom.gv_panelwrap) }); } } else { dom.gv_gallery.css({ width: gv.outerwidth(dom.gv_panelwrap), height: gv.outerheight(dom.gv_panelwrap) }); } dom.gv_gallerywrap.css({ width: gv.outerwidth(dom.gv_gallery), height: gv.outerheight(dom.gv_gallery), padding: this.opts.frame_gap }); }, setpositions: function() { var self = this, dom = this.dom, navvert = 0, fsvert = 0, navhorz = 0, fshorz = 0, vert, horz; // determine vertical or horizontal offset // if negative, apply to filmstrip, otherwise apply to navbar if(this.filmstriporientation === 'horizontal') { vert = math.round((gv.outerheight(dom.gv_filmstripwrap) - gv.outerheight(dom.gv_navwrap)) / 2); if(vert < 0) { fsvert = -1 * vert; } else { navvert = vert; } } else { horz = math.round((gv.outerwidth(dom.gv_filmstripwrap) - gv.outerwidth(dom.gv_navwrap)) / 2); if(horz < 0) { fshorz = -1 * horz; } else { navhorz = horz; } } // for horizontal filmstrips w/o navigation, center the filmstrip under the panel if(!this.opts.show_filmstrip_nav && this.filmstriporientation === 'horizontal') { fshorz = math.floor((gv.outerwidth(dom.gv_panelwrap) - gv.outerwidth(dom.gv_filmstripwrap)) / 2); } dom.gv_panelnavnext.css({ top: (gv.outerheight(dom.gv_panel) - gv.outerheight(dom.gv_panelnavnext)) / 2, right: 10 }); dom.gv_panelnavprev.css({ top: (gv.outerheight(dom.gv_panel) - gv.outerheight(dom.gv_panelnavprev)) / 2, left: 10 }); // pin elements to gallery corners according to filmstrip position switch(this.opts.filmstrip_position) { case 'top': dom.gv_navwrap.css({ top: navvert, right: navhorz }); dom.gv_panelwrap.css({ bottom: 0, left: 0 }); dom.gv_filmstripwrap.css({ top: fsvert, left: fshorz }); break; case 'right': dom.gv_navwrap.css({ bottom: navvert, right: navhorz }); dom.gv_panelwrap.css({ top: 0, left: 0 }); dom.gv_filmstripwrap.css({ top: fsvert, right: fshorz }); break; case 'left': dom.gv_navwrap.css({ bottom: navvert, left: navhorz }); dom.gv_panelwrap.css({ top: 0, right: 0 }); dom.gv_filmstripwrap.css({ top: fsvert, left: fshorz }); break; default: dom.gv_navwrap.css({ bottom: navvert, right: navhorz }); dom.gv_panelwrap.css({ top: 0, left: 0 }); dom.gv_filmstripwrap.css({ bottom: fsvert, left: fshorz }); break; } if(this.opts.overlay_position === 'top') { dom.gv_overlay.css({ top: 0, left: -99999 }); dom.gv_showoverlay.css({ top: 0, left: 0 }); } else { dom.gv_overlay.css({ bottom: 0, left: -99999 }); dom.gv_showoverlay.css({ bottom: 0, left: 0 }); } if(!this.opts.show_filmstrip_nav) { dom.gv_navwrap.remove(); } }, buildfilmstrip: function() { var self = this, dom = this.dom, frameslength = this.gvimages.length * ((this.filmstriporientation === 'horizontal' ? this.opts.frame_width : this.opts.frame_height) + this.opts.frame_gap); dom.gv_frame.append(dom.gv_thumbnail); if(this.opts.show_captions) { dom.gv_frame.append(dom.gv_caption); } dom.gv_thumbnail.css('opacity',this.opts.frame_opacity); dom.gv_thumbnail.bind({ mouseover: function() { if(!$(this).hasclass('current')) { $(this).stop().animate({opacity:1},250); } }, mouseout: function() { if(!$(this).hasclass('current')) { $(this).stop().animate({opacity:self.opts.frame_opacity},250); } } }); // drop a clone of the frame element into the filmstrip for each source image $.each(this.gvimages,function(i,img) { dom.gv_frame.clone(true).prependto(dom.gv_filmstrip); }); dom.gv_filmstrip.css({ width: gv.outerwidth(dom.gv_frame), height: gv.outerheight(dom.gv_frame) }); // if we are scrolling the filmstrip, and we can't show all frames at once, // make two additional copies of each frame if(this.opts.filmstrip_style === 'scroll') { if(this.filmstriporientation === 'horizontal') { if(frameslength > gv.innerwidth(dom.gv_filmstripwrap)) { dom.gv_filmstrip.find('.gv_frame').clone(true).appendto(dom.gv_filmstrip).clone(true).appendto(dom.gv_filmstrip); dom.gv_filmstrip.css('width',frameslength * 3); this.scrolling = true; } else { dom.gv_filmstrip.css('width',frameslength); } } else { if(frameslength > gv.innerheight(dom.gv_filmstripwrap)) { dom.gv_filmstrip.find('.gv_frame').clone(true).appendto(dom.gv_filmstrip).clone(true).appendto(dom.gv_filmstrip); dom.gv_filmstrip.css('height',frameslength * 3); this.scrolling = true; } else { dom.gv_filmstrip.css('height',frameslength); } } } else { dom.gv_filmstrip.css({ width: parseint(dom.gv_filmstripwrap.css('width'),10)+this.opts.frame_gap, height: parseint(dom.gv_filmstripwrap.css('height'),10)+this.opts.frame_gap }); } dom.gv_frames = dom.gv_filmstrip.find('.gv_frame'); $.each(dom.gv_frames,function(i,frame) { $(frame).data('frameindex',i); }); dom.gv_thumbnails = dom.gv_filmstrip.find('div.gv_thumbnail'); }, buildgallery: function() { var self = this, dom = this.dom; this.setdimensions(); this.setpositions(); if(this.opts.show_filmstrip) { this.buildfilmstrip(); } }, showinfobar: function() { if(!this.opts.show_infobar) { return; } var self = this, dom = this.dom; dom.gv_infobar.stop().stoptime('hideinfobar_' + self.id).html((this.iterator+1) + ' of ' + this.numimages).show().css('opacity',this.opts.infobar_opacity); dom.gv_infobar.onetime(2000 + this.opts.transition_speed,'hideinfobar_' + self.id,function() { dom.gv_infobar.fadeout(1000); }); }, initimages: function() { var self = this, dom = this.dom; $.each(this.gvimages,function(i,gvimage) { var img = $(''); img.css('visibility','hidden').data('index',i); img.bind('load.galleryview',function() { var _img = $(this), index = _img.data('index'), width = this.width, height = this.height, parent = dom[(_img.data('parent')).type].eq((_img.data('parent')).index), widthfactor = gv.innerwidth(parent) / width, heightfactor = gv.innerheight(parent) / height, parenttype = parent.hasclass('gv_panel') ? 'panel' : 'frame', heightoffset = 0, widthoffset = 0; gvimage.scale[parenttype] = self.opts[parenttype+'_scale'] === 'fit' ? math.min(widthfactor,heightfactor) : math.max(widthfactor,heightfactor); widthoffset = math.round((gv.innerwidth(parent) - (width * gvimage.scale[parenttype])) / 2); heightoffset = math.round((gv.innerheight(parent) - (height * gvimage.scale[parenttype])) / 2); _img.css({ width: width * gvimage.scale[parenttype], height: height * gvimage.scale[parenttype], top: heightoffset, left: widthoffset }); _img.hide().css('visibility','visible'); _img.remove().appendto(parent); if(parenttype === 'frame') { _img.fadein(); parent.parent().removeclass('gv_frame-loading'); parent.parent().find('.gv_caption').html(gvimage.attrs.title); } else if(index === self.opts.start_frame - 1) { parent.prependto(dom.gv_panelwrap); parent.removeclass('gv_panel-loading'); _img.fadein(); self.showinfobar(); } else { parent.removeclass('gv_panel-loading'); _img.show(); } }); // store eventual image container as data property // append to temporary storage element and set src if(self.opts.show_panels) { img.clone(true) .data('parent',{type:'gv_panels',index:i}) .appendto(dom.gv_imagestore) .attr('src',gvimage.src.panel); } if(self.opts.show_filmstrip) { img.clone(true) .data('parent',{type:'gv_thumbnails',index:i}) .appendto(dom.gv_imagestore) .attr('src',gvimage.src.frame); if(dom.gv_frames.length > dom.gv_panels.length) { img.clone(true) .data('parent',{type:'gv_thumbnails',index:i+self.numimages}) .appendto(dom.gv_imagestore) .attr('src',gvimage.src.frame); img.clone(true) .data('parent',{type:'gv_thumbnails',index:i+self.numimages+self.numimages}) .appendto(dom.gv_imagestore) .attr('src',gvimage.src.frame); } } }); }, shownext: function() { this.navaction = 'next'; this.showitem(this.frameiterator+1); }, showprev: function() { this.navaction = 'prev'; this.showitem(this.frameiterator-1); }, showitem: function(i) { if(isnan(i)) { return; } if(!this.opts.show_filmstrip) { i = i % this.numimages; } var self = this, dom = this.dom, frame_i = i, newpanelstart, oldpanelend, olditerator, panel, playing = false; // don't go out of bounds if(i >= this.numimages) { i = i % this.numimages; } else if(i < 0) { i = this.numimages - 1; if(dom.gv_frames != undefined) { frame_i = dom.gv_frames.length - 1; } else { frame_i = dom.gv_panels.length - 1; } } panel = dom.gv_panels.eq(i); playing = this.playing; if(playing) { this.stopslideshow(false); } this.unbindactions(); dom.gv_gallery.onetime(this.opts.transition_speed,'bindactions_' + self.id,function(){ if(playing) { self.startslideshow(false); } self.bindactions(); }); switch(this.opts.panel_animation) { case 'crossfade': dom.gv_panels.eq(this.iterator).fadeout(this.opts.transition_speed,function(){$(this).remove();}); panel.hide().prependto(dom.gv_panelwrap).fadein(this.opts.transition_speed); break; case 'fade': dom.gv_panels.eq(this.iterator).remove(); panel.hide().prependto(dom.gv_panelwrap).fadein(this.opts.transition_speed); break; case 'slide': if(this.navaction === 'next' || (this.navaction === 'frame' && frame_i > this.iterator)) { newpanelstart = gv.outerwidth(dom.gv_panel); oldpanelend = -1 * gv.outerwidth(dom.gv_panel); } else { newpanelstart = -1 * gv.outerwidth(dom.gv_panel); oldpanelend = gv.outerwidth(dom.gv_panel); } panel.css({ left:newpanelstart }).appendto(dom.gv_panelwrap).animate( { left:0 }, { duration: this.opts.transition_speed,easing: this.opts.easing } ); dom.gv_panels.eq(this.iterator).animate( { left: oldpanelend }, { duration: this.opts.transition_speed, easing: this.opts.easing, complete: function(){ $(this).remove(); } } ); break; default: dom.gv_panels.eq(this.iterator).remove(); panel.prependto(dom.gv_panelwrap); break; } this.updateoverlay(i); this.iterator = i; this.updatefilmstrip(frame_i); this.showinfobar(); }, updateoverlay: function(i) { var self = this, dom = this.dom; if(this.overlayvisible) { this.hideoverlay(null,function(){ dom.gv_overlay.html('

'+self.gvimages[i].attrs.title+'

'+self.gvimages[i].attrs.description+'

'); self.showoverlay(); }); } else { dom.gv_overlay.html('

'+self.gvimages[i].attrs.title+'

'+self.gvimages[i].attrs.description+'

'); dom.gv_overlay.css(this.opts.overlay_position,-1 * dom.gv_overlay.outerheight()); } }, hideoverlay: function(s,callback) { var self = this, dom = this.dom, endoverlay = {}, endbutton = {}, speed = s || self.opts.transition_speed / 2; callback = callback || function(){}; endoverlay[this.opts.overlay_position] = -1 * dom.gv_overlay.outerheight(); endbutton[this.opts.overlay_position] = 0; dom.gv_overlay.animate(endoverlay,{ duration: speed, easing: 'swing', complete: callback }); dom.gv_showoverlay.animate(endbutton,{ duration: speed, easing: 'swing' }); this.overlayvisible = false; }, showoverlay: function(s) { var self = this, dom = this.dom, startoverlay = {}, endoverlay = {}, endbutton = {}, speed = s || self.opts.transition_speed / 2; startoverlay[this.opts.overlay_position] = -1 * dom.gv_overlay.outerheight(); startoverlay.left = 0; endoverlay[this.opts.overlay_position] = 0; endbutton[this.opts.overlay_position] = dom.gv_overlay.outerheight(); dom.gv_overlay.css(startoverlay); dom.gv_overlay.animate(endoverlay,{ duration: speed, easing: 'swing' }); dom.gv_showoverlay.animate(endbutton,{ duration: speed, easing: 'swing' }); this.overlayvisible = true; }, updatefilmstrip: function(to) { if(!this.opts.show_filmstrip) { this.frameiterator = to; return; } var self = this, dom = this.dom, targetthumbs = dom.gv_thumbnails.eq(this.iterator), filmstripiterator, distance; if(this.scrolling) { targetthumbs = targetthumbs. add(dom.gv_thumbnails.eq(this.iterator + this.numimages)). add(dom.gv_thumbnails.eq(this.iterator + (2 * this.numimages))); } dom.gv_thumbnails.removeclass('current').animate({ opacity: this.opts.frame_opacity }); targetthumbs.stop().addclass('current').animate({ opacity: 1 },500); if(this.scrolling) { if(this.filmstriporientation === 'horizontal') { distance = (gv.outerwidth(dom.gv_frame) + this.opts.frame_gap) * (this.frameiterator - to); if(distance > 0) { distance = '+=' + math.abs(distance); } else { distance = '-=' + math.abs(distance); } dom.gv_filmstrip.animate({ left: distance },{ duration: this.opts.transition_speed, easing: this.opts.easing, complete: function(){ if(to < self.numimages) { dom.gv_filmstrip.css('left',gv.getint(dom.gv_filmstrip.css('left'))-(self.numimages*(gv.outerwidth(dom.gv_frame)+self.opts.frame_gap))); } else if(to >= (self.numimages * 2)) { dom.gv_filmstrip.css('left',gv.getint(dom.gv_filmstrip.css('left'))+(self.numimages*(gv.outerwidth(dom.gv_frame)+self.opts.frame_gap))); } self.frameiterator = (to % self.numimages) + self.numimages; } }); } else { distance = (gv.outerheight(dom.gv_frame) + this.opts.frame_gap) * (this.frameiterator - to); if(distance > 0) { distance = '+=' + math.abs(distance); } else { distance = '-=' + math.abs(distance); } dom.gv_filmstrip.animate({ top: distance },{ duration: this.opts.transition_speed, easing: this.opts.easing, complete: function(){ // adjust filmstrip position to ensure that there is always at least one frame behind // and (2 * filmstripsize) ahead if(to === 0) { dom.gv_filmstrip.css('top',gv.getint(dom.gv_filmstrip.css('top'))-(self.numimages*(gv.outerheight(dom.gv_frame)+self.opts.frame_gap))); self.frameiterator = self.numimages; } else if(to > ((self.numimages * 3) - (self.filmstripsize * 2))) { dom.gv_filmstrip.css('top',gv.getint(dom.gv_filmstrip.css('top'))+(self.numimages*(gv.outerheight(dom.gv_frame)+self.opts.frame_gap))); self.frameiterator = to - self.numimages; } else { self.frameiterator = to; } } }); } } else { this.frameiterator = to; } }, startslideshow: function(changeicon) { var self = this, dom = this.dom; if(!self.opts.enable_slideshow) { return; } if(changeicon) { dom.gv_navplay.removeclass('gv_navplay').addclass('gv_navpause'); } this.playing = true; dom.gv_gallerywrap.everytime(this.opts.transition_interval,'slideshow_'+this.id,function(){ self.shownext(); }); }, stopslideshow: function(changeicon) { var self = this, dom = this.dom; if(changeicon) { dom.gv_navplay.removeclass('gv_navpause').addclass('gv_navplay'); } this.playing = false; dom.gv_gallerywrap.stoptime('slideshow_'+this.id); }, enablepanning: function() { var self = this, dom = this.dom; if(!self.opts.enable_slideshow) { return; } dom.gv_panel.css('cursor','url(http://www.google.com/intl/en_all/mapfiles/openhand.cur), n-resize'); if(this.opts.pan_style === 'drag') { dom.gv_panelwrap.delegate('.gv_panel img','mousedown.galleryview',function(e) { self.ismousedown = true; $(this).css('cursor','url(http://www.google.com/intl/en_all/mapfiles/closedhand.cur), n-resize'); }).delegate('.gv_panel img','mouseup.galleryview',function(e) { self.ismousedown = false; $(this).css('cursor','url(http://www.google.com/intl/en_all/mapfiles/openhand.cur), n-resize'); }).delegate('.gv_panel img','mousemove.galleryview',function(e) { var disty, distx, image = $(this), new_top, new_left; if(self.ismousedown) { disty = e.pagey - self.mouse.y; distx = e.pagex - self.mouse.x; new_top = gv.getint(image.css('top')) + disty; new_left = gv.getint(image.css('left')) + distx; image.css('cursor','url(http://www.google.com/intl/en_all/mapfiles/closedhand.cur), n-resize'); if(new_top > 0) new_top = 0; if(new_left > 0) new_left = 0; if(new_top < (-1 * (gv.outerheight(image) - gv.innerheight(dom.gv_panel)))) { new_top = -1 * (gv.outerheight(image) - gv.innerheight(dom.gv_panel)); } if(new_left < (-1 * (gv.outerwidth(image) - gv.innerwidth(dom.gv_panel)))) { new_left = -1 * (gv.outerwidth(image) - gv.innerwidth(dom.gv_panel)); } image.css('top',new_top); image.css('left',new_left); } else { image.css('cursor','url(http://www.google.com/intl/en_all/mapfiles/openhand.cur), n-resize'); } }); } else { } }, bindactions: function() { var self = this, dom = this.dom; dom.gv_showoverlay.bind('click.galleryview',function(){ if(self.overlayvisible) { self.hideoverlay(250); } else { self.showoverlay(250); } }); dom.gv_navwrap.delegate('div','click.galleryview',function(){ var el = $(this); if(el.hasclass('gv_navnext')) { self.shownext(); } else if(el.hasclass('gv_navprev')) { self.showprev(); } else if(el.hasclass('gv_navplay')) { self.startslideshow(true); } else if(el.hasclass('gv_navpause')) { self.stopslideshow(true); } return false; }); dom.gv_panelnavnext.bind('click.galleryview',function(){ self.shownext(); return false; }); dom.gv_panelnavprev.bind('click.galleryview',function(){ self.showprev(); return false; }); dom.gv_filmstripwrap.delegate('.gv_frame','click.galleryview',function(){ var el = $(this), i = el.data('frameindex'); this.navaction = 'frame'; self.showitem(i); return false; }); dom.gv_panelwrap.bind('mouseover.galleryview',function(){ self.showpanelnav(); }).bind('mouseout.galleryview',function(){ self.hidepanelnav(); }); }, unbindactions: function() { var self = this, dom = this.dom; dom.gv_showoverlay.unbind('click.galleryview'); dom.gv_panelnavnext.unbind('click.galleryview'); dom.gv_panelnavprev.unbind('click.galleryview'); dom.gv_navwrap.undelegate('div','click.galleryview'); dom.gv_filmstripwrap.undelegate('.gv_frame','click.galleryview'); }, showpanelnav: function() { var self = this, dom = this.dom; dom.gv_panelnavnext.show(); dom.gv_panelnavprev.show(); }, hidepanelnav: function() { var self = this, dom = this.dom; dom.gv_panelnavnext.hide(); dom.gv_panelnavprev.hide(); }, init: function(options,el) { var self = this, dom = this.dom = {}; this.opts = $.extend({},$.fn.galleryview.defaults,options); this.el = el; this.$el = $(el); this.id = el.id; this.iterator = this.frameiterator = this.opts.start_frame - 1; this.overlayvisible = false; this.playing = false; this.scrolling = false; this.ismousedown = false; this.mouse = { x: 0, y: 0 }; this.filmstriporientation = (this.opts.filmstrip_position === 'top' || this.opts.filmstrip_position === 'bottom') ? 'horizontal' : 'vertical'; $(document).bind('mousemove.galleryview',function(e) { self.mouse = {x: e.pagex, y: e.pagey}; }); // create all necessary dom elements $.each(this.elems,function(i,elem) { var elem = elem.split('.'); // if there is no tag name, assume
if(elem[0] === '') { elem[0] = 'div'; } // add jquery element to dom object dom[elem[1]] = self.createelem({'class':elem[1]},elem[0]); }); dom.gv_imagestore.appendto($('body')); dom.gv_gallerywrap.delegate('img','mousedown.galleryview',function(e){ if(e.preventdefault) { e.preventdefault(); } }); dom.gv_panel.addclass('gv_panel-loading'); dom.gv_frame.addclass('gv_frame-loading'); // nest dom elements dom.gv_gallerywrap.hide().append(dom.gv_gallery); if(this.opts.show_panels) { dom.gv_gallery.append(dom.gv_panelwrap); if(this.opts.show_panel_nav) { dom.gv_panelwrap.append(dom.gv_panelnavnext,dom.gv_panelnavprev); } if(this.opts.show_infobar) { dom.gv_panelwrap.append(dom.gv_infobar); } } if(this.opts.show_filmstrip) { dom.gv_gallery.append( dom.gv_filmstripwrap.append( dom.gv_filmstrip ) ); if(this.opts.show_filmstrip_nav) { dom.gv_gallery.append( dom.gv_navwrap.append( dom.gv_navprev, (this.opts.enable_slideshow?dom.gv_navplay:$('')), dom.gv_navnext ) ); } } if(this.opts.enable_overlays) { dom.gv_panelwrap.append(dom.gv_overlay,dom.gv_showoverlay); } if(this.opts.show_captions) { dom.gv_frame.append(dom.gv_caption).appendto(dom.gv_gallery); } //swap out source element with gallery this.$el.replacewith(dom.gv_gallerywrap); if(this.opts.pan_images) { this.enablepanning(); } // convert source images into gvimage objects this.storeimages(); // block out dimensions/positions of gallery elements this.buildgallery(); // begin loading images into gallery this.initimages(); // set up transitions, buttons this.bindactions(); // remove temporary frame element dom.gv_frame.remove(); // show gallery dom.gv_gallerywrap.show(); if(this.opts.autoplay) { this.startslideshow(true); } this.updateoverlay(this.iterator); this.updatefilmstrip(this.frameiterator); } }; // end galleryview /* main plugin code */ $.fn.galleryview = function (options) { if (this.length) { return this.each(function () { var gallery = object.create(galleryview); gallery.init(options,this); }); } }; /* default options object literal storing default plugin options */ $.fn.galleryview.defaults = { // general options transition_speed: 1000, //int - duration of panel/frame transition (in milliseconds) transition_interval: 5000, //int - delay between panel/frame transitions (in milliseconds) easing: 'swing', //string - easing method to use for animations (jquery provides 'swing' or 'linear', more available with jquery ui or easing plugin) // panel options show_panels: true, //boolean - flag to show or hide panel portion of gallery show_panel_nav: true, //boolean - flag to show or hide panel navigation buttons enable_overlays: false, //boolean - flag to show or hide panel overlays panel_width: 800, //int - width of gallery panel (in pixels) panel_height: 400, //int - height of gallery panel (in pixels) panel_animation: 'fade', //string - animation method for panel transitions (crossfade,fade,slide,none) panel_scale: 'crop', //string - cropping option for panel images (crop = scale image and fit to aspect ratio determined by panel_width and panel_height, fit = scale image and preserve original aspect ratio) overlay_position: 'bottom', //string - position of panel overlay (bottom, top) pan_images: false, //boolean - flag to allow user to grab/drag oversized images within gallery pan_style: 'drag', //string - panning method (drag = user clicks and drags image to pan, track = image automatically pans based on mouse position pan_smoothness: 15, //int - determines smoothness of tracking pan animation (higher number = smoother) // filmstrip options start_frame: 1, //int - index of panel/frame to show first when gallery loads show_filmstrip: true, //boolean - flag to show or hide filmstrip portion of gallery show_filmstrip_nav: true, //boolean - flag indicating whether to display navigation buttons enable_slideshow: true, //boolean - flag indicating whether to display slideshow play/pause button autoplay: false, //boolean - flag to start slideshow on gallery load show_captions: false, //boolean - flag to show or hide frame captions filmstrip_size: 3, //int - number of frames to show in filmstrip-only gallery filmstrip_style: 'scroll', //string - type of filmstrip to use (scroll = display one line of frames, scroll filmstrip if necessary, showall = display multiple rows of frames if necessary) filmstrip_position: 'bottom', //string - position of filmstrip within gallery (bottom, top, left, right) frame_width: 80, //int - width of filmstrip frames (in pixels) frame_height: 40, //int - width of filmstrip frames (in pixels) frame_opacity: 0.4, //float - transparency of non-active frames (1.0 = opaque, 0.0 = transparent) frame_scale: 'crop', //string - cropping option for filmstrip images (same as above) frame_gap: 5, //int - spacing between frames within filmstrip (in pixels) // info bar options show_infobar: true, //boolean - flag to show or hide infobar infobar_opacity: 1 //float - transparency for info bar }; })(jquery);