viernes, 30 de noviembre de 2012

Social Media Icons

3D black and white
Contiene 41 íconos de 32x32 y 48x48, en formato PNG.
descargar

Yammy Social Media
Contiene 30 íconos de 64x64 y 128x128, en formato PNG.
descargar

miércoles, 28 de noviembre de 2012

Nuevo Gadget de Seguidores de Google+ en Blogger y cómo empezar a usarlo

Ayer agregué al blog el nuevo gadgtet de Seguidores de Google+, mismo que anunciaban oficialmente desde Blogger Buzz, y parece que todo funciona de maravilla. Se reportó un problema con quienes usan las vistas dinámicas, al parecer el gadget no se veía, aunque desde el Blog de los problemas conocidos de Blogger se publicó que esto podía solucionarse si se vaciaba la caché del navegador y se volvía a cargar la página.



El gadget de Seguidores de Google+ le facilitará a los usuarios de tu blog que puedan agregarte a un círculo, y así seguir el contenido que publicas y envías a tu página de Google+, o a tu perfil en Google+, según como lo tengas configurado en tu cuenta de Blogger.




Gadget de seguidores de Google+









Cómo empezar a usar el gadget de Seguidores de Google+




Una vez que hayas actualizado tu perfil de Blogger al de Google+, puedes empezar a usar el gadget y desde ahí, los usuarios de tu blog podrán agregarte a un círculo, función que ya cumplía el gadget de "Insignia de Blogger" que no hace mucho fue habilitado, con la diferencia de que este nuevo gadget mostrará la foto del perfil en Google+ de quienes te han agregado, y un enlace que mostrará el resto de tus seguidores desde Google+. Es un gadget similar al de Google Friend Connect o "Seguidores", y puedes usar de forma simultánea con éste, si así lo deseas.



Si eres usuario nuevo de Blogger, y aún no utilizas Google+, no puedes perder la oportunidad de vincular tu cuenta de Blogger a tu perfil de Google+ o mejor aún, crear una página para tu blog y así hacer crecer tu audiencia favoreciendo la promoción de tu blog y establecer vínculos con otros blogueros como tú.





Cómo actualizar mi perfil de Blogger a mi perfil de G+ 





1. Desde el panel de Blogger, ve a la pestaña de "Google+" y luego actualiza tu perfil de Blogger al de Google haciendo click en "Actualizar a Google+".




Actualizar perfil de Google+




Para ello, lo ideal es que ya hayas actualizado tu perfil en Google+, poniendo una foto tuya, y los datos que consideres pertinentes y que quieras mostrar en la Web.



2. Luego, aceptas los términos que implica el cambio, mismos que ahí se explican, y actualizas tu perfil en "Cambiar ahora".




Cambiar perfil de Blogger por perfil de Google+





El nombre que aparece en la imagen es ficticio y muestra solo un ejemplo.



3. Hecho lo anterior, ya habrás asociado tu blog al perfil de Google+, y tanto el gadget de "Perfil", así como tus entradas y comentarios serán enlazados a tu perfil de Google+. Además, ya puedes empezar a usar el gadget de Seguidores de Google+.





Cómo agregar el gadget de Seguidores de Google+




Es muy simple y lo haces del mismo modo que agregas cualquier otro gadget. Desde la pestaña "Diseño" del panel de Blogger, haces click en agregar un gadget, y eliges la opción de "Seguidores de Google+"




Nuevo gadget de seguidores



Por el momento, (no se si sea permanente) no hay opciones que configurar en este gadget, así que sólo hay que guardarlo para que se agregue.



Conclusiones 



Tal y como lo mencionan desde el blog de los productos de Google en español y en el mismo Blogger Buzz, creo que este gadget le da más relevancia a tus seguidores de Google+, puede hacer crecer más tu audiencia, ya que éste siempre estará visible desde tu blog, ¿tú que piensas?



Al asociar tu blog con la cuenta de Google+, tendrás múltiples beneficios como la capacidad de poder compartir entradas fácilmente cada vez que publiques, y poder agregar la fotografía de tu perfil en G+, en los resultados de búsqueda de Google, ¿ya lo has hecho?.



Y aprovechando la ocasión, "Muchas gracias por agregarme a un círculo y seguir mi contenido" ;)



+ Información sobre el tema y referencias

Gadget de Seguidores de Google+

Cómo administrar la configuración de Google+ de tu blog

martes, 27 de noviembre de 2012

Sobre resúmenes e imágenes desproporcionadas

Son muchos los que utilizan alguna clase de plantilla o tiene un sitio donde las entradas del home se muestran resumidas, adornadas con una imagen. También son muchos los que preguntan ¿cómo puedo hacer para que esas imágenes no se deformen?

La respuesta a eso es sencilla y no le gusta a nadie: no se puede.

No se puede porque si usamos etiquetas IMG y las re-dimensionamos, cosa que podemos hacer con width y height tanto en el CSS como con atributos en la misma etiqueta, la imagen se mostrará con esa dimensión; como una es más alta que ancha, el pobre patito "engordará".



