domingo, 28 de octubre de 2012

Jugando con jQuery y las imágenes de fondo

Jugando un poco con jQuery para ... podría decir aprender pero prefiero decir la verdad. Jugando sólo por jugar.

Si quiero poner una imagen en la página pero es demasiado grande la puedo re-dimensionar perdiendo calidad pero también la puedo "cortar"; mostrarla como fondo dentro de un contenedor al que le doy un tamaño cualquiera ; de ese modo, sin importar su proporción, la veré o veré algo. Esta es una opción válida cuando se usan como elementos decorativos, por ejemplo miniaturas que adornan una página con resúmenes ya que la imagen en si no interesa porque se trata de un elemento estético.

Eso, es algo que puede hacerse usando sólo CSS:
.thumb {
background: transparent url(URL_imagen) no-repeat 50% 50%;
height: valorpx;
width: valorpx;
}
<div class="thumb"></div>


Pero quiero algo más, quiero que al poner el cursor encima ... pase algo: quiero que el fondo se mueva y al hacer click encima, se muestre completa pero dentro de ese contenedor así que empiezo haciendo un HTML más complicado; algo así:
<div id="cimage">
<div id="c-lefttop" rel="left top"></div>
<div id="c-righttop" rel="right top"></div>
<div id="c-leftbottom" rel="left bottom"></div>
<div id="c-rightbottom" rel="right bottom"></div>
</div>
Y reglas de estilo para eso:
<style>
#cimage {
background-color: transparent
background-image: url(URL_imagen);
background-position:50% 50%;
background-repeat: no-repeat;
background-size: auto;
height: valorpx;
margin: 0 auto;
position:relative;
width: valorpx;
transition: all 1s; /* con cada uno de los prefijos : -moz- -webkit- -o- -ms- */
}
#cimage.cover {background-size: cover;}
#cimage.cover div {display: none;}
#cimage div {
height:50%;
position:absolute;
width:50%;
}
#c-lefttop {left: 0;top: 0;}
#c-righttop {right: 0;top: 0;}
#c-leftbottom {left: 0;bottom: 0;}
#c-rightbottom {right: 0; bottom: 0;}
</style>
Y un poco de jQuery para que funcione:
<script>
$('#cimage div').live('mouseover', function() {
var pos = $(this).attr('rel');
$('#cimage').css('background-position',pos);
})
$('#cimage div').live('mouseout', function() {
$('#cimage').css('background-position','50% 50%');
})
$('#cimage').live('click', function(e) {
$('#cimage').toggleClass('cover');
})
</script>
La idea es simple; dentro del contenedor hay cuatro DIVs posicionados de modo absoluto y que ocupan un cuarto de ella; al poner el cursor encima de cada uno de esos pedacitos, se ejecuta una función que cambia la posición del fondo del contenedor y como este tiene una propiedad transition, parece ... moverse.

Al quitar el cursor, se restaura la posición al centro y al hacer click en la imagen se cambia la propiedad background-size por cover lo que hará que la imagen ocupe el 100% del contenedor, sin importar su tamaño o proporción.


Pero claro, hacer eso para cada imagen es un poco engorroso así que habría que simplificar el proceso; yo no quiero escribir tanta cosa, quiero poner cualquier imagen en un contenedor de cualquier tamaño; algo así:
<div class="eimage" style="width:valorpx;height:valorpx;background-image:url(URL_imagen);"></div>
Y para eso, necesito crear una función propia, ago que con jQuery es bastante fácil.

Lo que hará esto, es agregar las mismas funciones del primer ejemplo, a cualquier etiqueta con la clase eimage y ademá, le agregará esos DIVs internos que, ene ste caso, no serán cuatro sino nueve, es decir, al imagen quedará dividida en nueve rectangulos (3x3) :
<script>

$.fn.ejemplo = function() {
// la función la llamo ejemplo
$(this).each(function() {
// los nueve DIVs que agregaré
var html = "<div class='c1' rel='left top'></div><div class='c2' rel='50% top'></div><div class='c3' rel='right top'></div><div class='c4' rel='left 50%'></div><div class='c5' rel='50% 50%'></div><div class='c6' rel='right 50%'></div><div class='c7' rel='left bottom'></div><div class='c8' rel='50% bottom'></div><div class='c9' rel='right bottom'></div>";
$(this).append(html); // se agregan al contenedor
// y agregamos las funciones internas
var $this = $(this);
// al hacer click en la imagen, esta se expande
$this.click(function() {
$(this).toggleClass('cover');
});
$this.children().each(function(){
// si se coloca el puntero encima de alguno de las nueve divisiones, el fondo se desplaza
$(this).mouseover(function() {
var pos = $(this).attr('rel');
$this.css('background-position',pos);
})
// al quitar el puntero de encima, el fondo se restaura
$(this).mouseout(function() {
$this.css('background-position','50% 50%');
})
});
});
return $(this);
}

// y adosamos esa funcion ejemplo a toda etiqueta que tenga la clase eimage
$(document).ready(function() {
$('.eimage').ejemplo();
})

</script>
Faltaría el CSS que es similar al anterior.


<style>
.eimage {
background-color: transparent;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: auto;
margin: 0 auto;
position: relative;
-moz-transition: all 1s;
-webkit-transition: all 1s;
-o-transition: all 1s;
-ms-transition: all 1s;
transition: all 1s;
}
.eimage.cover { background-size: cover; }
.eimage.cover div { display: none; }
.eimage div { /* la imagen dividada en tercios */
height: 33%;
position: absolute;
width: 33%;
}
.c1 { left: 0; top: 0; }
.c2 { left: 33%; top: 0; }
.c3 { right: 0; top: 0; }
.c4 { left: 0; top: 33%; }
.c5 { left: 33%; top: 33%; }
.c6 { right: 0; top: 33%; }
.c7 { left: 0; bottom: 0; }
.c8 { left: 33%; bottom: 0; }
.c9 { right: 0; bottom: 0; }
</style>
El resultado sería esto:


Y el efecto, debería adaptarse a cualquier tamaño:


300x200 | 600x250 | 500x500 | 500x312

No hay comentarios:

Publicar un comentario