martes, 27 de noviembre de 2012

Una Galería de Imágenes con Paginación





Hace poco veíamos cómo agregar una galería de imágenes a una página estática del blog. Alguien me comentaba que le gustaría mostrar la galería con paginación, ya que pensaba mostrar muchas imágenes. Eso es posible gracias a  jPages, un plugin para jQuery que permite mostrar contenido paginado.



Vamos a usar jPages con el segundo ejemplo que veíamos en el post mencionado. Pensando en que vas a poner la galería en una página estática, te recomiendo ámpliamente ver la explicación del post mencionado para poder ver más detalles.

También vamos a agregar una animación con CSS al cargarse la página con la galería, usando la librería de Animate:css (una libreria fantástica de animaciones con CSS3), que también usan en las demostraciones del plugin y que puede integrarse fácilmente a éste.



Este plugin también puede integrarse con lazy load, de ese modo las imágenes cargarán según el usuario vaya viendo el contenido. Detalles de cómo implementarlo se pueden ver en la página del plugin, de cualquier modo, publicaré otra entrada para explicar cómo implementarlo.











Cómo agregar la galería al blog  (en una página estática)




1. Primero agregas el CSS de la galería y el CSS para la navegación del plugin, en Añadir CSS del diseñador de plantillas:


/*Galeria */

ul.galeria2{

width:100%;

margin:10px 5px;

padding:0}

ul.galeria2 li{

height:160px; /*el mismo alto que la imagen*/                                                  width:200px;  /*el mismo ancho que la imagen*/

display:block;

margin:0 3px 5px 0; /* separación de cada elemento*/

padding:0;

float:left;

list-style:none;

position:relative;

overflow:hidden;}

 

ul.galeria2 a{

background:none;

margin:0;

padding:0;

color:#fff;

text-align:center;

white-space:nowrap;}

ul.galeria2  li img{                                                                                                                  width:200px;  /*ancho de la imagen*/                                                                                                    height:160px; /*alto de la imagen*/                                                                           margin:0;

padding:0;

border:none;

}

ul.galeria2 span{

width:200px; /*el mismo ancho de la imagen*/

left:1px; /*el mismo ancho que el borde*/                                                                      margin:0;

padding:3px 0 3px 0;

background:#000;

bottom:-8px;

left:0px; filter:alpha(opacity=0);

opacity:0;

overflow:hidden;

cursor:pointer; position:absolute;

-webkit-transition:all .25s ease; -moz-transition:all .25s ease; -o-transition:all .25s ease; transition:all .25s ease;}

ul.galeria2  a:hover span{ left:0; bottom:0; opacity:.9;filter:alpha(opacity=90)}

ul.galeria2  a span:hover{color:#cec20b} /*color fuente al poner el puntero encima*/

                                                                                                                /*Navegacion CSS*/

.holder {

margin: 15px 0;

}

.holder a {

font-size: 12px;

cursor: pointer;

margin: 0 5px;

color: #333;

}

.holder a:hover {

background-color: #222;

color: #fff;

}

.holder a.jp-previous { margin-right: 15px; }

.holder a.jp-next { margin-left: 15px; }

.holder a.jp-current, a.jp-current:hover {

color: #FF4242;

font-weight: bold;

}

.holder a.jp-disabled, a.jp-disabled:hover {

color: #bbb;

}

.holder a.jp-current, a.jp-current:hover,

.holder a.jp-disabled, a.jp-disabled:hover {

cursor: default;

background: none;

}

.holder span { margin: 0 5px; }






Agregar la animación con CSS cuando se carga la galería.




2. Si vas a  agregar la animación con CSS de la demostración al cargarse la página, habrá que agregar el CSS de la misma, debajo del CSS anterior.




/*Animate.css - http://daneden.me/animateLICENSED UNDER THE  MIT LICENSE (MIT)Copyright (c) 2011 Dan Eden*/           .animated{-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:1s;-moz-animation-duration:1s;-ms-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s}

.animated.hinge{-webkit-animation-duration:2s; -moz-animation-duration:2s; -ms-animation-duration:2s; -o-animation-duration:2s; animation-duration:2s}
@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.3)}50%{opacity:1;-webkit-transform:scale(1.05)}70%{-webkit-transform:scale(.9)}100%{-webkit-transform:scale(1)}}@-moz-keyframes bounceIn{0%{opacity:0;-moz-transform:scale(.3)}50%{opacity:1;-moz-transform:scale(1.05)}70%{-moz-transform:scale(.9)}100%{-moz-transform:scale(1)}}@-o-keyframes bounceIn{0%{opacity:0;-o-transform:scale(.3)}50%{opacity:1;-o-transform:scale(1.05)}70%{-o-transform:scale(.9)}100%{-o-transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.05)}70%{transform:scale(.9)}100%{transform:scale(1)}}.bounceIn{-webkit-animation-name:bounceIn;-moz-animation-name:bounceIn;-o-animation-name:bounceIn;animation-name:bounceIn;}



