martes, 27 de marzo de 2012

Efecto mostrar imagen en porciones

La gama de efectos que se pueden lograr fácilmente con jQuery es interminable, hasta infinita si se tiene en cuenta que todo el tiempo se están creando mas y mas.
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