En este caso, nuestro primer aporte del blog va a ser una pequeña librería que se acopla por separado a jquery y permite generar el efecto llamando al método bengala(data) de un objeto jquery $("#x") que funciona como contenedor del efecto.
Empezamos a ver el código con comentarios línea por línea. Esto es código abierto y no nos vamos a poner a publicar estas librerías de escaso tamaño comprimidas para no complicar la lectura de las mismas.
//Con esta linea acoplamos la libreria con la de jquery
jQuery.fn.bengala = function (data) {
//Capturamos todos los parametros para setear los valores
//default en el caso de que no fueran enviados
ch = data.corteHorizontal != undefined ? data.corteHorizontal : true;cp = data.cantidadPiezas != undefined ? data.cantidadPiezas : 15;
src = data.src != undefined ? data.src : "NOIMAGE";
io = data.initOpacity != undefined ? data.initOpacity : 0;
fo = data.finalOpacity != undefined ? data.finalOpacity : 1;
//Como la imagen es obligatoria, chequeamos que se haya indicado
//la ruta de la misma para poder continuar
if (src == "NOIMAGE")console.log("%s", "Es obligatorio definir la ruta de la imagen para poder cargarla.\nIt's mandatory to provide the source for the image to load.");
else{
//Guardamos la referencia al contenedor para poder acceder desde
//dentro de los otros elementos
container = this;
//Modificamos el estilo del contenedor al que le aplicamos el efecto
$(container).css({"text-align":"center", "overflow":"none"});
//Creamos una imagen temporal invisible para contener la imagen
//y poder obtener el ancho y alto mas tarde
$("<img src='"+src+"' id='original'/>").css({"display":"none"})
.appendTo(container);
//Esperamos a que la imagen cargue completamente para ejecutar
//el resto del código del efecto bengala
$("#original").load(function(){
//Obtenemos ancho y alto de la imagen de la temporal
var height = $("#original").css("height").replace("px","");var width = $("#original").css("width").replace("px","");
//Simple, dividimos el ancho o el alto segun el sentido del efecto
//en tantas partes como se haya definido
var division = ch ? (parseFloat(height) / cp) :
(parseFloat(width) / cp);
//El efecto incluye una variacion de opacidad, este es el promedio
//entre el valor inicial y el valor final
var mo = parseFloat(parseFloat(fo)+parseFloat(io)) / 2;
//Pasamos a crear cada una de las piezas del efecto dependiendo del sentido
for(var i = 0; i < cp ; i++){
//Corte horizontal
if (ch){
//Creamos un div para cada una de las piezas y lo agregamos
//al contenedor al que le aplicamos el efecto
$("<div class='pieza'/>").appendTo(container)
//Le agrego la foto de fondo e indico
//que parte se va a mostrar
.css({"background":"url("+src+")" + (i!=0?" 0 -"+parseFloat(division)*(i)+"px "+"no-repeat":""),
//Dependiendo del sentido del corte seteamos ancho y alto
"width":(width), "height":(parseFloat(division)+((i!=0?1:0))),
//Lo posicionamos en el centro de la pantalla
//(cambiar esto si no corresponde)
position:"absolute",top:(($(window).height() - $(this).outerHeight())/2)
+(parseInt(division*i)-((i!=0?1:0))),
left: ($(window).width() - $(this).outerWidth())/2,
//Seteamos la transparencia inicial
opacity:io,
//Eliminamos márgenes y paddings para que no
//haya espacios entre las piezas
margin:0,padding:0,
});
}
else{
$("<div class='pieza'/>").appendTo(container)
.css({"background":"url("+src+")" + (i!=0?"-"+parseFloat(division)*(i)+"px "+" 0 "+"no-repeat":""),
//Dependiendo del sentido del corte seteo ancho y alto
"width":parseFloat(division)+(i!=0?1:0), "height":height,
position:"absolute",
left:(($(window).width() - $(this).outerWidth())/2)+(parseInt(division*i)-((i!=0?1:0))),
top: (($(window).height() - $(this).outerHeight())/2),
opacity:io,
margin:0,
padding:0,
});
}
}
//En estas variables guardaremos los valores
//de posición de la primer pieza para colocar la img original
var divTop=-1;
var divLeft=-1;
//Una vez creados todos los elementos pasamos a darles movimiento,
//nuevamente tomando caminos distintos según el efecto
if (ch){
//Las piezas pares las ubicamos a la izquierda del centro
$(".pieza:even").css({left:"-=650"})
//La animacion los mueve a la derecha pasando el centro
.animate({left:"+=750", "opacity":mo},1500,
//y al terminar la esa animacion vuelven a la izquierda
//para acomodarse en el centro
function(){$(this).animate({left:"-=100", "opacity":fo}, 1500,//Cuando se terminan de acomodar, se eliminan todas las piezas
//para liberar espacio, memoria y elementos innecesarios en el body
//y se coloca la imagen original en la misma posicion
function(){
if (divTop==-1 && divLeft==-1){
divTop = parseFloat($(".pieza:first").css("top").replace("px",""));
divLeft = parseFloat($(".pieza:first").css("left").replace("px",""));
$(container).empty();
img.appendTo(container)
.css({position:"absolute",
left: divLeft,
top: divTop})
.show();
}
});});
//Las piezas impares las ubicamos a la derecha del centro
$(".pieza:odd") .css({left:"+=650"})
//La animacion los mueve a la izquierda pasando el centro
.animate({left:"-=750", "opacity":mo},1500,
//y al terminar la esa animacion vuelven a la derecha
//para acomodarse en el centro
function(){$(this).animate({left:"+=100", "opacity":fo}, 1500);});
//terminado esto se encuentran las 'cp' partes en el centro
}else{
//Con corte vertical funciona igual pero el
//desplazamiento es de arriba hacia abajo y viceversa
$(".pieza:even").css({top:"-=650"}).animate({top:"+=750", "opacity":mo},1500,
function(){$(this).animate({top:"-=100", "opacity":fo}, 1500,
//Cuando se terminan de acomodar, se eliminan todas las piezas
//para liberar espacio, memoria y elementos innecesarios en el body
//y se coloca la imagen original en la misma posicion
function(){
if (divTop==-1 && divLeft==-1){
divTop = parseFloat($(".pieza:first").css("top").replace("px",""));
divLeft = parseFloat($(".pieza:first").css("left").replace("px",""));
$(container).empty();
img.appendTo(container)
.css({position:"absolute",
left: divLeft,
top: divTop})
.show();
}
});});
$(".pieza:odd") .css({top:"+=650"})
.animate({top:"-=750", "opacity":mo},1500,
function(){$(this).animate({top:"+=100", "opacity":fo}, 1500);});
}
});
}
};
Para invocarlo debemos llamarlo de la siguiente manera.
$(document).ready(function(){
$("#padre").bengala({
src:"../images/images.jpg", //Obligatorio
initOpacity: 0, //Opcional, default 0
finalOpacity: 1, //Opcional, default 1
cantidadPiezas: 30, //Opcional, default 15
corteHorizontal: true //Opcional, default true
});
});
Esperamos que este efecto haya sido de su agrado y utilidad, seguramente tiene varios lugares donde se lo puede mejorar, y esperamos sus comentarios!
No hay comentarios:
Publicar un comentario