Nota: El plugin tiene una animación que si funciona en Internet Explorer, que parece como desvanecimiento en las imágenes al cargar cada página, y la puedes ver funcionando en esta página, por lo que, si no usas la animación con CSS3 de la librería, la galería tendrá ese efecto.  



3. Luego, vas a la edición de HTML de la plantilla, y agregas jQuery (via Google) antes de </head>, si es que no lo usas en el blog.




<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'></script>



 4. Después, agregas el archivo con el plugin, que alojarás en un sitio de confianza, y que puedes descargar desde la página.





<script type='text/javascript' src='//mi-archivo.js'></script>



O bien, lo agregas directamente en la plantilla, debajo de jQuery:



<script type="text/javascript">

//<![CDATA[                                                    

/**

 * jQuery jPages v0.7

 * Client side pagination with jQuery

 * http://luis-almeida.github.com/jPages

 *

 * Licensed under the MIT license.

 * Copyright 2012 Luís Almeida

 * https://github.com/luis-almeida

 */



 ;(function($,window,document,undefined){var name="jPages",instance=null,defaults={containerID:"",first:false,previous:" previous",next:"next",last:false,links:"numeric",startPage:1,perPage:10,midRange:5,startRange:1,endRange:1,keyBrowse:false,scrollBrowse:false,pause:0,clickStop:false,delay:50,direction:"forward",animation:"",fallback:400,minHeight:true,callback:undefined};function Plugin(element,options){this.options=$.extend({},defaults,options);this._container=$("#"+this.options.containerID);if(!this._container.length)return;this.jQwindow=$(window);this.jQdocument=$(document);this._holder=$(element);this._nav={};this._first=$(this.options.first);this._previous=$(this.options.previous);this._next=$(this.options.next);this._last=$(this.options.last);this._items=this._container.children(":visible");this._itemsShowing=$([]);this._itemsHiding=$([]);this._numPages=Math.ceil(this._items.length/this.options.perPage);this._currentPageNum=this.options.startPage;this._clicked=false;this._cssAnimSupport=this.getCSSAnimationSupport();this.init();}Plugin.prototype={constructor:Plugin,getCSSAnimationSupport:function(){var animation=false,animationstring='animation',keyframeprefix='',domPrefixes='Webkit Moz O ms Khtml'.split(' '),pfx='',elm=this._container.get(0);if(elm.style.animationName)animation=true;if(animation===false){for(var i=0;i<domPrefixes.length;i++){if(elm.style[domPrefixes[i]+'AnimationName']!==undefined){pfx=domPrefixes[i];animationstring=pfx+'Animation';keyframeprefix='-'+pfx.toLowerCase()+'-';animation=true;break;}}}return animation;},init:function(){this.setStyles();this.setNav();this.paginate(this._currentPageNum);this.setMinHeight();},setStyles:function(){var requiredStyles="<style>"+".jp-invisible { visibility: hidden !important; } "+".jp-hidden { display: none !important; }"+"</style>";$(requiredStyles).appendTo("head");if(this._cssAnimSupport&&this.options.animation.length)this._items.addClass("animated jp-hidden");else this._items.hide();},setNav:function(){var navhtml=this.writeNav();this._holder.each(this.bind(function(index,element){var holder=$(element);holder.html(navhtml);this.cacheNavElements(holder,index);this.bindNavHandlers(index);this.disableNavSelection(element);},this));if(this.options.keyBrowse)this.bindNavKeyBrowse();if(this.options.scrollBrowse)this.bindNavScrollBrowse();},writeNav:function(){var i=1,navhtml;navhtml=this.writeBtn("first")+this.writeBtn("previous");for(;i<=this._numPages;i++){if(i===1&&this.options.startRange===0)navhtml+="<span>...</span>";if(i>this.options.startRange&&i<=this._numPages-this.options.endRange)navhtml+="<a href='#' class='jp-hidden'>";else

navhtml+="<a>";switch(this.options.links){case"numeric":navhtml+=i;break;case"blank":break;case"title":var title=this._items.eq(i-1).attr("data-title");navhtml+=title!==undefined?title:"";break;}navhtml+="</a>";if(i===this.options.startRange||i===this._numPages-this.options.endRange)navhtml+="<span>...</span>";}navhtml+=this.writeBtn("next")+this.writeBtn("last")+"</div>";return navhtml;},writeBtn:function(which){return this.options[which]!==false&&!$(this["_"+which]).length?"<a class='jp-"+which+"'>"+this.options[which]+"</a>":"";},cacheNavElements:function(holder,index){this._nav[index]={};this._nav[index].holder=holder;this._nav[index].first=this._first.length?this._first:this._nav[index].holder.find("a.jp-first");this._nav[index].previous=this._previous.length?this._previous:this._nav[index].holder.find("a.jp-previous");this._nav[index].next=this._next.length?this._next:this._nav[index].holder.find("a.jp-next");this._nav[index].last=this._last.length?this._last:this._nav[index].holder.find("a.jp-last");this._nav[index].fstBreak=this._nav[index].holder.find("span:first");this._nav[index].lstBreak=this._nav[index].holder.find("span:last");this._nav[index].pages=this._nav[index].holder.find("a").not(".jp-first, .jp-previous, .jp-next, .jp-last");this._nav[index].permPages=this._nav[index].pages.slice(0,this.options.startRange).add(this._nav[index].pages.slice(this._numPages-this.options.endRange,this._numPages));this._nav[index].pagesShowing=$([]);this._nav[index].currentPage=$([]);},bindNavHandlers:function(index){var nav=this._nav[index];nav.holder.bind("click.jPages",this.bind(function(evt){var newPage=this.getNewPage(nav,$(evt.target));if(this.validNewPage(newPage)){this._clicked=true;this.paginate(newPage);}evt.preventDefault();},this));if(this._first.length){this._first.bind("click.jPages",this.bind(function(){if(this.validNewPage(1)){this._clicked=true;this.paginate(1);}},this));}if(this._previous.length){this._previous.bind("click.jPages",this.bind(function(){var newPage=this._currentPageNum-1;if(this.validNewPage(newPage)){this._clicked=true;this.paginate(newPage);}},this));}if(this._next.length){this._next.bind("click.jPages",this.bind(function(){var newPage=this._currentPageNum+1;if(this.validNewPage(newPage)){this._clicked=true;this.paginate(newPage);}},this));}if(this._last.length){this._last.bind("click.jPages",this.bind(function(){if(this.validNewPage(this._numPages)){this._clicked=true;this.paginate(this._numPages);}},this));}},disableNavSelection:function(element){if(typeof element.onselectstart!="undefined")element.onselectstart=function(){return false;};else if(typeof element.style.MozUserSelect!="undefined")element.style.MozUserSelect="none";else

element.onmousedown=function(){return false;};},bindNavKeyBrowse:function(){this.jQdocument.bind("keydown.jPages",this.bind(function(evt){var target=evt.target.nodeName.toLowerCase();if(this.elemScrolledIntoView()&&target!=="input"&&target!="textarea"){var newPage=this._currentPageNum;if(evt.which==37)newPage=this._currentPageNum-1;if(evt.which==39)newPage=this._currentPageNum+1;if(this.validNewPage(newPage)){this._clicked=true;this.paginate(newPage);}}},this));},elemScrolledIntoView:function(){var docViewTop,docViewBottom,elemTop,elemBottom;docViewTop=this.jQwindow.scrollTop();docViewBottom=docViewTop+this.jQwindow.height();elemTop=this._container.offset().top;elemBottom=elemTop+this._container.height();return((elemBottom>=docViewTop)&&(elemTop<=docViewBottom));},bindNavScrollBrowse:function(){this._container.bind("mousewheel.jPages DOMMouseScroll.jPages",this.bind(function(evt){var newPage=(evt.originalEvent.wheelDelta||-evt.originalEvent.detail)>0?(this._currentPageNum-1):(this._currentPageNum+1);if(this.validNewPage(newPage)){this._clicked=true;this.paginate(newPage);}evt.preventDefault();return false;},this));},getNewPage:function(nav,target){if(target.is(nav.currentPage))return this._currentPageNum;if(target.is(nav.pages))return nav.pages.index(target)+1;if(target.is(nav.first))return 1;if(target.is(nav.last))return this._numPages;if(target.is(nav.previous))return nav.pages.index(nav.currentPage);if(target.is(nav.next))return nav.pages.index(nav.currentPage)+2;},validNewPage:function(newPage){return newPage!==this._currentPageNum&&newPage>0&&newPage<=this._numPages;},paginate:function(page){var itemRange,pageInterval;itemRange=this.updateItems(page);pageInterval=this.updatePages(page);this._currentPageNum=page;if($.isFunction(this.options.callback))this.callback(page,itemRange,pageInterval);this.updatePause();},updateItems:function(page){var range=this.getItemRange(page);this._itemsHiding=this._itemsShowing;this._itemsShowing=this._items.slice(range.start,range.end);if(this._cssAnimSupport&&this.options.animation.length)this.cssAnimations(page);else this.jQAnimations(page);return range;},getItemRange:function(page){var range={};range.start=(page-1)*this.options.perPage;range.end=range.start+this.options.perPage;if(range.end>this._items.length)range.end=this._items.length;return range;},cssAnimations:function(page){clearInterval(this._delay);this._itemsHiding.removeClass(this.options.animation+" jp-invisible").addClass("jp-hidden");this._itemsShowing.removeClass("jp-hidden").addClass("jp-invisible");this._itemsOriented=this.getDirectedItems(page);this._index=0;this._delay=setInterval(this.bind(function(){if(this._index===this._itemsOriented.length)clearInterval(this._delay);else{this._itemsOriented.eq(this._index).removeClass("jp-invisible").addClass(this.options.animation);}this._index=this._index+1;},this),this.options.delay);},jQAnimations:function(page){clearInterval(this._delay);this._itemsHiding.addClass("jp-hidden");this._itemsShowing.fadeTo(0,0).removeClass("jp-hidden");this._itemsOriented=this.getDirectedItems(page);this._index=0;this._delay=setInterval(this.bind(function(){if(this._index===this._itemsOriented.length)clearInterval(this._delay);else{this._itemsOriented.eq(this._index).fadeTo(this.options.fallback,1);}this._index=this._index+1;},this),this.options.delay);},getDirectedItems:function(page){var itemsToShow;switch(this.options.direction){case"backwards":itemsToShow=$(this._itemsShowing.get().reverse());break;case"random":itemsToShow=$(this._itemsShowing.get().sort(function(){return(Math.round(Math.random())-0.5);}));break;case"auto":itemsToShow=page>=this._currentPageNum?this._itemsShowing:$(this._itemsShowing.get().reverse());break;default:itemsToShow=this._itemsShowing;}return itemsToShow;},updatePages:function(page){var interval,index,nav;interval=this.getInterval(page);for(index in this._nav){if(this._nav.hasOwnProperty(index)){nav=this._nav[index];this.updateBtns(nav,page);this.updateCurrentPage(nav,page);this.updatePagesShowing(nav,interval);this.updateBreaks(nav,interval);}}return interval;},getInterval:function(page){var neHalf,upperLimit,start,end;neHalf=Math.ceil(this.options.midRange/2);upperLimit=this._numPages-this.options.midRange;start=page>neHalf?Math.max(Math.min(page-neHalf,upperLimit),0):0;end=page>neHalf?Math.min(page+neHalf-(this.options.midRange%2>0?1:0),this._numPages):Math.min(this.options.midRange,this._numPages);return{start:start,end:end};},updateBtns:function(nav,page){if(page===1){nav.first.addClass("jp-disabled");nav.previous.addClass("jp-disabled");}if(page===this._numPages){nav.next.addClass("jp-disabled");nav.last.addClass("jp-disabled");}if(this._currentPageNum===1&&page>1){nav.first.removeClass("jp-disabled");nav.previous.removeClass("jp-disabled");}if(this._currentPageNum===this._numPages&&page<this._numPages){nav.next.removeClass("jp-disabled");nav.last.removeClass("jp-disabled");}},updateCurrentPage:function(nav,page){nav.currentPage.removeClass("jp-current");nav.currentPage=nav.pages.eq(page-1).addClass("jp-current");},updatePagesShowing:function(nav,interval){var newRange=nav.pages.slice(interval.start,interval.end).not(nav.permPages);nav.pagesShowing.not(newRange).addClass("jp-hidden");newRange.not(nav.pagesShowing).removeClass("jp-hidden");nav.pagesShowing=newRange;},updateBreaks:function(nav,interval){if(interval.start>this.options.startRange||(this.options.startRange===0&&interval.start>0))nav.fstBreak.removeClass("jp-hidden");else nav.fstBreak.addClass("jp-hidden");if(interval.end<this._numPages-this.options.endRange)nav.lstBreak.removeClass("jp-hidden");else nav.lstBreak.addClass("jp-hidden");},callback:function(page,itemRange,pageInterval){var pages={current:page,interval:pageInterval,count:this._numPages},items={showing:this._itemsShowing,oncoming:this._items.slice(itemRange.start+this.options.perPage,itemRange.end+this.options.perPage),range:itemRange,count:this._items.length};pages.interval.start=pages.interval.start+1;items.range.start=items.range.start+1;this.options.callback(pages,items);},updatePause:function(){if(this.options.pause&&this._numPages>1){clearTimeout(this._pause);if(this.options.clickStop&&this._clicked)return;else{this._pause=setTimeout(this.bind(function(){this.paginate(this._currentPageNum!==this._numPages?this._currentPageNum+1:1);},this),this.options.pause);}}},setMinHeight:function(){if(this.options.minHeight&&!this._container.is("table, tbody")){setTimeout(this.bind(function(){this._container.css({"min-height":this._container.css("height")});},this),1000);}},bind:function(fn,me){return function(){return fn.apply(me,arguments);};},destroy:function(){this.jQdocument.unbind("keydown.jPages");this._container.unbind("mousewheel.jPages DOMMouseScroll.jPages");if(this.options.minHeight)this._container.css("min-height","");if(this._cssAnimSupport&&this.options.animation.length)this._items.removeClass("animated jp-hidden jp-invisible "+this.options.animation);else this._items.removeClass("jp-hidden").fadeTo(0,1);this._holder.unbind("click.jPages").empty();}};$.fn[name]=function(arg){var type=$.type(arg);if(type==="object"){if(this.length&&!$.data(this,name)){instance=new Plugin(this,arg);this.each(function(){$.data(this,name,instance);});}return this;}if(type==="string"&&arg==="destroy"){instance.destroy();this.each(function(){$.removeData(this,name);});return this;}if(type==='number'&&arg%1===0){if(instance.validNewPage(arg))instance.paginate(arg);return this;}return this;};})(jQuery,window,document);