¿Qué pasa en los resúmenes? Imaginemos algo así:
<div class="demoresumen">
<div>
<img src="una_imagen"/>
<p> ... un texto ... </p>
</div>
<!-- etc etc etc -->
<div>
<img src="una_imagen"/>
<p> ... un texto ... </p>
</div>
</div>
Con este estilo:
<style>
.demoresumen {margin: 0 auto; overflow: hidden; width: 480px;}
.demoresumen div {border: 1px solid #444; float: left; height: 240px; margin: 5px; width: 225px;}
.demoresumen p {font-size: 11px; margin: 0; padding: 10px;}
.demoresumen img {display: block; height: 160px; margin: 10px auto 0; width: 200px;}
</style>
Veríamos algo así:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...


Para que una imagen se re-dimensione sin perder sus proporciones debemos establecer una y solo una de las dimensiones, dejando que la otra sea calculada por el navegador; en este caso, basta con eliminar height o colocar height: auto; pero, obviamente, con este método, toda la estructura se desquicia ya que habrá rectángulos mas altos que otros y si estamos dimensionando la altura del contenedor y usando overflow:hidden, se cortará.

height: auto | overflow:hidden | restaurar

¿Podemos hacer que la imagen del pato se muestre sin deformarse? Si pero no. Una forma de hacerlo es colocarla dentro de un contenedor, dimesionarlo y usar overflow; es decir, "cortar" lo que sobre; en lugar de:
<img src="una_imagen"/>
pondríamos algo así:
<span><img src="una_imagen"/></span>
y cambiaríamos las reglas de estilo:
.demoresumen span {display: block;height: 160px;margin: 10px auto 0;overflow: hidden;width: 200px;}
.demoresumen img {width: 200px;}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...


Tampoco resuelve demasiado.

Si estamos buscando opciones sencillas, lo ideal es que las imágenes que vamos a utilizar mantengan siempre una proporción adecuada y listo; ese tipo de plantilla ha sido pensada para eso; caso contrario, deberíamos olvidarnos de lo que tenemos y pasar a alguna estructura de mosaico usando CSS3 lo que impedirá que se muestre correctamente en ciertos navegadores o agregando algún script que maneje ese tipo de solución.

Una alternativa intermedia es usar un poco de CSS que no resolverá el problema pero mitigará los efectos. Para esto, debemos olvidarnos de la etiqueta IMG y colocar la imagen como fondo. Otra vez, en lugar de:
<img src="una_imagen"/>
pondríamos algo así:
<span style="background-image:url(una_imagen)"></span>
Y es esa etiqueta con la imagen de fondo la que podemos manipular un poco mediante las propiedades background; por ejemplo:
.demoresumen span {
display: block;
height: 160px;
margin: 10px auto 0;
width: 200px;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: cover;
}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy ...


La imagen se cortará pero, podemos establecer donde; en el ejemplo, eso se hace con background-position y los valores 50% 50% indican que se coloque en el medio pero puede ser cualquier otro valor.

La otra propiedad que podemos usar es background-size aunque esta, sólo se aplicará en navegadores modernos y, básicamente, tiene tres valores:

background-size: contain | background-size: cover | background-size: auto

En resumen, no hay soluciones perfectas y por eso comencé diciendo que la respuesta a la pregunta es no, no se puede porque es imposible mantener las proporciones de una imagen si lo que estamos haciendo es cambiando esas proporciones. El problema, termina siendo una contradicción en si misma.

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




Cómo hacer que cualquier usuario publique en Blogger sin ser autor (Actualizado)

En Blogger hay una interesante función conocida como "Mail2Blogger", muy pocos la conocen y hacen uso de esta característica. Para los que no sepan cual es su función, Mail2Blogger nos permite enviar entradas desde nuestro correo electrónico y así publicarlas en nuestro blog o guardarlas como borrador. Podemos hacer uso de esta interesante herramienta para que otros puedan publicar entradas sin necesidad de que establezcas su autoría.

Esto es muy útil si deseas crear un sitio de frases, página de confesiones, sistema similar a un foro o alguna otra cosa que se te ocurra.

blogger multiautor


Para ello, he creado un formulario a base de PHP básico y algo de CSS3, el cual podrás ponerlo dentro de un iframe en alguna parte de tu blog y así conseguir que otros publiquen artículos en él. Para ver un demo en funcionamiento puedes visitar el siguiente enlace:


El tutorial:

Primero les explicaré cómo funciona el sistema: Consta básicamente de un formulario que envía un correo electrónico a la dirección de tu Mail2Blogger. Al hacer esto, el sistema automáticamente publicará el artículo, o lo dejará en tu borrador según tu configuración. Para poder moderar las publicaciones te recomiendo que establezcas la segunda alternativa por defecto, pero si lo deseas puedes dejar el paso libre a cualquier post.

Paso 1: ¿Cómo configurar Mail2Blogger?:

Habilitar la característica de envío de entradas por correo electrónico es muy sencilla, símplemente en nuestro escritorio Blogger vamos a la opción "Configuración | Móviles y Correo electrónico", en ella estableceremos nuestras SecretWords y eliges la configuración que desees más conveniente:

correo-blogger

Paso 2: El formulario PHP y su configuración básica:

Descarga este archivo .zip (Actualizado) y descomprímelo en donde desees, dentro hay un archivo con la extensión .PHP, en él busca la siguiente línea:
$tu_mail2blogger = 'usuario.secretwords@blogger.com'; // Inserta aquí tu correo Mail2Blogger

Reemplaza el correo que aparece por el que usas en Mail2Blogger, guarda el archivo y estará listo para subirse a algún servidor.

Puedes modificar algunos otros valores, pero te recomiendo únicamente que modifiques los atributos de la hoja de estilos para hacerla coincidir con tu blog.

Paso 3: Subir e insertar el formulario en tu blog:

Para este paso es necesario un servidor web (No Dropbox, Google Sites o similares), te recomiendo Nixiweb ya que posee ancho de banda y espacio ilimitados.

Una vez que hayas subido el archivo a tu servidor, lo insertas en la plantilla de la siguiente manera:
<iframe src='URL_ARCHIVO_PHP' style='height:320px;border:0; width:100%;' />

Modifica los valores width y height para cambiar el ancho y el alto del iframe, respectivamente.

Extra: Configurar la apariencia de las entradas en tu blog:

Por defecto he establecido el siguiente formato de salida al correo:

<span class="post-autor">Escrito por: Cloudx18</span>
<div class="post-body-enviado">
Este es el cuerpo de la entrada.
</div>

Nota: El título del post se agrega automáticamente dentro de la entrada normalmente.

Para poder establecer los atributos necesarios deberás utilizar los siguientes selectores CSS:
.post-autor {
/*Atributos del nombre del autor*/
}

.post-body-enviado {
/*Atributos del texto de la entrada*/
}

Nota: Para que los usuarios puedan hacer saltos de línea, es necesario que utilicen la etiqueta breakline o <br />

Si consideras que el editor es demasiado simple, puedes añadirle un editor WYSIWYG, o si lo amerita, puedo actualizar la entrada mas adelante con el editor avanzado.


Actualización Viernes 30 de Noviembre de 2012:

El sistema tenía muchos contras, uno de ellos era que los usuarios podían insertar HTML sin restricciones, un gran fallo de parte mía ya que los usuarios podían escribir etiquetas <script> y <style> (Gracias a Emilio Cobos por informarme sobre tamaño desastre y descuido).

Puedes descargar el sistema nuevamente modificado por Emilio, o bien descargar la actualización y corrección que incluí por mi cuenta, ambas opciones deberían funcionar correctamente.

 La lista de opciones que incluí fueron las siguientes (Reescribí el sistema desde 0):

  • Validador del formulario: Necesario para que los usuarios deban escribir un mínimo de carácteres para poder enviar el artículo. Para cambiar los parámetros deberás modificar los siguientes datos:

Para el nombre:
if (validador.nombre.value.length < 4) { 
Para el título:
if (validador.titulopost.value.length < 10) {
Para el post:
if (validador.mensaje.value.length < 20) {  

Tampoco olvides modificar las siguientes líneas:

Para el nombre:
Mín. 4 Carácteres
Para el título:
Mín. 10 Carácteres
Para el post:
Mín. 20 Carácteres

  • Se ha añadido además el formulario dentro de una tabla para mantener los elementos alineados correctamente según el ancho del iframe.
  • Se agregó un Doctype y se corrigieron problemas de síntaxis.
  • Las palabras que lleven tilde y eñe (Ñ) debieran mostrarse correctamente.
  • Ya no se pueden ejecutar scripts ni aplicar hojas de estilos en ninguno de los campos ya que las etiquetas se suprimen y dejan el contenido fuera, puedes modificar la lista de etiquetas utilizables desde la siguiente línea:
// Usamos strip_tags para permitir sólamente algunas etiquetas, si alguna otra existe dentro del código, ésta se suprimirá y dejará el contenido ---- No incluyas las etiquetas <SCRIPT> ni <STYLE> por una cuestión de seguridad.
$cuerpo_seguro = strip_tags($cuerpo_post, '<p><a><br><b><u><i><ul><ol><li><span><img><blockquote><h1><h2><h3><h4><h5><h6><strike><stroke><div><font><input><button>');

Si deseas agregar un editor WYSIWYG, puedes usar Nicedit, es un sistema muy útil que sirve para reemplazar todos los textareas de una página web:
<script src="http://js.nicedit.com/nicEdit-latest.js" type="text/javascript"></script>
<script type="text/javascript">bkLib.onDomLoaded(nicEditors.allTextAreas);</script>

Este código debes pegarlo arriba de
</head>

lunes, 26 de noviembre de 2012

Contenido en orden alfabético que se desliza estilo iPhone

SliderNav es un plugin ligero, que te permite añadir de forma dinámica contenido que se desliza a través de una barra vertical de navegación. Es ideal para mostrar listados en orden alfabético, aunque se pueden usarse otras palabras.



Según el autor, el plugin es compatible con Firefox 3, Chrome 5, IE7, Safari 4 y Opera 10 en adelante. Puedes ver la Demostración, desde la página del plugin o bien en este blog donde lo he probado. La explicación será considerando el ejemplo 1, que muestra la barra de navegación con las letras del alfabeto (en inglés), como se aprecia en la siguiente imagen.




contenido que se desliza


La imagen solo muestra una parte del elemento (recortada).




Cómo implementarlo en el blog



Vamos a pensar que quieres agregarlo en la columna lateral del blog, entonces harás lo siguiente:




1. Primero, necesitas agregar jQuery antes de </head>, yendo a la edición de HTML de la plantilla. Si ya lo tienes agregado, entonces no necesitas volverlo a poner. Como lo muestro enseguida, lo cargamos desde la librería CDN de Google:


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

2. Luego, agregas el plugin directamente en la plantilla después de jQuery:


<script type='text/javascript'>                       

 //<![CDATA[    





/*
* SliderNav - A Simple Content Slider with a Navigation Bar
* Copyright 2010 Monjurul Dolon, http://mdolon.com/
* Released under the MIT, BSD, and GPL Licenses.
* More information: http://devgrow.com/slidernav
*/
$.fn.sliderNav=function(options){var defaults={items:["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"],debug:false,height:null,arrows:true};var opts=$.extend(defaults,options);var o=$.meta?$.extend({},opts,$$.data()):opts;var slider=$(this);$(slider).addClass('slider');$('.slider-content li:first',slider).addClass('selected');$(slider).append('<div class="slider-nav"><ul></ul></div>');for(var i in o.items)$('.slider-nav ul',slider).append("<li><a alt='#"+o.items[i]+"'>"+o.items[i]+"</a></li>");var height=$('.slider-nav',slider).height();if(o.height)height=o.height;$('.slider-content, .slider-nav',slider).css('height',height);if(o.debug)$(slider).append('<div id="debug">Scroll Offset: <span>0</span></div>');$('.slider-nav a',slider).mouseover(function(event){var target=$(this).attr('alt');var cOffset=$('.slider-content',slider).offset().top;var tOffset=$('.slider-content '+target,slider).offset().top;var height=$('.slider-nav',slider).height();if(o.height)height=o.height;var pScroll=(tOffset-cOffset)-height/8;$('.slider-content li',slider).removeClass('selected');$(target).addClass('selected');$('.slider-content',slider).stop().animate({scrollTop:'+='+pScroll+'px'});if(o.debug)$('#debug span',slider).html(tOffset);});if(o.arrows){$('.slider-nav',slider).css('top','20px');$(slider).prepend('<div class="slide-up end"><span class="arrow up"></span></div>');$(slider).append('<div class="slide-down"><span class="arrow down"></span></div>');$('.slide-down',slider).click(function(){$('.slider-content',slider).animate({scrollTop:"+="+height+"px"},500);});$('.slide-up',slider).click(function(){$('.slider-content',slider).animate({scrollTop:"-="+height+"px"},500);});}}; //]]>
</script>



O bien, lo alojas en un sito de alojamiento que uses de confianza, para luego llamarlo usando la etiqueta script:



<script type='text/javascript' src='//mi_arcivo_con_el_plugin.js'></script>



3. Después, agregas la función de jQuery para llamar al elemento que se está creando...




<script type="text/javascript">
//<![CDATA[
$(document).ready(function(){
$('#slider').sliderNav();
});
//]]>
</script>






4. Luego, agregas el CSS, yendo a plantilla > Personalizar > Avanzado > Añadir CSS.


/*
* SliderNav - A Simple Content Slider with a Navigation Bar
* Copyright 2010 Monjurul Dolon, http://mdolon.com/
* Released under the MIT, BSD, and GPL Licenses.
* More information: http://devgrow.com/slidernav
*/
.slider {
width: 300px; /*el ancho del slider.Toma nota del ancho de donde lo colocaras*/
min-height: 250px;
display: block;
position: relative;
background: #fff;/*color de fondo de los elementos de la lista*/ 
overflow: hidden;
}
.slider ul {
list-style: none;
margin:0; 
padding:0; 
}
.slider-content {
 float: left;
width: 100%;
display: block;
overflow: hidden;
 min-height: 250px;
}
.slider-content ul {
float: left;
width: 100%;
display: block;
position: relative;                                                                                                            top:-3px;
}
.slider-content ul li {
float: left;                                                                                                                     width: 100%;
}
.slider-content ul ul li a {
padding: 5px 10px;
display: block;
border-bottom: 1px solid #f3f3f3; /*borde al fondo de cada elemento*/
text-transform: capitalize;
}
.slider-content ul ul li a:hover {
background: #f3faff; /*el color de fondo al poner el puntero encima del titulo*/                                               border-color: #d5ebf9;/*color del borde*/
}
.slider-content .title {
padding: 5px 0;
text-indent: 10px;
background: #bbb; /*color de fondo del bloque de cada letra en la lista*/
color: #fff;  /*color de fuente*/                                                                                                         width: 100%;
float: left;                                                                                                              font-weight: bold;
text-transform: uppercase;
}
.slider-content .selected .title {
background: #666; /*el color de fondo de la letra seleccionada en la lista*/ 
}
.slider .slider-nav {
position: absolute;
right: 0;
top: 0;
background: #666; /*color de fondo barra vertical con letras de navegación*/
min-height: 250px;
}
.slider .slider-nav ul {
padding: 5px 0;                                                                                                                   }
.slider .slider-nav li a {
padding: 3px 5px;
line-height: 13px;
text-align: center;
color: #fff; /*color de fuente de cada elemento de lista*/
font-weight: bold;
display: block;
text-transform: uppercase;
cursor: pointer;
}
.slider #debug {
position: absolute;
bottom: 0;
left: 0;
padding: 5px;
background: #000;
color: #fff;
}
.slider .arrow { /*las flechas creadas con css*/
font-size: 0px;
line-height: 0%;
width: 0px;
border-bottom: 8px solid #fff;
border-left: 5px solid #333;
border-right: 5px solid #333;
position: relative;                                                                                                          top: -5px; /*mover flecha de arriba*/
}
.slider .down {
border-bottom: none;
border-top: 8px solid #fff;
top: 2px;  /*mover flecha al fondo*/
}
.slider .slide-up, .slider .slide-down {
height: 20px;
background: #333; /*color de fondo de las barras horizontales con las flechas */ 
text-align: center;
cursor: pointer;
float: right;
width: 100%;
position: relative;
}



Notas importantes del CSS.


  • Comúnmente, cuando agregas un elemento a una plantilla de Blogger, hay que hacer ajustes, ya que puede haber algunas propiedades que estén en la plantilla que se hereden al elemento, cuando no fueron especificadas en el CSS, y por ello, puede verse alterado la apariencia de dicho elemento.

  • En la plantilla de ejemplo, he editado algunos valores y agregado algunas propiedades del CSS mismas que he resaltado de morado para que puedas identificarlas, que pueden ser claves para ajustar el elemento.

  • En cuanto a los colores de fondo, bordes y color de fuentes, los he resaltado de rojo para que puedan editarse. Por favor, también lee los comentarios de color verde, para que sepas de que se trata cada cosa, ya que termines, puedes eliminarlos.



5. Finalmente, y pensando en que vas a agregar el elemento en una columna lateral, ve a Diseño y agregas el código HTML en un gadget con la opción de HTML/Javascript, siguiendo la siguiente estructura:



<div id="slider">
<div class="slider-content">
<ul>
<li id="a"><a name="a" class="title">A</a>
<ul>
<li><a href="#">Adam</a></li>
<li><a href="#">Alum</a></li>
<li><a href="#">Ali</a></li>

</ul>
</li>
<li id="b"><a name="b" class="title">B</a>
<ul>
<li><a href="#">Bohemia</a></li>
<li><a href="#">Becky</a></li>

</ul>
</li>
etc... </ul> </div>


Explicación de la estructura del código HTML (del paso 4)




Antes del cierre de la etiqueta <ul> que resalté de azul, deben estar los bloques con las listas en orden alfabético, es decir en la parte que dice etc... Asegúrate de eliminar ese texto del código. Entonces, siguiendo con la estructura anterior, seguiría la "C", y el código HTML de éste se verá así:

<li id="c"><a name="c" class="title">C</a>
<ul>
<li><a href="#">Corem</a></li>
<li><a href="#">Cohemia</a></li>
</ul>
</li>


IMPORTANTE:  Cada vez que agregues el bloque con la lista, asegúrate de que el ID de la etiqueta "li" y el nombre asignado a la etiqueta "a", lleven la misma letra respectivamente. En el bloque anterior lleva la "c" que es la que seguía, tomando en cuenta el orden alfabético.


Si quieres agregar más elementos a la lista de cada bloque con determinada letra, entonces deberás repetir esta linea...

<li><a href="#">Cometia</a></li>

Entonces, el bloque anterior, con la linea anterior, quedaría así:

<li id="c"><a name="c" class="title">C</a>
<ul>
<li><a href="#">Corem</a></li>
<li><a href="#">Cohemia</a></li>
<li><a href="#">Cometia</a></li>
</ul>
</li>


Al terminar de poner todos los elementos con la letra "c", seguirá el bloque con la letra "d" y así sucesivamente. Su estructura será la misma que se explicaba anteriormente.

Otras notas:


Se puede ajustar la altura en pixeles, si deseas anular la detección automática basada en la navegación vertical. Según explican, puede que sea necesario ajustar la altura mínima en el CSS (min-height). Puede inhabilitarse las flechas. Puedes verse todos los detalles en la página del autor



domingo, 25 de noviembre de 2012

Ascii, canvas, experimentos divertidos

No, esto no es para ser utilizado en ninguna parte pero llama la atención la simplicidad del código y muestra lo fantástico de algunas de las posibilidades que nos brindan el CSS y la etiqueta canvas.

Este, es uno de los muchos demos que hay en Thecodeplayer.com/ y lo que hace es transformar una imagen (un sprite) en una animación con caracteres Ascii.


La etiqueta canvas tiene una serie de funciones que nos permiten manipular las imágenes de muchos modos pero, también tiene una restricción de seguridad, sólo funciona si esas imágenes están en el mismo servidor que la página por lo tanto, en Blogger es imposible usarla de modo normal y, en este caso, lo que hice para divertirme fue subir el HTML y la imagen a Dropbox y mostrarla con un iframe.


Para los curiosos, este sería el código fuente:

<html>
<head>
<style>
* {margin: 0; padding: 0;}
#ascii {font-family: monospace;font-size: 11px;line-height: 70%;}
#sprite {display: none;}
#container {overflow: hidden;display: inline-block;}
</style>
<script>
window.onload = function(){
var r, g, b, gray;
var character, line = "";
var sprite = document.getElementById("sprite");
var W = sprite.width;
var H = sprite.height;
var tcanvas = document.createElement("canvas");
tcanvas.width = W;
tcanvas.height = H; //same as the image
var tc = tcanvas.getContext("2d");
tc.fillStyle = "white";
tc.fillRect(0, 0, W, H);
tc.drawImage(sprite, 0, 0, W, H);
var pixels = tc.getImageData(0, 0, W, H);
var colordata = pixels.data;
var ascii = document.getElementById("ascii");
for(var i = 0; i < colordata.length; i = i+4){
r = colordata[i];
g = colordata[i+1];
b = colordata[i+2];
gray = r*0.2126 + g*0.7152 + b*0.0722;
if(gray > 250) character = " ";
else if(gray > 230) character = "`";
else if(gray > 200) character = ":";
else if(gray > 175) character = "*";
else if(gray > 150) character = "+";
else if(gray > 125) character = "#";
else if(gray > 50) character = "W";
else character = "@";
if(i != 0 && (i/4)%W == 0){
ascii.appendChild(document.createTextNode(line));
ascii.appendChild(document.createElement("br"));
line = "";
}
line += character;
}
var frames = 10;
var container = document.getElementById("container");
var frame_width = parseInt(window.getComputedStyle(container).width)/frames;
container.style.width = frame_width+"px";
ascii.style.marginLeft = "0";
setInterval(loop, 1000/10);
function loop(){
var current_ml = parseFloat(ascii.style.marginLeft);
if(current_ml == frame_width*(frames-1)*-1)
ascii.style.marginLeft = "0";
else
ascii.style.marginLeft = (current_ml - frame_width) + "px";
}
}
</script>
</head>
<body>
<img src="sprite.png" id="sprite"/><div id="container"><pre id="ascii"></pre></div>
</body>
</html>

sábado, 24 de noviembre de 2012

Agregar AdSense a blogger 3 : entre el post y los comentarios

Éste post es el tercer tutorial de cómo Agregar AdSense a nuestro blog. Hasta el moemtno hemos visto dos formas: agregar AdSense en la sidebar y agregar AdSense entre posts.

Hoy vamos a ver una forma más de agregar la publicidad AdSense a nuestro blog, esa vez agregándola entre el post (entrada) y los comentarios.


1.§ Vamos a Plantilla - Edición de HTML - Continuar. Damos clic a la opción Expandir plantillas de artilugios.

2.§ Con ayuda de CTRL+F buscamos el siguiente código en nuestra plantilla:
<p class='post-footer-line post-footer-line-3'/>

<div class='post-footer-line post-footer-line-4'>

3.§ Copiamos el código generado en AdSense y, para evitar que nos pueda dar algún error lo convertimos a texto plano o a su equivalente en HTML.

Para ello, y como vimos en el primer tutorial de AdSense, podemos usar esta página para convertir el código o hacerlo manualmente reemplazando los valores de la izquierda por los de la derecha:
< por &lt;
> por &gt;
" por &quot;

4.§ Debajo del código que buscamos en el paso 2.§, vamos a pegar lo siguiente:
<b:if cond='data:blog.pageType == "item"'>

Pegar-aquí-código-AdSense

</b:if>

» Donde dice Pegar-aquí-código-AdSense pegamos el código que convertimos en el paso 3.§

5.§ Damos clic a Guardar plantilla y eso sería todo.

jueves, 22 de noviembre de 2012

Un FanBox para Twitter personalizable

AVISO
La API de Twitter cambió y ahora requiere autenticación para obtener los datos de los seguidores, por tal motivo éste y los demás fanbox para Twitter han dejado de funcionar. Si me entero de una solución u otra alternativa lo publicaré de inmediato.



Hemos visto con anterioridad dos FanBox para Twitter, que no son otra cosa mas que gadgets que muestran los seguidores que tenemos en Twitter. El primer FanBox para Twitter que vimos es proporcionado por Moopz, un buen gadget pero que no tiene muchas opciones de personalización. El segundo que vimos fue un FanBox para Twitter que muestra los avatares en forma deslizante, muy llamativo aunque no se parece tanto al FanBox tradicional de Facebook.

El siguiente FanBox para Twitter que veremos (llamado por su autor "Twitter Follow Box") también está hecho con jQuery, pero con dos ventajas, una es que tiene un aspecto más semejante al de Facebook, y otra es que podemos personalizarlo mucho más, cambiarle el color de los nombres, del título, del borde, del fondo, incluso ponerle una imagen de fondo si se desea.

Sin embargo, cualquiera de estas tres opciones sufren de un problema constante, y es que suelen no mostrarse de vez en cuando, así que antes de usar cualquiera de estos tres habrá que considerar ese problema, que habrá veces en las que no se vea y de repende se mostrará otra vez.

Este es el FanBox para Twitter del que hablamos.




Este gadget lo pondremos todo dentro de un elemento HTML/Javascript para evitar tocar la plantilla, así que sólo entra en Diseño | Añadir un gadget | HTML/Javascript y ahí pega el siguiente código:
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js' type='text/javascript'></script>

<style>.follow_box_widget{overflow: hidden; padding-left: 5px; padding-right: 5px; padding-top: 5px; background-color: #fff transparent; position: relative; margin: auto;}.follow_box{font-size: 11px; font-family: "lucida grande",tahoma,verdana,arial,sans-serif; color: #333; line-height: 1.28; text-align: left; direction: ltr;}.follow_box .follow_top{padding: 5px 10px 0px 5px; margin-bottom: 8px; min-width: 230px; overflow: hidden;}.follow_box .profileimage{float: left; width: 40px; height: 40px; padding: 0px; margin: 0 10px 4px 0;}.follow_box img{border: 0;}.follow_box a{cursor: pointer; color: #3B5998; text-decoration: none;}.follow_box a:hover{text-decoration: underline;}.follow_action{padding: 0 0 0 8px;}.follow_box .follow_action .name{line-height: 15px; font-size: 14px; font-weight: bold;}.follow_box .follow_button{margin: 5px 0 0;}.follow_box .total{min-width: 230px; overflow: hidden; display: block;}.follow_box .connections{padding: 5px 0 4px 0px; border-top: solid 1px #D8DFEA; border-bottom: 1px solid #CCC; min-height: 150px;}.follow_box .connections .connections_grid{padding-top: 5px; overflow: hidden;}.follow_box .clearfix{zoom: 1;}.follow_box .connections .connections_grid .grid_item{float: left; margin:0px; margin-right: 5px; margin-bottom: 8px; overflow: hidden; width: 50px;}.follow_box .connections .connections_grid .grid_item .name{font-size: 9px; color: gray; overflow: hidden; padding-top: 2px; text-align: center; white-space: nowrap;}.follow_box .connections .connections_grid .grid_item img{width: 48px; height: 48px;}.follow_box .follow_widget_footer{ cursor: default; width: 100%; min-width: 230px; overflow: hidden;}.follow_box .footer_border{ margin-top: 5px;}.follow_box .uiImageBlock{line-height: 14px;}.follow_box .follow_widget_footer .footer_logo{float: left; margin-right: 5px;}.follow_box .follow_widget_footer .footer_text{cursor: default; color: #808080; font-size: 9px; float: left;}.follow_box .follow_widget_footer .footer_text a.footer_text_link{color: #808080;}.follow_box .titlecase{text-transform:capitalize;}.dark{background: #333;}.dark a,.dark .total, .dark .connections .connections_grid .grid_item .name, .dark .follow_widget_footer .footer_text a.footer_text_link{color: #808080;}.dark .connections{border-bottom: 1px solid #444;}</style>
<script>
/*
* Twitter Follow Box jQuery Plugin
* http://jobyj.in/twitter-follow-box-widget/
* Copyright 2012, Joby Joseph
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
(function(a){a.fn.followbox=function(b){function f(a,b){if(a>100)a=100;var c=new Array;for(var d=0;d<a;d++){c.push(b[d])}var e=c.join();return e}var c=a(this);var d="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV-y76crGcjrratuOI4lbVbBGwf2Js1b3lATBAnR30LCzcOAeFc0R-LNSepI3MMmvwHL0xbsC9j_LphssHXr7t9fO-8cVNpzt8YrTWSzhmGQ8DktjNkdgVha3f0q6jbF3AkYkf6gDOZ1I/";var e=a.extend({user:"jobysblog",width:292,height:252,theme:"light",border_color:"#AAA",bg_color:"#fff",bg_image:"",title_color:"#3B5998",total_count_color:"#333",follower_name_color:"#BBB"},b);a.ajax({url:"http://api.twitter.com/1/users/lookup.json?screen_name="+e.user+"&include_entities=true",dataType:"jsonp",success:function(b){var g=e.width-2;var h=e.height-2;var i=e.height-115;var j=parseInt(e.width/55);var k=parseInt(i/69)+1;var l=j*k;c.html('<div class="follow_box_main" style="border: 1px solid #bbb; width: '+g+"px; height: "+h+'px;"><div class="follow_box_widget"><div class="follow_box"><div><div class="follow_top clearfix"><a href="http://www.twitter.com/'+e.user+'" target="_blank"><img class="profileimage img" src="'+b[0].profile_image_url_https+'" alt="'+b[0].name+'"></a><div class="follow_action"><div class="name_block"><a href="http://www.twitter.com/'+e.user+'" target="_blank"><span class="name titlecase">'+b[0].name.toLowerCase()+"</span> @"+b[0].screen_name+'</a></div><div class="follow_button"><iframe allowtransparency="true" frameborder="0" scrolling="no" src="//platform.twitter.com/widgets/follow_button.html?screen_name='+e.user+'&show_count=false&show_screen_name=false&lang=es" style="width:100px; height:20px;"></iframe></div></div></div><div class="connections"><span class="total"><span class="follow_box_follower_count">'+b[0].followers_count+'</span> personas siguen a <b class="titlecase">'+b[0].name.toLowerCase()+'</b></span><div class="connections_grid clearfix" style="height:'+i+'px;"></div></div></div><div style="height: 23px"><div class="follow_widget_footer"><div class="footer_border"><div class="clearfix uiImageBlock"><a class="footer_logo" target="_blank" href="http://jobyj.in/twitter-follow-box-widget"><img src="'+d+'"/></a><div class="footer_text"><a class="footer_text_link" target="_blank" href="http://jobyj.in/twitter-follow-box-widget">Twitter Social Plugin</a></div></div></div></div></div></div></div></div>');if(e.theme=="dark"){c.find(".follow_box_main").addClass("dark")}c.find(".follow_box_follower_count").text(c.find(".follow_box_follower_count").text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,"));if(a.browser.msie&&!a.support.boxModel)a(".follow_box .connections").css("padding-bottom","14px");if(e.theme=="custom"){c.find(".follow_box_main").css({"border-color":e.border_color,"background-color":e.bg_color,"background-image":'url("'+e.bg_image+'")'});c.find(".follow_box a").css({color:e.title_color});c.find(".follow_box .total").css({color:e.total_count_color})}a.ajax({url:"https://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name="+e.user,dataType:"jsonp",success:function(b){var d=f(l,b.ids);a.ajax({url:"https://api.twitter.com/1/users/lookup.json?user_id="+d+"&include_entities=true",dataType:"jsonp",success:function(b){for(var d=0;d<b.length;d++){var f=a.trim(b[d].name);var g=f.split(" ");var h='<div class="grid_item"><a href="http://twitter.com/'+b[d].screen_name+'" target="_blank"><img class="img" src="'+b[d].profile_image_url+'" alt=""><div class="name titlecase">'+g[0].toLowerCase()+"</div></a></div>";c.find(".connections_grid").append(h)}if(e.theme=="custom"){c.find(".connections .connections_grid .grid_item .name").css({color:e.follower_name_color})}}})}})}})}})(jQuery)
</script>

<script>
$(document).ready(function(){
$('#twitterfollowbox').followbox({
'user':'usuario',
'theme':'custom',
'height':'250', // Altura del gadget
'width':'287', // Ancho del gadget
'border_color':'#cccccc', // Color del borde
'bg_color':'#ffffff', // Color de fondo
'bg_image':'', // Imagen de fondo
'title_color':'#3B5998', // Color del título
'total_count_color':'#333333', // Color del contador
'follower_name_color':'#BDBDBB' // Color del nombre de los usuarios
});
});
</script>

<div id="twitterfollowbox" class="follow-box-container"> </div>
Pon tu nombre de usuario de Twitter donde se indica (sin la @) y listo.
Si ya tuvieras jQuery en la plantilla no pongas la primera línea que está en azul.
Si usas Mootools o Scriptaculous cambia esta parte:
$(document).ready(function(){
$('#twitterfollowbox').followbox({
Por esta otra:
jQuery.noConflict();
jQuery(document).ready(function(){
jQuery('#twitterfollowbox').followbox({
En color verde puedes ver dónde se personalizan las distintas áreas del gadget.
Con la altura y el ancho podemos hacer que se muestren más o menos avatares.
Si quisieras ponerle una imagen de fondo entonces cambia esta línea:
'bg_image':'', // Imagen de fondo
Por esta:
'bg_image':'URL de la imagen', // Imagen de fondo

Como puedes ver es un gadget al que se le pueden personalizar los colores de manera que se adecúe al diseño de nuestra plantilla, pero su talón de Aquíles al igual que los otros es el detalle de que por ratos podría dejar de verse, pero al ser un "gadget de vanidad" quizá no importe mucho eso.

Autor | Twitter Follow Box