1// Simple JavaScript Templating 2// John Resig - http://ejohn.org/ - MIT Licensed 3(function(){ 4 var cache = {}; 5 6 this.jrtmpl = function tmpl(str, data){ 7 // Figure out if we're getting a template, or if we need to 8 // load the template - and be sure to cache the result. 9 var fn = !/\W/.test(str) ? 10 cache[str] = cache[str] || 11 tmpl(document.getElementById(str).innerHTML) : 12 13 // Generate a reusable function that will serve as a template 14 // generator (and which will be cached). 15 new Function("obj", 16 "var p=[],print=function(){p.push.apply(p,arguments);};" + 17 18 // Introduce the data as local variables using with(){} 19 "with(obj){p.push('" + 20 21 // Convert the template into pure JavaScript 22 str 23 .replace(/[\r\t\n]/g, " ") 24 .split("<%").join("\t") 25 .replace(/((^|%>)[^\t]*)'/g, "$1\r") 26 .replace(/\t=(.*?)%>/g, "',$1,'") 27 .split("\t").join("');") 28 .split("%>").join("p.push('") 29 .split("\r").join("\\'") 30 + "');}return p.join('');"); 31 32 // Provide some basic currying to the user 33 return data ? fn( data ) : fn; 34 }; 35})(); 36 37/** 38 * jQuery Plugin to obtain touch gestures from iPhone, iPod Touch and iPad, should also work with Android mobile phones (not tested yet!) 39 * Common usage: wipe images (left and right to show the previous or next image) 40 * 41 * @author Andreas Waltl, netCU Internetagentur (http://www.netcu.de) 42 * @version 1.1.1 (9th December 2010) - fix bug (older IE's had problems) 43 * @version 1.1 (1st September 2010) - support wipe up and wipe down 44 * @version 1.0 (15th July 2010) 45 */ 46(function($){$.fn.touchwipe=function(settings){var config={min_move_x:20,min_move_y:20,wipeLeft:function(){},wipeRight:function(){},wipeUp:function(){},wipeDown:function(){},preventDefaultEvents:true};if(settings)$.extend(config,settings);this.each(function(){var startX;var startY;var isMoving=false;function cancelTouch(){this.removeEventListener('touchmove',onTouchMove);startX=null;isMoving=false}function onTouchMove(e){if(config.preventDefaultEvents){e.preventDefault()}if(isMoving){var x=e.touches[0].pageX;var y=e.touches[0].pageY;var dx=startX-x;var dy=startY-y;if(Math.abs(dx)>=config.min_move_x){cancelTouch();if(dx>0){config.wipeLeft()}else{config.wipeRight()}}else if(Math.abs(dy)>=config.min_move_y){cancelTouch();if(dy>0){config.wipeDown()}else{config.wipeUp()}}}}function onTouchStart(e){if(e.touches.length==1){startX=e.touches[0].pageX;startY=e.touches[0].pageY;isMoving=true;this.addEventListener('touchmove',onTouchMove,false)}}if('ontouchstart'in document.documentElement){this.addEventListener('touchstart',onTouchStart,false)}});return this}})(jQuery); 47 48 49/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 50* Licensed under the MIT License (LICENSE.txt). 51* 52* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 53* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 54* Thanks to: Seamus Leahy for adding deltaX and deltaY 55* 56* Version: 3.0.6 57* 58* Requires: 1.2.2+ 59*/ 60 61(function(d){var b=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks){for(var a=b.length;a;){d.event.fixHooks[b[--a]]=d.event.mouseHooks}}d.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var e=b.length;e;){this.addEventListener(b[--e],c,false)}}else{this.onmousewheel=c}},teardown:function(){if(this.removeEventListener){for(var e=b.length;e;){this.removeEventListener(b[--e],c,false)}}else{this.onmousewheel=null}}};d.fn.extend({mousewheel:function(e){return e?this.bind("mousewheel",e):this.trigger("mousewheel")},unmousewheel:function(e){return this.unbind("mousewheel",e)}});function c(j){var h=j||window.event,g=[].slice.call(arguments,1),k=0,i=true,f=0,e=0;j=d.event.fix(h);j.type="mousewheel";if(h.wheelDelta){k=h.wheelDelta/120}if(h.detail){k=-h.detail/3}e=k;if(h.axis!==undefined&&h.axis===h.HORIZONTAL_AXIS){e=0;f=-1*k}if(h.wheelDeltaY!==undefined){e=h.wheelDeltaY/120}if(h.wheelDeltaX!==undefined){f=-1*h.wheelDeltaX/120}g.unshift(j,k,f,e);return(d.event.dispatch||d.event.handle).apply(this,g)}})(jQuery); 62 63 64 65/** 66 * @author trixta 67 * @version 1.2 68 */
69(function(c){var b={pos:[-260,-260]},d=3,h=document,g=h.documentElement,e=h.body,a,i;function f(){if(this===b.elem){b.pos=[-260,-260];b.elem=false;d=3}}c.event.special.mwheelIntent={setup:function(){var j=c(this).bind("mousewheel",c.event.special.mwheelIntent.handler);if(this!==h&&this!==g&&this!==e){j.bind("mouseleave",f)}j=null;return true},teardown:function(){c(this).unbind("mousewheel",c.event.special.mwheelIntent.handler).unbind("mouseleave",f);return true},handler:function(j,k){var l=[j.clientX,j.clientY];if(this===b.elem||Math.abs(b.pos[0]-l[0])>d||Math.abs(b.pos[1]-l[1])>d){b.elem=this;b.pos=l;d=250;clearTimeout(i);i=setTimeout(function(){d=10},200);clearTimeout(a);a=setTimeout(function(){d=3},1500);j=c.extend({},j,{type:"mwheelIntent"});return c.event.dispatch.apply(this,arguments)}}};c.fn.extend({mwheelIntent:function(j){return j?this.bind("mwheelIntent",j):this.trigger("mwheelIntent")},unmwheelIntent:function(j){return this.unbind("mwheelIntent",j)}});c(function(){e=h.body;c(h).bind("mwheelIntent.mwheelIntentDefault",c.noop)})})(jQuery); 70 71/** 72 * jQuery Masonry v2.1.05 73 * A dynamic layout plugin for jQuery 74 * The flip-side of CSS Floats 75 * http://masonry.desandro.com 76 * 77 * Licensed under the MIT license. 78 * Copyright 2012 David DeSandro 79 */ 80(function(a,b,c){"use strict";var d=b.event,e;d.special.smartresize={setup:function(){b(this).bind("resize",d.special.smartresize.handler)},teardown:function(){b(this).unbind("resize",d.special.smartresize.handler)},handler:function(a,c){var d=this,f=arguments;a.type="smartresize",e&&clearTimeout(e),e=setTimeout(function(){b.event.dispatch.apply(d,f)},c==="execAsap"?0:100)}},b.fn.smartresize=function(a){return a?this.bind("smartresize",a):this.trigger("smartresize",["execAsap"])},b.Mason=function(a,c){this.element=b(c),this._create(a),this._init()},b.Mason.settings={isResizable:!0,isAnimated:!1,animationOptions:{queue:!1,duration:500},gutterWidth:0,isRTL:!1,isFitWidth:!1,containerStyle:{position:"relative"}},b.Mason.prototype={_filterFindBricks:function(a){var b=this.options.itemSelector;return b?a.filter(b).add(a.find(b)):a},_getBricks:function(a){var b=this._filterFindBricks(a).css({position:"absolute"}).addClass("masonry-brick");return b},_create:function(c){this.options=b.extend(!0,{},b.Mason.settings,c),this.styleQueue=[];var d=this.element[0].style;this.originalStyle={height:d.height||""};var e=this.options.containerStyle;for(var f in e)this.originalStyle[f]=d[f]||"";this.element.css(e),this.horizontalDirection=this.options.isRTL?"right":"left",this.offset={x:parseInt(this.element.css("padding-"+this.horizontalDirection),10),y:parseInt(this.element.css("padding-top"),10)},this.isFluid=this.options.columnWidth&&typeof this.options.columnWidth=="function";var g=this;setTimeout(function(){g.element.addClass("masonry")},0),this.options.isResizable&&b(a).bind("smartresize.masonry",function(){g.resize()}),this.reloadItems()},_init:function(a){this._getColumns(),this._reLayout(a)},option:function(a,c){b.isPlainObject(a)&&(this.options=b.extend(!0,this.options,a))},layout:function(a,b){for(var c=0,d=a.length;c<d;c++)this._placeBrick(a[c]);var e={};e.height=Math.max.apply(Math,this.colYs);if(this.options.isFitWidth){var f=0;c=this.cols;while(--c){if(this.colYs[c]!==0)break;f++}e.width=(this.cols-f)*this.columnWidth-this.options.gutterWidth}this.styleQueue.push({$el:this.element,style:e});var g=this.isLaidOut?this.options.isAnimated?"animate":"css":"css",h=this.options.animationOptions,i;for(c=0,d=this.styleQueue.length;c<d;c++)i=this.styleQueue[c],i.$el[g](i.style,h);this.styleQueue=[],b&&b.call(a),this.isLaidOut=!0},_getColumns:function(){var a=this.options.isFitWidth?this.element.parent():this.element,b=a.width();this.columnWidth=this.isFluid?this.options.columnWidth(b):this.options.columnWidth||this.$bricks.outerWidth(!0)||b,this.columnWidth+=this.options.gutterWidth,this.cols=Math.floor((b+this.options.gutterWidth)/this.columnWidth),this.cols=Math.max(this.cols,1)},_placeBrick:function(a){var c=b(a),d,e,f,g,h;d=Math.ceil(c.outerWidth(!0)/this.columnWidth),d=Math.min(d,this.cols);if(d===1)f=this.colYs;else{e=this.cols+1-d,f=[];for(h=0;h<e;h++)g=this.colYs.slice(h,h+d),f[h]=Math.max.apply(Math,g)}var i=Math.min.apply(Math,f),j=0;for(var k=0,l=f.length;k<l;k++)if(f[k]===i){j=k;break}var m={top:i+this.offset.y};m[this.horizontalDirection]=this.columnWidth*j+this.offset.x,this.styleQueue.push({$el:c,style:m});var n=i+c.outerHeight(!0),o=this.cols+1-l;for(k=0;k<o;k++)this.colYs[j+k]=n},resize:function(){var a=this.cols;this._getColumns(),(this.isFluid||this.cols!==a)&&this._reLayout()},_reLayout:function(a){var b=this.cols;this.colYs=[];while(b--)this.colYs.push(0);this.layout(this.$bricks,a)},reloadItems:function(){this.$bricks=this._getBricks(this.element.children())},reload:function(a){this.reloadItems(),this._init(a)},appended:function(a,b,c){if(b){this._filterFindBricks(a).css({top:this.element.height()});var d=this;setTimeout(function(){d._appended(a,c)},1)}else this._appended(a,c)},_appended:function(a,b){var c=this._getBricks(a);this.$bricks=this.$bricks.add(c),this.layout(c,b)},remove:function(a){this.$bricks=this.$bricks.not(a),a.remove()},destroy:function(){this.$bricks.removeClass("masonry-brick").each(function(){this.style.position="",this.style.top="",this.style.left=""});var c=this.element[0].style;for(var d in this.originalStyle)c[d]=this.originalStyle[d];this.element.unbind(".masonry").removeClass("masonry").removeData("masonry"),b(a).unbind(".masonry")}},b.fn.imagesLoaded=function(a){function h(){a.call(c,d)}function i(a){var c=a.target;c.src!==f&&b.inArray(c,g)===-1&&(g.push(c),--e<=0&&(setTimeout(h),d.unbind(".imagesLoaded",i)))}var c=this,d=c.find("img").add(c.filter("img")),e=d.length,f="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",g=[];return e||h(),d.bind("load.imagesLoaded error.imagesLoaded",i).each(function(){var a=this.src;this.src=f,this.src=a}),c};var f=function(b){a.console&&a.console.error(b)};
80b.fn.masonry=function(a){if(typeof a=="string"){var c=Array.prototype.slice.call(arguments,1);this.each(function(){var d=b.data(this,"masonry");if(!d){f("cannot call methods on masonry prior to initialization; attempted to call method '"+a+"'");return}if(!b.isFunction(d[a])||a.charAt(0)==="_"){f("no such method '"+a+"' for masonry instance");return}d[a].apply(d,c)})}else this.each(function(){var c=b.data(this,"masonry");c?(c.option(a||{}),c._init()):b.data(this,"masonry",new b.Mason(a,this))});return this}})(window,jQuery); 81 82/*! 83 * jQuery imagesLoaded plugin v1.0.4 84 * http://github.com/desandro/imagesloaded 85 * 86 * MIT License. by Paul Irish et al. 87 */ 88 89(function(a,b){a.fn.imagesLoaded=function(i){var g=this,e=g.find("img").add(g.filter("img")),c=e.length,h="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";function f(){i.call(g,e)}function d(j){if(--c<=0&&j.target.src!==h){setTimeout(f);e.unbind("load error",d)}}if(!c){f()}e.bind("load error",d).each(function(){if(this.complete||this.complete===b){var j=this.src;this.src=h;this.src=j}});return g}})(jQuery); 90 91/* 92 * Special event for image load events 93 * Needed because some browsers does not trigger the event on cached images. 94 95 * MIT License 96 * Paul Irish | @paul_irish | www.paulirish.com 97 98 * Andree Hansson | @peolanha | www.andreehansson.se 99 * 2010. 100 * 101 * Usage: 102 * $(images).bind('load', function (e) { 103 * // Do stuff on load 104 * }); 105 * 106 * Note that you can bind the 'error' event on data uri images, this will trigger when 107 * data uri images isn't supported. 108 * 109 * Tested in: 110 * FF 3+ 111 * IE 6-8 112 * Chromium 5-6 113 * Opera 9-10 114 */ 115 116 117(function($){ 118 119 PEXETO.share = { 120 121 facebook:function(url){ 122 return '<iframe src="//www.facebook.com/plugins/like.php?href='+encodeURIComponent(url)+'&send=false&layout=button_count&width=450&show_faces=true&action=like&colorscheme=light&font=arial&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:21px;" allowTransparency="true"></iframe>'; 123 }, 124 gplus:function(url, lang){ 125 return '<div class="g-plusone" data-size="medium" data-href="'+url+'"></div>\ 126 <script type="text/javascript" >\ 127 window.___gcfg = {lang: "'+lang+'"};\ 128 (function() {\ 129 var po = document.createElement("script"); po.type = "text/javascript"; po.async = true;\ 130 po.src = "https://apis.google.com/js/plusone.js";\ 131 var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(po, s);\ 132 })();\ 133 </script>' 134 }, 135 twitter:function(url, text){ 136 return '<iframe allowtransparency="true" frameborder="0" scrolling="no" src="https://platform.twitter.com/widgets/tweet_button.html?url='+encodeURIComponent(url)+'&counturl='+encodeURIComponent(url)+'&text='+encodeURIComponent(text)+'" style="width:130px; height:20px;"></iframe>' 137 }, 138 pinterest:function(url, image, title){ 139 return '<a href="http://pinterest.com/pin/create/button/?url='+encodeURIComponent(url)+'&media='+encodeURIComponent(image)+'&description='+encodeURIComponent(title)+'" class="pin-it-button" count-layout="horizontal"><img border="0" src="//assets.pinterest.com/images/PinExt.png" title="Pin It" /></a><script type="text/javascript" src="//assets.pinterest.com/js/pinit.js"></script>'; 140 } 141 }; 142 143})(jQuery); 144 145/** 146 * Rotation script. 147 * code from http://javascriptisawesome.blogspot.com.au/2011/09/jquery-css-rotate-and-animate-rotation.html 148 */ 149(function($){ 150 var _e = document.createElement("canvas").width 151 $.fn.cssrotate = function(d) { 152 return this.css({ 153 '-moz-transform':'rotate('+d+'deg)', 154 '-webkit-transform':'rotate('+d+'deg)', 155 '-o-transform':'rotate('+d+'deg)', 156 '-ms-transform':'rotate('+d+'deg)' 157 }).prop("rotate", _e ? d : null) 158 }; 159 var $_fx_step_default = $.fx.step._default; 160 $.fx.step._default = function (fx) { 161 if(fx.prop != "rotate")return $_fx_step_default(fx); 162 if(typeof fx.elem.rotate == "undefined")fx.start = fx.elem.rotate = 0; 163 $(fx.elem).cssrotate(fx.now) 164 }; 165})(jQuery); 166 167/** 168 * Fullscreen slider of images. Displays the images in full-width or full-height size of the window, with the following functionality enabled: 169 * - previous/next arrows for navigation 170 * - thumbnail tooltips for image preview on previous and next arrows 171 * - fullscreen button for displaying the image on the fullscreen without the additional elements such as header and footer 172 * - sharing functionality 173 * - close button 174 * - description for each image 175 * - image counter 176 * 177 * Dependencies: 178 * - imagesLoaded - Paul Irish 179 * - mousewheel - Brandon Aaron (http://brandonaaron.net) 180 * - mwheelintent - http://www.protofunc.com/scripts/jquery/mwheelIntent/ 181 * - jrtmpl - John Resig templating code 182 * - PEXETO.share - builds the sharing buttons code 183 * - touchwipe - Andreas Waltl (http://www.netcu.de) 184 * - Rotation script - http://javascriptisawesome.blogspot.com.au/2011/09/jquery-css-rotate-and-animate-rotation.html 185 * 186 * Events triggered on the root object 187 * - sliderImgLoaded - fired when the first image in the slider has been loaded and the slider is
187initialized 188 * - fullscreen - fired when the fullscreen mode is changed 189 * - nextItem - fired when the "Next Project" link was clicked (the initializator object should take care of showing the next item) 190 * - prevItem - fired when the "Previous Project" link was clicked (the initializator object should take care of showing the previous item) 191 * - imgRefresh - fired when something related with the image size and positioning is changed 192 * - closeSlider - fired when the close button is clicked (the initializator object should take care of hiding the slider ) 193 * 194 * @author Pexeto 195 * http://pexeto.com 196 */ 197(function( $ ) { 198 var sliderIndex = 0; 199 $.fn.pexetoFullscreenSlider = function( options ){ 200 201 var defaults={ 202 easing : "easeOutElastic", 203 animationSpeed : 400, 204 showThumbPreview : true, 205 fullscreen : false, //boolean setting the default fullscreen state (true if fullscreen) 206 showClose : true, //boolean setting whether to show the Close button or not 207 subtractElements : [], //array of jQuery objects whose height will be subtracted from the window height to set the image in full height (e.g. header, footer) 208 loadPortions : 5, //number of images to load on portions 209 210 //selectors and classes 211 leftArrowId : "preview-left-arrow", 212 rightArrowId : "preview-right-arrow", 213 arrowsClass : "preview-arrows", 214 sliderImagesClass : "slider-images", 215 previewContentClass : "preview-content", 216 imgWrapperClass : "slider-img-wrapper", 217 loadingClass : "slider-loading", 218 descriptionClass : "item-desc", 219 shareClass : "item-share", 220 countClass : "item-count", 221 closeClass : "close-btn", 222 fullsceenClass : "fullscreen-btn", 223 shareId : "share-container", 224 sharePointerClass : "share-pointer", 225 disabledArrowClass : "disabled" 226 }, 227 //define some helper variables that will be used globally by the plugin 228 o = $.extend(defaults, options), 229 $root = $(this), 230 item = o.item, 231 images = item.images, 232 imgNum = images.length, 233 $larrow = null, 234 $rarrow = null, 235 $larrowDiv = null, 236 $rarrowDiv = null, 237 $imageContainer = null, 238 $previewContent = null, 239 $descContainer = null, 240 $shareButton = null, 241 $shareContainer = null, 242 $countContainer = null, 243 $closeBtn = null, 244 $fullscreenBtn = null, 245 $lpreview = null, 246 $rpreview = null, 247 current = 0, 248 fullscreen = false, 249 inScreenAnimation = false, 250 inAnimation = false, 251 pendingImg = -1, 252 shareShow = false, 253 isIE8 = false, 254 isIdevice =(navigator.platform === 'iPad' || navigator.platform === 'iPhone' || navigator.platform === 'iPod')?true:false, 255 resizeArgs = {fullwidth:item.fullwidth, subtractElements:o.subtractElements, resizeParent:!isIdevice, imgLoaded:true, fullscreen:o.fullscreen, imgSelector:"."+o.imgWrapperClass}, 256 $nextTooltip = null, 257 $prevTooltip = null, 258 rRotated = false, //right arrow rotated 259 lRotated = false, //left arrow rotated 260 sharingButtons = [ 261 {name:"facebook", arg:[item.link]}, 262 {name:"twitter", arg:[item.link, o.texts.twitterText]}, 263 {name:"gplus", arg:[item.link, o.texts.gplusLang]}, 264 {name:"pinterest", arg:[item.link, item.images[0].img, item.title]} 265 ], 266 showShare = (o.excludeSharing.length===sharingButtons.length && !o.additionalButtons)?false:true, 267 //TEMPLATES 268 tmpl = { 269 previewContent : '<% if(showShare){ %><div class="'+o.shareClass+'">'+o.texts.shareText+'</div><% } %><div class="'+o.countClass+'"></div><div class="preview-description"><div class="item-title"><%= title %></div><div class="'+o.descriptionClass+'"></div></div>', 270 271 shareContent: '<div id="'+o.shareId+'"><ul></ul><div class="'+o.sharePointerClass+'"></div></div>' 272 }, 273 eventNs = "fs"+sliderIndex, 274 lastLoaded = 0, 275 iFullscreen = false; 276 277 /** 278 * Inits the main functionality - calls the initialization functions. 279 */
280 function init() { 281 sliderIndex++; 282 283 var parentClass = item.fullwidth ? "full-width" : "full-height", 284 removeClass = item.fullwidth ? "full-height" : "full-width"; 285 if(!o.showClose){ 286 parentClass+=' no-close'; 287 } 288 $root.removeClass(removeClass).addClass(parentClass); 289 if (o.fullscreen) { 290 fullscreen = true; 291 } 292 293 buildMarkup(); 294 295 addNavigation(); 296 loadSlider(); 297 loadNextImages(); 298 bindEventHandlers(); 299 300 } 301 302 /** 303 * Loads the slider once all the images are loaded. 304 */ 305 function loadSlider() { 306 $imageContainer.imagesLoaded(function () { 307 resizeArgs.subtractElements.push({ 308 el: $previewContent, 309 position: "Bottom" 310 }); 311 if (o.fullscreen) { 312 setOuterElementsPosition(false); 313 } 314 setDescription(0); 315 setCounter(0); 316 $root.trigger("sliderImgLoaded").pexetoResizableImg(resizeArgs); 317 $previewContent.css({ 318 bottom: 0 319 }); 320 refreshArrowState(false); 321 }); 322 } 323 324 /** 325 * Loads all the images: 326 * - creates an image element 327 * - binds on images loaded event 328 */ 329 function loadNextImages() { 330 var i, image, thumb, 331 len = (lastLoaded+o.loadPortions>=imgNum)?(imgNum-1):(lastLoaded+o.loadPortions); 332 for (i = lastLoaded+1; i <= len; i += 1) { 333 if(!images[i].loaded){ 334 image = new Image(); 335 thumb = null; 336 image.setAttribute("src", images[i].img); 337 338 //preload the thumbnail preview images 339 if (o.showThumbPreview) { 340 thumb = new Image(); 341 thumb.src = images[i].thumb; 342 } 343 344 (function (i) { 345 images[i].el = $('<div/>', { 346 "class": o.imgWrapperClass 347 }).append(image).imagesLoaded(function () { 348 images[i].loaded = true; 349 if (pendingImg === i) { 350 //image has been selected to show, but wasn't loaded yet 351 pendingImg = -1; 352 hideLoading(); 353 showImage(true); 354 } 355 }); 356 })(i); 357 } 358 } 359 360 lastLoaded = len; 361 } 362 363 /** 364 * Binds event handlers to the elements/ 365 */ 366 function bindEventHandlers() { 367 //MAIN ROOT EVENTS 368 $root.on("sliderVisible."+eventNs, function (e, args) { 369 //when the slider is visible, show the elements 370 $larrow.fadeIn(); 371 $rarrow.fadeIn(); 372 $previewContent.css({ 373 bottom: 0 374 }); 375 376 if(PEXETO.checkIfMobile() && PEXETO.mobileType==="iphone" && (window.orientation === -90 || window.orientation === 90) && !fullscreen){ 377 doOnToggleFullscreen(); 378 iFullscreen = true; 379 } 380 }).on("hide."+eventNs, hideElements) 381 .on("destroy."+eventNs, destroy); 382 383 //BUTTONS EVENTS 384 if (showShare) { 385 $shareButton.click(doOnShareClicked); 386 } 387 if (o.showClose) { 388 $closeBtn.on("click", doOnClose); 389 } 390 $fullscreenBtn.on("click", function(){ 391 iFullscreen = false; 392 doOnToggleFullscreen(); 393 }); 394 395 396 //NAVIGATION EVENTS 397 $larrow.on("click", doOnPreviousClicked).on("mouseenter", function () { 398 doOnArrowMouseEnter(false); 399 }).on("mouseleave", function () { 400 doOnArrowMouseLeave(false); 401 }); 402 $rarrow.on("click", doOnNextClicked).on("mouseenter", function () { 403 doOnArrowMouseEnter(true); 404 }).on("mouseleave", function () { 405 doOnArrowMouseLeave(true); 406 }); 407 408 $root.touchwipe({ 409 wipeLeft: doOnNextClicked, 410 wipeRight: doOnPreviousClicked 411 }); 412 413 $imageContainer.on("mousewheel", function (e, delta) { 414 e.preventDefault(); 415 if (delta < 0) { 416 doOnNextClicked(); 417 } else { 418 doOnPreviousClicked(); 419 } 420 }); 421 422 $(window).on("keydown."+eventNs, function(e){ 423 if(e.which===37){ 424 doOnPreviousClicked(); 425 }else if(e.which===39){ 426 doOnNextClicked(); 427 } 428 }); 429 430 if(o.showClose){ 431 $(window).on("popstate."+eventNs, doOnClose); 432 } 433 434 if(PEXETO.checkIfMobile() && PEXETO.mobileType==="iphone"){ 435 $(window).on("orientationchange."+eventNs, function(){ 436 if ((window.orientation === -90 || window.orientation === 90) && !fullscreen){ 437 iFullscreen = true; 438 doOnToggleFullscreen(); 439 }else if(window.orientation === 0 && iFullscreen && fullscreen){ 440 doOnToggleFullscreen(); 441 iFullscreen = false; 442 } 443 });
444 } 445 } 446 447 448 449 /*************************************************************************************************************** 450 * ELEMENT RENDERING FUNCTIONS 451 ***************************************************************************************************************/ 452 453 /** 454 * Builds the main slider markup. 455 */ 456 function buildMarkup() { 457 var $wrapDiv, img, addClass; 458 459 $imageContainer = $('<div />', { 460 "class": o.sliderImagesClass 461 }).appendTo($root); 462 //add the first image 463 $wrapDiv = $('<div/>', { 464 "class": o.imgWrapperClass 465 }); 466 img = new Image(); 467 img.setAttribute("src", images[0].img); 468 images[0].el = $wrapDiv; 469 470 $wrapDiv.append(img); 471 $imageContainer.append($wrapDiv); 472 473 //generate the content elements 474 $previewContent = $('<div />', { 475 "class": o.previewContentClass 476 }).appendTo($root); 477 $previewContent.append(jrtmpl(tmpl.previewContent, { 478 cat: (item.cat || ''), 479 title: item.title, 480 content: item.content, 481 showShare: showShare 482 })); 483 $descContainer = $previewContent.find("." + o.descriptionClass + ":first"); 484 485 //sharing functionality 486 if (showShare) { 487 $shareButton = $previewContent.find("." + o.shareClass + ":first"); 488 $previewContent.append(jrtmpl(tmpl.shareContent)); 489 $shareContainer = $('#' + o.shareId, $previewContent); 490 addSociableLinks(); 491 } 492 $countContainer = $previewContent.find("." + o.countClass + ":first"); 493 494 //buttons functionality 495 if (o.showClose) { 496 $closeBtn = $('<div />', { 497 "class": o.closeClass, 498 "title": o.texts.closeText 499 }).appendTo($root); 500 } 501 addClass = o.fullscreen ? " fullscreen-exit" : ""; 502 $fullscreenBtn = $('<div />', { 503 "class": o.fullsceenClass + addClass, 504 "title": o.texts.fullscreenText 505 }).appendTo($root); 506 507 $root.append($('<div />', { 508 "class": "clear" 509 })); 510 } 511 512 /** 513 * Adds the sociable buttons to the share container. 514 */ 515 function addSociableLinks() { 516 var $shareUl = $shareContainer.find('ul:first'), 517 i, len, sfn; 518 for (i = 0, len = sharingButtons.length; i < len; i += 1) { 519 sfn = PEXETO.share[sharingButtons[i].name]; 520 if ($.inArray(sharingButtons[i].name, o.excludeSharing) === -1) { 521 if (sfn && typeof sfn === "function") { 522 $shareUl.append('<li>' + sfn.apply(null, sharingButtons[i].arg) + '</li>'); 523 } 524 } 525 } 526 527 if (o.additionalButtons) { 528 $shareUl.append(o.additionalButtons); 529 } 530 } 531 532 /** 533 * Adds the navigation elements 534 */ 535 function addNavigation() { 536 var prevText = o.texts.prevProjectText.replace(" ", "<br/>"), 537 nextText = o.texts.nextProjectText.replace(" ", "<br/>"); 538 539 //previous/next arrows 540 $larrow = $('<div class="' + o.arrowsClass + '" id="' + o.leftArrowId + '"><div class="arrow"></div></div>').appendTo($root); 541 $rarrow = $('<div class="' + o.arrowsClass + '" id="' + o.rightArrowId + '"><div class="arrow"></div></div>').appendTo($root); 542 $larrowDiv = $larrow.find("div:first"); 543 $rarrowDiv = $rarrow.find("div:first"); 544 545 //previous project/next project tooltips 546 if (o.linkProjects) { 547 $nextTooltip = $('<div class="next-bubble"><span>' + nextText + '</span></div>').appendTo($rarrow); 548 $prevTooltip = $('<div class="prev-bubble"><span>' + prevText + '</span></div>').appendTo($larrow); 549 } 550 //previous image/next image preview tooltips 551 if (o.showThumbPreview) { 552 $lpreview = $("<div />", { 553 "class": "circle circle-preview prev-preview" 554 }).appendTo($larrow); 555 $rpreview = $("<div />", { 556 "class": "circle circle-preview next-preview" 557 }).appendTo($rarrow); 558 refreshPreviewImages(0); 559 } 560 } 561 562 563 /*************************************************************************************************************** 564 * EVENT HANDLER FUNCTIONS 565 ***************************************************************************************************************/ 566 567 /** 568 * On previous arrow click event handler. Shows the previous image if there is one or shows the "previous project" tooltip. 569 */ 570 function doOnPreviousClicked() { 571 if (!inAnimation) { 572 if (current !== 0) { 573 //show previous image 574 showImage(false); 575 } else { 576 //it's the first item, snow the previous project link 577 if (o.linkProjects && item.prevItem) { 578 showLoading(); 579 $root.trigger("prevItem"); 580 } 581 } 582 } 583 } 584 585 /** 586 * On next arrow click event handler. Shows the next image if there is one or shows the "next project" tooltip. 587 */ 588 function doOnNextClicked() { 589 if (!inAnimation) { 590 if ((current + 1) < imgNum) { 591 //show next image 592 if (images[current + 1].loaded) { 593 showImage(true); 594 } else { 595 pendingImg = current + 1; 596 showLoading(); 597 } 598 if(current+1 === lastLoaded && lastLoaded+1 < imgNum){ 599 loadNextImages(); 600 } 601 } else { 602 //it's the last item, show the next project link 603 if (o.linkProjects && item.nextItem) { 604 showLoading(); 605 $root.trigger("nextItem"); 606 } 607 } 608 } 609 } 610 611 /** 612 * On share link click event handler. Shows/hides the sharing buttons container. 613 */ 614 function doOnShareClicked() { 615 if (shareShow) { 616 //hide share container 617 $shareContainer.animate({ 618 bottom: '-=20', 619 opacity: 0 620 }, 300, function () { 621 $shareContainer.hide(); 622 shareShow = false; 623 }); 624 } else { 625 //show share container 626 $shareContainer.show().animate({ 627 bottom: '+=20', 628 opacity: 1 629 }, 300, function () { 630 shareShow = true; 631 }); 632 } 633 634 } 635 636 /** 637 * On previous/next arrow mouse enter evert handler. Depending on the current state and settings shows a preview of previous/next 638 * image preview. 639 * @param next boolean - if true next arrow is hovered, if false - previous arrow is hovered 640 */ 641 function doOnArrowMouseEnter(next) { 642 var $preview = next ? $rpreview : $lpreview, 643 last = (next && current === imgNum - 1) || (!next && current === 0) ? true : false; 644 645 if (!last) { 646 //show the preview image tooltip 647 $preview.stop().hide().fadeIn(); 648 } 649 650 if (o.linkProjects && last && !next && item.prevItem) { 651 //animate the "previous project" tooltip 652 $prevTooltip.stop().fadeIn(); 653 $larrowDiv.addClass('rotated'); 654 lRotated = true; 655 } 656 } 657 658 /** 659 * On previous/next arrow mouse leave evert handler. Depending on the current state and settings hides a preview of previous/next 660 * image preview. 661 * @param next boolean - if true next arrow is hovered, if false - previous arrow is hovered 662 */ 663 function doOnArrowMouseLeave(next) { 664 var $preview = null, 665 first = (!next && current === 0) ? true : false; 666 667 if (o.showThumbPreview) { 668 //hide the preview image tooltip 669 $preview = next ? $rpreview : $lpreview; 670 $preview.stop().fadeOut(); 671 } 672 673 if (o.linkProjects && first && item.prevItem) { 674 //animate the "previous project" tooltip 675 $prevTooltip.stop().show().fadeOut(); 676 if (lRotated) { 677 $larrowDiv.removeClass('rotated'); 678 } 679 } 680 } 681 682 683 /** 684 * On fullscreen button click event handler - toggles fullscreen mode. 685 */ 686 function doOnToggleFullscreen() { 687 if (!inScreenAnimation) { 688 inScreenAnimation = true; 689 fullscreen = !fullscreen;
690 $fullscreenBtn.toggleClass("fullscreen-exit"); 691 692 if (!fullscreen) { 693 //refresh the description and image counter 694 setDescription(current); 695 setCounter(current); 696 } 697 $root.trigger("fullscreen", [fullscreen]); 698 setOuterElementsPosition(true); 699 700 //set the root height 701 var windowHeight = $(window).height(), 702 h = 0, 703 i = o.subtractElements.length; 704 705 if (!fullscreen) { 706 while (i--) { 707 h += o.subtractElements[i].el.outerHeight(); 708 } 709 } 710 711 if (!isIdevice) { 712 $root.parent().animate({ 713 height: (windowHeight - h) 714 }); 715 } 716 $root.trigger("imgRefresh", [{animate:true}]); 717 $root.animate({ 718 height: (windowHeight - h) 719 }, function () { 720 inScreenAnimation = false; 721 }); 722 723 return $root; 724 } 725 } 726 727 728 /** 729 * On close button click event handler. Triggers a "closeSlider" event, if it is in fullscreen mode, first removes fullscreen mode. 730 */ 731 function doOnClose() { 732 if (fullscreen) { 733 doOnToggleFullscreen().promise().done(function () { 734 $root.trigger("closeSlider"); 735 }); 736 } else { 737 $root.trigger("closeSlider"); 738 $previewContent.fadeOut(); 739 } 740 } 741 742 743 /*************************************************************************************************************** 744 * ELEMENT/STATE CHANGING FUNCTIONS 745 ***************************************************************************************************************/ 746 747 /** 748 * Displays next or previous image. 749 * @param next boolean, if true - show next image, if false - show previous image 750 */ 751 function showImage(next) { 752 var frameWidth = $(window).width() + 10, 753 mult = next ? 1 : -1; //multiplier : makes the positioning values positive or negative, depending whether to show next image or previous image 754 inAnimation = true; 755 setDescription(current + mult); 756 setCounter(current + mult); 757 758 images[current].el.animate({ 759 left: -frameWidth * mult 760 }, o.animationSpeed, o.easing, function () { 761 $(this).detach(); 762 }); 763 current += mult; 764 if (o.showThumbPreview) { 765 refreshPreviewImages(current); 766 } 767 768 refreshArrowState(true); 769 770 //add the image and animate it 771 images[current].el.css({ 772 left: frameWidth * mult 773 }).appendTo($imageContainer).animate({ 774 left: 0 775 }, o.animationSpeed, o.easing, function () { 776 inAnimation = false; 777 }); 778 779 780 $root.trigger("imgRefresh"); 781 } 782 783 /** 784 * Sets the description of the image that has been selected. 785 * @param index the index of the image that is being displayed 786 */ 787 function setDescription(index) { 788 if (!fullscreen) { 789 var desc = images[index].desc ? '<span class="separator"></span>' + images[index].desc : ''; 790 $descContainer.html(desc); 791 } 792 793 } 794 795 796 /** 797 * Refreshes the image counter. 798 * @param index the index of the currently displayed image 799 */ 800 function setCounter(index) { 801 if (!fullscreen) { 802 $countContainer.html((index + 1) + "/" + imgNum); 803 } 804 } 805 806 /** 807 * Refreshes the arrows state regarding the previous/next project tooltips. 808 * @param both boolean setting whether to refresh both arrows. If false, will refresh only the "next" arrow 809 */ 810 function refreshArrowState(both) { 811 if (current === imgNum - 1) { 812 if(o.linkProjects && item.nextItem){ 813 //show the next project tooltip 814 $nextTooltip.fadeIn(); 815 $rarrowDiv.addClass('rotated'); 816 rRotated = true; 817 }else{ 818 $rarrowDiv.addClass(o.disabledArrowClass); 819 } 820 } else { 821 if(o.linkProjects && item.nextItem){ 822 //hide the next project tooltip 823 $nextTooltip.hide(); 824 if (rRotated) { 825 $rarrowDiv.removeClass('rotated'); 826 rRotated = false; 827 } 828 }else{ 829 $rarrowDiv.removeClass(o.disabledArrowClass); 830 } 831 } 832 if (current === 0) { 833 if(o.linkProjects && item.prevItem && both){ 834 //show the previous project tooltip 835 $prevTooltip.fadeIn(); 836 $larrowDiv.addClass('rotated'); 837 lRotated = true; 838 }else if(!o.linkProjects || !item.prevItem){ 839 $larrowDiv.addClass(o.disabledArrowClass); 840 } 841 } else { 842 if(o.linkProjects && item.prevItem && both){ 843 //hide the previous project tooltip 844 $prevTooltip.hide(); 845 if (lRotated) { 846 $larrowDiv.removeClass('rotated'); 847 lRotated = false; 848 } 849 }else{ 850 $larrowDiv.removeClass(o.disabledArrowClass); 851 } 852 } 853 } 854 855 /** 856 * Refreshes the small preview images that are displayed on arrow hover 857 * @param index - the index of the item according which the preview images should be changed 858 */ 859 function refreshPreviewImages(index) { 860 if (index + 1 < imgNum) { 861 $rpreview.html('<img src="' + images[index + 1].thumb + '" />'); 862 } else { 863 $rpreview.stop().fadeOut(); 864 } 865 866 if (index > 0) { 867 $lpreview.html('<img src="' + images[index - 1].thumb + '" />'); 868 } else { 869 $lpreview.fadeOut(); 870 } 871 } 872 873 /** 874 * Positions the elements around the slider according to the fullscreen mode. 875 */ 876 function setOuterElementsPosition(animate) { 877 var i, len, args, margin, el, sub; 878 for (i = 0, len = o.subtractElements.length; i < len; i += 1) { 879 el = o.subtractElements[i]; 880 args = {}; 881 sub = isIE8 ? 1 : 0; 882 args["margin" + o.subtractElements[i].position] = fullscreen ? (-o.subtractElements[i].el.outerHeight()) : 0; 883 884 if(fullscreen){ 885 margin = el.el.outerHeight()-sub; 886 args["margin" + el.position] = -margin; 887 if (animate) { 888 (function(el, margin){ 889 el.el.animate(args, function(){ 890 if(!isIE8){ 891 $(this).css({height:el.el.outerHeight(), overflow:"hidden"}); 892 } 893 });
894 }(el, margin)); 895 } else { 896 el.el.css(args); 897 } 898 }else{ 899 if(!isIE8){ 900 el.el.css({height:"auto", overflow:"visible"}); 901 } 902 args["margin" + el.position] = 0; 903 el.el.animate(args); 904 } 905 906 907 } 908 } 909 910 /** 911 * Hides the navigation elements and buttons. 912 */ 913 function hideElements() { 914 var elements = [$rarrow, $larrow, $closeBtn, $fullscreenBtn]; 915 $.each(elements, function (i, el) { 916 el.hide(); 917 }); 918 $previewContent.animate({ 919 opacity: 0 920 }); 921 } 922 923 function destroy(){ 924 hideLoading(); 925 $.removeData($root.get(0)); 926 $root.off("."+eventNs); 927 $(window).off("."+eventNs); 928 } 929 930 /** 931 * Displays a loader on the current image. 932 */ 933 function showLoading() { 934 images[current].el.append('<div class="' + o.loadingClass + '"></div>'); 935 } 936 937 /** 938 * Hides the loader on the current image. 939 */ 940 function hideLoading() { 941 images[current].el.find("." + o.loadingClass).remove(); 942 } 943 944 945 init(); 946 947 return $(this); 948 }; 949}( jQuery )); 950 951 952 953/** 954 * Portfolio grid gallery - displays the portfolio items separated in a grid structure. Provides different options for the 955 * gallery item clicking actions - open the image in lightbox, open a preview section with more images displayed in a slider, 956 * open a custom link, etc. 957 * Provides a category filter to display items by a selected category. 958 * All the functionality is executed via AJAX requests, there are no page reloads. 959 * 960 * Dependencies: 961 * - PEXETO - for general helper functions (by Pexeto) 962 * - pexetoFullscreenSlider - the horizontal slider functionality on image preview (by Pexeto) 963 * - jQuery imagesLoaded plugin v1.0.4 - http://github.com/desandro/imagesloaded 964 * - jQuery Masonry - http://masonry.desandro.com 965 * - jrtmpl - John Resig templating code 966 * 967 * @author Pexeto 968 * http://pexeto.com 969 */ 970(function($){ 971 $.fn.pexetoGridGallery=function(options){ 972 var defaults={ 973 //default settings 974 itemsPerPage : 15, //the number of items per page 975 showCategories : true, //if set to false, the categories will be hidden 976 easing : 'easeOutSine', //the animation easing 977 scrollEasing : 'easeOutExpo', //the easing of the scrolling animation in the preview slider section 978 imageWidth : 260, //the default image width 979 imageHeight : 160, //the default image height 980 itemMargin : 7, //the right margin of the items (space between the items) 981 category : -1, //category to load by default (-1 for all categories) 982 categories : [], //the categories that will be displayed in the filter 983 windowMargin : 7, //the sum of the window marging from left and right 984 orderBy : 'date', //the way the items should be ordered - available options: "date" and "custom" 985 //texts 986 texts : { 987 allText : 'ALL', 988 filterText : 'Filter', 989 loadMoreText : 'Load More', 990 closeText : 'Close', 991 fullscreenText : 'Fullscreen Mode', 992 shareText : 'Share' 993 }, 994 //selectors and class/id names 995 itemClass : 'content-box', //the class of the div that wraps each portfolio item data 996 itemInfoClass : 'content-box-content', 997 itemTextClass : 'content-box-text', 998 loadingClass : 'loading', 999 btnLoadingClass : 'btn-loading', 1000 galleryId : 'grid-gallery', 1001 categoryHolderId : 'portfolio-categories', 1002 selectedClass : 'selected', 1003 openedClass : 'filter-opened', 1004 filterBtnId : 'filter-btn', 1005 galleryContainerId : 'gallery-container', 1006 slideContainerId : 'gallery-slide-container', 1007 previewWrapperClass : 'slider-wrapper', 1008 backBtnClass : 'back-btn', 1009 backBtnEndClass : 'back-btn-end', 1010 itemLoadingClass : 'portfolio-loading' 1011 }, 1012 //define some helper variables that will be globally used within the plugin 1013 o = $.extend(defaults, options), 1014 $wrapper = $(this), 1015 $galleryContainer = $wrapper.find('#'+o.galleryContainerId), 1016 $previewWrapper = $('<div />', {"class":o.previewWrapperClass}).appendTo($wrapper), 1017 $previousWrapper = null, 1018 $filterBtn = null, 1019 $root = $('<div/>', {'id':o.galleryId}).appendTo($galleryContainer), 1020 items = [], //will contain all the portfolio items 1021 itemsMap = [], 1022 cachedItems = [], 1023 $moreBtn = null, //the "Load More" button element 1024 $catHolder = null, //the category filter holder 1025 currentCat = o.category, //the ID of the current selectec category 1026 windowWidth = $(window).width(), 1027 currentItem = null, 1028 previewMode = false, //a boolean setting whether a preview content section is displayed
1029 currentXhr = null, 1030 inLoading = false, 1031 galleryLoaded = false, 1032 isIdevice = (navigator.platform === 'iPad' || navigator.platform === 'iPhone' || navigator.platform === 'iPod')?true:false, 1033 isIe = false, 1034 isIE8 = false, 1035 tmpl = {}, 1036 nextPending = false, //will be set to true when next project is about to load in slider 1037 prevPending = false, //will be set to true when previous project is about to load in slider 1038 wrapperLoaded = true, 1039 filterDisplayed = false, //the state of the category filter - true for displayed and false for hidden 1040 filterInAnimation = false, //a boolean setting whether the filter has been currently animated 1041 fullscreen = false, 1042 galleryUrl = '', 1043 supportsHistory = (window.history && window.history.pushState) ? true : false; 1044 1045 1046 /** 1047 * Initializes the main functionality - calls the main functions. 1048 */ 1049 function init() { 1050 1051 setTemplates(); 1052 bindEventHandlers(); 1053 1054 $moreBtn = $(jrtmpl(tmpl.morebtn, { 1055 text: o.texts.loadMoreText 1056 })); 1057 1058 1059 var item = null, 1060 itemToLoad = getItemFromHash(); 1061 1062 if (itemToLoad) { 1063 //load an item slider 1064 item = { 1065 slug: itemToLoad, 1066 slider: true 1067 }; 1068 currentItem = item; 1069 loadItemContent(item); 1070 galleryUrl = window.location.href.split('#')[0]; 1071 } else { 1072 //load the gallery 1073 loadGallery(); 1074 } 1075 1076 } 1077 1078 /** 1079 * Checks the URL hash for item slug. 1080 * @return the item's slug if it exists or false if it doesn't 1081 */ 1082 function getItemFromHash() { 1083 var hash = location.hash.replace('#!', ''); 1084 1085 if (o.itemSlug) { 1086 return o.itemSlug; 1087 } 1088 if (hash && hash.indexOf('prettyPhoto') === -1) { 1089 return hash; 1090 } 1091 return false; 1092 } 1093 1094 1095 /** 1096 * Sets the main templates for element markup generation. 1097 */ 1098 function setTemplates() { 1099 tmpl = { 1100 morebtn: '<div class="more-container"><a id="loadMore" class="button"><span><%= text %></span></a></div>', 1101 1102 //CATEGORIES FILTER 1103 categories: '<ul>\ 1104 <li class="' + o.selectedClass + '" data-cat="' + o.category + '">' + o.texts.allText + '</li>\ 1105 <% for(var i=0, len=categories.length; i<len; i++){ %>\ 1106 <li data-cat="<%=categories[i].id%>"><span class="cat-separator">/</span><%=categories[i].name%></li>\ 1107 <% } %></ul>', 1108 1109 //ITEM IMAGE TEMPLATE 1110 item: '<div class="' + o.itemClass + '" style="width:<%= width %>px;">\ 1111 <img src="<%= item.image %>" width="<%=width%>"/>\ 1112 <div class="' + o.itemInfoClass + '"><div class="' + o.itemTextClass + '">\ 1113 <% if(item.link){ %><a href="<%= link %>" rel="<%= rel %>" title="<%= title %>"><% } %>\ 1114 <div class="text-wrapper">\ 1115 <% if(item.cat){ %>\ 1116 <h3 class="post-info"><%=item.cat%></h3>\ 1117 <% } %>\ 1118 <h2><%= item.title %></h2></div><div class="view-gallery">\ 1119 <% if(item.imgnum){ %><span class="item-num"><%= item.imgnum %></span><% } %>\ 1120 <span class="grid-gallery-icon<%= additionalClass %>"></span><span class="view-text"><%= viewText %><span class="more-arrow">»</span></span>\ 1121 </div><% if(item.link){ %></a><% } %>\ 1122 </div></div>\ 1123 </div>' 1124 }; 1125 } 1126 1127 /** 1128 * Loads the gallery - calls all the main functions to load and build the gallery. 1129 */ 1130 function loadGallery() { 1131 if(supportsHistory){ 1132 galleryUrl = galleryUrl || window.location.href; 1133 history.pushState(null, null, galleryUrl); 1134 } 1135 if (o.showCategories) { 1136 displayCategoryFilter(); 1137 } 1138 loadImages({}); 1139 bindGalleryEventHandlers(); 1140 1141 //initialize the Masonry script to order the items one below another 1142 $root.masonry({ 1143 itemSelector: '.' + o.itemClass, 1144 isAnimated: true, 1145 columnWidth: getImageWidthForScreen 1146 }); 1147 galleryLoaded = true; 1148 } 1149 1150 /** 1151 * Binds event handlers for the preview slider only. 1152 */ 1153 function bindEventHandlers() { 1154 $wrapper.on("sliderImgLoaded", "." + o.previewWrapperClass, doOnSliderImgLoaded) 1155 .on("closeSlider", "." + o.previewWrapperClass, doOnCloseClicked) 1156 .on("nextItem", "." + o.previewWrapperClass, function() { 1157 doOnLoadNewItem(true); 1158 }).on("prevItem", "." + o.previewWrapperClass, function() { 1159 doOnLoadNewItem(false); 1160 }).on("fullscreen", "." + o.previewWrapperClass, function(e, full) { 1161 fullscreen = full; 1162 }); 1163 } 1164 1165 /** 1166 * Binds event handlers to the elements in the gallery. 1167 */ 1168 function bindGalleryEventHandlers() { 1169 //the hover effect of the items 1170 $root.delegate('.' + o.itemClass, 'mouseenter', doOnItemMouseEnter); 1171 $root.delegate('.' + o.itemClass, 'mouseleave', doOnItemMouseLeave); 1172 1173 $moreBtn.find('a').on('click', doOnMoreBtnClick); 1174 1175 if (o.showCategories) { 1176 $catHolder.delegate('li', 'click', doOnCategoryClick); 1177 } 1178 $(window).on("resize", setFilterVisibility); 1179 } 1180 1181 eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('4 T(2){b d=2.k,i,7,5,$9;t(i=0,7=d.c;i<7;i+=1){5=d[i];$9=1o(5);5.9=d.9=$9;k.f(5);3(5.H||(5.17&&!5.1p)){1q(5)}$8.1n($9)}12.1m($8.1i("a[1j^=\'17\']"));3(!1k){12.1l()}$8.1r(4(){b i,7,q;Q();$B.1s();$8.D(\'z\').1h(\'1A\');q=4(i){d[i].9.1B({n:0,1y:\'1x\',E:L}).v({n:1,E:0},1t,o.16,4(){3(i===7-1){$8.D("z");
11813(2.1u){$B.1v($8)}}})};t(i=0,7=d.c;i<7;i+=1){(4(i){1w.1C(4(){q(i)},i*L)})(i)}})}4 1g(2){b x=[],y=[],s=[],i,7;t(i=0,7=2.p.c;i<7;i+=1){x.f("");y.f(2.p[i].1f);s.f(2.p[i].1d)}$.1e.1z(s,x,y)}4 1J(2){b e=22(2),r;3(e.m){2.m=O.m=e.m}3(e.l){2.l=O.l=e.l}r={16:o.23,18:o.18,21:[{9:$(\'#20\'),1X:"1Y"}],5:2,A:o.A,C:o.C,S:o.S,P:o.P,Z:o.Z,N:o.N,M:M};$25.24(r)}4 28(h){1D=j;$8.v({n:0},4(){$8.29().v({n:1},0);$26.27(o.2a);k=[];Y({h:h})})}4 1Z(5){b 2={W:o.V,1V:5.U,1c:\'1W\'},w=5.H?j:1K,u=1L(5.U);3(u){19(w,u);1I}3(!6.c){2.6="j";2.h=o.10;2.14=o.13}3(!g){g=$.J({R:o.K,2:2,1b:\'I\',11:\'X\'}).1a(4(2){3(2&&!2.1H){3(2.6){6=2.6}1E.f(2);19(w,2)}F{3(!1F){g=1G;1M()}}})}}4 Y(G){b 2={W:o.V,h:o.10,14:o.13,1N:0,1T:o.1U,1S:o.1R,15:o.15,1c:\'1O\'};3(!6.c){2.6="j"}2=$.1P(2,G);3(!g){g=$.J({R:o.K,2:2,1b:\'I\',11:\'X\'}).1a(4(2){3(2.6){6=2.6}3(2.k.c){T(2)}F{Q()}}).1Q(2b)}}',62,136,'||data|if|function|item|itemsMap|len|root|el||var|length|newItems|itemLinks|push|currentXhr|cat||true|items|prevItem|nextItem|opacity||images|displayItem|args|srcs|for|cachedItem|animate|loadSlider|titles|descs|reload|texts|moreBtn|excludeSharing|masonry|marginTop|else|options|slider|json|ajax|ajaxUrl|100|fullscreen|showThumbPreview|currentItem|showClose|removeLoading|url|additionalButtons|printItems|slug|itemsPerPage|number|GET|loadImages|linkProjects|category|type|PEXETO|orderBy|orderby|itemMargin|easing|lightbox|fullwidth|doOnContentLoaded|done|dataType|action|img|prettyPhoto|desc|loadLightbox|trigger|find|rel|isIE8|loadCufon|setLightbox|append|renderItemElement|video|bindItemClickHandler|imagesLoaded|detach|300|more|insertAfter|window|visible|visibility|open|itemsLoaded|css|setTimeout|inLoading|cachedItems|galleryLoaded|null|failed|return|initItemSlider|false|getCachedItem|loadGallery|offset|pexeto_get_portfolio_items|extend|always|imageHeight|imgheight|imgwidth|imageWidth|itemslug|pexeto_get_portfolio_content|position|Top|loadItemContent|header|subtractElements|getItemLinks|scrollEasing|pexetoFullscreenSlider|previewWrapper|wrapper|addClass|filterItems|empty|loadingClass|doOnAjaxComplete'.split('|'),0,{})) 1182 1183 1184 /***************************************************************************************** 1185 * ELEMENT RENDERING FUNCTIONS 1186 ****************************************************************************************/ 1187 1188 /** 1189 * Renders the HTML of each of the items depending on the settings. 1190 * @return the item as jQuery object 1191 */ 1192 function renderItemElement(item) { 1193 var rel = item.video ? 'lightbox' : '', 1194 link = (item.slider && !supportsHistory) ? '#!' + item.slug : item.link, 1195 desc = item.desc || "", 1196 html = "", 1197 additionalClass = '', 1198 viewText = o.texts.viewGalleryText; 1199 if (item.video) { 1200 viewText = o.texts.playVideoText; 1201 additionalClass = " video-icon"; 1202 } else if (!item.slider && !item.video && !item.lightbox) { 1203 viewText = o.texts.openText; 1204 additionalClass = " link-icon"; 1205 } 1206 1207 html = jrtmpl(tmpl.item, { 1208 item: item, 1209 width: o.imageWidth, 1210 link: link, 1211 rel: rel, 1212 title: desc, 1213 viewText: viewText, 1214 additionalClass: additionalClass 1215 }); 1216 return $(html); 1217 } 1218 1219 /** 1220 * Renders the category filter element and appends it to the gallery container. 1221 */ 1222 function displayCategoryFilter() {
1223 var $filterContainer = $('<div id="filter-container"></div>'), 1224 catHtml = jrtmpl(tmpl.categories, { 1225 categories: o.categories 1226 }); 1227 $filterBtn = $('<div />', { 1228 "id": o.filterBtnId, 1229 "html": "<span>" + o.texts.allText + "</span>" 1230 }).click(doOnFilterClick).appendTo($filterContainer); 1231 $catHolder = $('<div />', { 1232 "id": o.categoryHolderId, 1233 "html": catHtml 1234 }).appendTo($filterContainer); 1235 1236 $galleryContainer.prepend($filterContainer); 1237 } 1238 function abortPendingRequests() { 1239 if (currentXhr) { 1240 //there is a request pending, abort it and execute this one 1241 currentXhr.abort(); 1242 if (currentItem) { 1243 removeItemLoading(currentItem.el); 1244 } 1245 } 1246 } 1247 1248 /***************************************************************************************** 1249 * EVENT BINDING AND HANDLER FUNCTIONS 1250 ****************************************************************************************/ 1251 1252 eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('3 2A(25,k){4(25){4(k.G){6.G=k.G}4(k.H){6.H=k.H}4(k.13){6.13=k.13}2l(k);1o=g}v{2j(k);1y(6.d)}22()}3 2o(){u m;1V=$(12).7(),O=2p,L=10;4(!2q){1T.2r()}4(1a){m=$n.z();14(6);$l.b("1b",[{1Z:g}]).f({m:0},O,o.J);$n.b("V").r({7:\'11%\',1e:L}).f({m:(-m-L)},O,o.J,3(){$n.b("1n").1w();U=g});1a=D}v 4(1t){14(6,{2n:g});m=$n.z();$n.b("V");$l.r({m:(-m-L),1e:L}).f({m:0},O,o.J,3(){$n.b("1n").1w();U=g}).b("1b",[{1Z:g}]);1t=D}v{28();4(6.d){1y(6.d)}$(\'#1F\').V();18();$Y.f({1C:-1V-2k},1B,o.J,3(){$(B).f({z:\'V\'});$l.b("1b",[{}]);16()})}}3 2m(){1R($(B).a(\'.\'+o.1E),1)}3 2i(){4(!$(B).a(\'.\'+o.1p).C&&!1T.2s()){26($(B).a(\'.\'+o.1E),0)}}3 2t(){u M=$(B),q=1I(M.k(\'q\')),1k=o.2z.2B;1g();4(N!==q){N=q;2y(q);M.1q(o.1f).2x(\'.\'+o.1f).1x(o.1f);$1r.2u();4(q!==-1){1k=1s.a(o.2v,3(c){K 1I(c.2w)===q}).2C}$T.a("2f:2a").2b(1k);4($T.r("2c")!=="2e"){$T.b("1L")}}}3 2d(24){4(!S&&U){u 8="";U=D;S=g;$n=$l;$l=$(\'<1j />\',{"1J":o.2h});4(24){$l.2g($n);1a=g;8=6.G}v{$l.2K($n);1t=g;8=6.H}6={8:8,1Q:g};1M(6)}}3 33(){u M=$(B),1m=1i?0:10;4(!1h){1h=g;$T.34().f({m:1m,1e:1m});M.32(o.31);$1d.2Y(2Z,\'36\',3(){1h=D;1i=!1i})}}3 35(){1g();$1r.1q(o.1S);3b({3a:s.C,q:N})}3 37(5){5.d.1L(3(e){e.39();4(5.1Q){14(5)}1g();4(!1o&&!S){5.d.38(\'<1j 1J="\'+o.1p+\'"></1j>\');6=5;1M(5)}})}3 3c(){4(1Y){12.1U.21(P,P,30)}v{1D.29=\'\'}4(6&&6.d){6.d.a(\'1z\').b("1G")}18();1o=D;$I.r({z:"1c"});$(\'#1F\').2D();$Y.1N().f({1C:0,9:1},1B,o.J,3(){16();$l.b("1n").2J("2X","").2L()});4(2I){$2H.2E(\'2F\')}v{27();2G()}}3 22(){S=D;2M=P}3 18(){u W=$(12).7();$I.7(2*W);$l.r({7:W});$Y.7(W)}3 16(){$I.r({7:\'11%\'});$l.r({7:\'11%\'});$Y.r({7:\'11%\'})}3 2N(X){u t=0,R=0,1l=0,A,i,j,F,Q,w,h;t=19.17(X/o.Z);R=X-t*(o.Z-o.y);4(R>0){A=0;4(!(t===1&&o.Z/2>R)){t+=1}A=19.17(X/t)-o.y;1l=o.Z/A;1A(i=0,j=s.C;i<j;i+=1){F=s[i].F;Q=s[i].Q;w=A;h=0;4(F>1&&t>1){w=(A+o.y)*F-o.y}s[i].d.7(w).a("1z").7(w);s[i].d.7(w).a(".1W-1X").7(w);4(o.23!=="1c"){h=t===1?"1c":(19.17(o.23/1l)+o.y)*Q-o.y;s[i].d.z(h).a("1z").z(h);s[i].d.7(w).a(".1W-1X").z(h)}}}K A+o.y}3 2T(8){u 1u=P,i,j;1A(i=0,j=1v.C;i<j;i+=1){4(1v[i].8===8){1u=1v[i];20}}K 1u}3 2U(5){u p=[],x=-1,i,j=0,15={};4(N!==-1){p=1s.2V(1H,3(1K){K 1s.2S(1K.q,N)!==-1})}p=p.C?p:1H;j=p.C;1A(i=0;i<j;i+=1){4(p[i].8===5.8){x=i;20}}4(x!==-1){4(x+1<j){15.G=p[x+1].8}4(x!==0){15.H=p[x-1].8}}K 15}3 14(5,2R){4(1Y){1U.21({2O:5.8},5.2P,5.13)}v{1D.29=\'!\'+5.8}}3 2W(){4($(12).7()>2Q&&$1d){$1d.1N()}}3 1y($5){$5.a(\'.\'+o.1p).1w();$5.b("1G")}3 28(){$I.1x(o.1P);$1r.1x(o.1S)}3 27(){$I.1q(o.1P)}3 1R($E,9){9=9||1;$E.1O().f({9:1},3(){$E.f({9:9},0)})}3 26($E,9){$E.1O().f({9:9},3(){$E.f({9:9},0)})}',62,199,'|||function|if|item|currentItem|width|slug|opacity|find|trigger||el||animate|true|||len|data|previewWrapper|marginTop|previousWrapper||filtItems|cat|css|items|numColumns|var|else||itemIndex|itemMargin|height|newImgW|this|length|false|elem|col|nextItem|prevItem|wrapper|easing|return|marg|that|currentCat|sp|null|row|spaceLeft|inLoading|filterBtn|wrapperLoaded|hide|winWidth|containerWidth|galleryContainer|imageWidth||100|window|link|setUrl|res|resetWrappersSize|floor|setWrappersSize|Math|nextPending|sliderVisible|auto|catHolder|marginBottom|selectedClass|abortPendingRequests|filterInAnimation|filterDisplayed|div|catName|ratio|margin|destroy|previewMode|itemLoadingClass|addClass|moreBtn|_|prevPending|cachedItem|cachedItems|remove|removeClass|removeItemLoading|img|for|800|marginLeft|location|itemTextClass|footer|mou
1252seleave|itemsMap|Number|class|it|click|loadItemContent|show|stop|loadingClass|slider|elemFadeIn|btnLoadingClass|PEXETO|history|windowWidth|no|color|supportsHistory|staticDesc|break|replaceState|doOnAjaxComplete|imageHeight|next|loadSlider|elemFadeOut|addLoading|removeLoading|hash|first|html|display|doOnLoadNewItem|none|span|insertAfter|previewWrapperClass|doOnItemMouseLeave|loadLightbox|50|initItemSlider|doOnItemMouseEnter|replace|doOnSliderImgLoaded|600|isIE8|loadCufon|checkIfMobile|doOnCategoryClick|detach|categories|id|siblings|filterItems|texts|doOnContentLoaded|allText|name|fadeIn|masonry|reload|loadGallery|root|galleryLoaded|attr|insertBefore|empty|currentXhr|getImageWidthForScreen|state|title|490|options|indexOf|getCachedItem|getItemLinks|filter|setFilterVisibility|style|slideToggle|200|galleryUrl|openedClass|toggleClass|doOnFilterClick|parent|doOnMoreBtnClick|linear|bindItemClickHandler|append|preventDefault|offset|loadImages|doOnCloseClicked'.split('|'),0,{})) 1253 1254 1255 init(); 1256 1257 }; 1258}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.