//]]>


</script>



5. Luego, iniciamos el plugin agregando lo siguiente, poniéndolo debajo del plugin. Desde ese código puedes configurar las opciones de la paginación de la galería y que abajo se explican:






<script type='text/javascript'>


//<![CDATA[


     $(function() {


     $("div.holder").jPages({


      containerID: "itemContainer",


      previous: "← Anterior",


      next: "Siguiente →",


      perPage: 8,


      midRange: 4,


      animation: "bounceIn"


    });


  });


//]]>


  </script>






Opciones configurables (cosas que puedes cambiar)



En:

perPage:Especificas el número de imágenes por página. Por defecto son 10.

previouspones el texto del enlace anterior. Igualmente se pueden usar una imagen si se desea.

next: pones el texto del enlace siguiente. Igualmente se pueden usar una imagen si se desea.

midRange:define el número de enlaces a las páginas que serán visibles en la navegación, antes de llegar a la última... Si por ejemplo el valor es 4, y hay un total de 10 páginas, entonces la navegación se verá así:

← Anterior 1 2 3 4 ... 10 Siguiente →

Por defecto viene 5 como valor en el plugin.

animation: Especificas el tipo de animación con CSS3 que vas a aplicar a la galería. Si es diferente a la que muestro en el ejemplo, entonces el CSS será también otro (del paso 2). En la página de la librería (Animate CSS) lo facilitan y lo  puedes descargar de forma individual por animación, para no tener que usar el archivo con todas las animaciones que son más de 2500 lineas de código y que facilitan en la página del plugin.

En la página del plugin puedes ver las demostraciones para ver cómo se ve la galería con cada animación...



Importante: Si no vas a usar animación con CSS3 (del paso 2), entonces elimina la linea del código anterior:  animation: "bounceIn".



Además de éstas, hay otras opciones que pueden agregarse, y en la página del plugin pueden verse más detalles en los ejemplos.  



6. Ya para terminar, en el panel de edición de páginas, agregas el HTML de la galería y lo publicas:


<div class="holder"></div><ul id="itemContainer" class="galeria2"><li><a href="#" title=""><img alt="" src="URL_DE_LA_IMAGEN" /><span style="border:0;">El titulo o leyenda</span></a></li>                                                                                                          

<li><a href="#" title=""><img alt="" src="URL_DE_LA_IMAGEN" /><span style="border:0;">El titulo o leyenda</span></a></li>                                                                                      <li><a href="#" title=""><img alt="" src="URL_DE_LA_IMAGEN" /><span style="border:0;">El titulo o leyenda</span></a></li>                                                                                                                                 <li><a href="#" title=""><img alt="" src="URL_DE_LA_IMAGEN" /><span style="border:0;">El titulo o leyenda</span></a></li>                                                                </ul>



El código anterior está listo para mostrar 4 imágenes. Edita lo que está resaltado de rojo, y agrega el código para mostrar más imágenes, repitiendo esta parte:




<li><a href="#" title=""><img alt="" src="URL_DE_LA_IMAGEN" /><span style="border:0;">El titulo o leyenda</span></a></li>






...antes del cierre de la etiqueta ul, es decir , antes de </ul>. En el paso 3 de la primera opción de la entrada que mencionaba, se explican los detalles.



Notas adicionales.

El plugin es asombrosamente configurable, hay muchas opciones y explicar todo es muy amplio, en la página pueden verse muchos mas detalles ;)



Las animaciones con CSS3 que están integradas en el ejemplo, no son visibles en IE, sin embargo, el plugin tiene un efecto llamado fade in, que hace que las imágenes se vean como que se desvanecen y que también se puede configurar desde las opciones, arriba puse el enlace para que veas cómo se ve.



El hecho de que tenga paginación la galería, no significa que cada página del contenido tenga una URL única, imagina que es como un slidehow, que va mostrando las imágenes según como lo hayas configurado, y a petición del usuario. En otras palabras no son páginas independientes.





Crédito de las imágenes usadas en la galería Garry Knight

Plugin visto en Vagabundia




No hay comentarios:

Publicar un comentario