Publicidad

lunes, 2 de mayo de 2011

Efecto de Rotacion con JQuery

Excelente Efecto de Rotacion con JQuery

En el siguiente tutorial vamos a crear un regulador de la imagen asimétrica, con un pequeño giro: al deslizar las fotos que poco les rotar y retrasar el desplazamiento de cada elemento. La forma inusual de la corredera es creado por la colocación de algunos elementos y el uso de bordes gruesos. También vamos a añadir una opción de reproducción automática y la funcionalidad de la rueda del ratón. 

1. Vamos a empezar con el código HTML!
En primer lugar, se ajustará a todos nuestros elementos de barra de desplazamiento en un contenedor con la clase "rm_wrapper":
<div class="rm_wrapper">
...
</div> 
Dentro de este contenedor tendremos un contenedor de la lista deslizante reales, algunos elementos de la máscara y la esquina, el título y un div oculto que contendrá todos los conjuntos de imágenes:
<div id="rm_container" class="rm_container">
 <ul>
  <li data-images="rm_container_1" data-rotation="-15">
   <img src="images/1.jpg"/>
  </li>
  <li data-images="rm_container_2" data-rotation="-5">
   <img src="images/2.jpg"/>
  </li>
  <li data-images="rm_container_3" data-rotation="5">
   <img src="images/3.jpg"/>
  </li>
  <li data-images="rm_container_4" data-rotation="15">
   <img src="images/4.jpg"/>
  </li>
 </ul>
 <div id="rm_mask_left" class="rm_mask_left"></div>
 <div id="rm_mask_right" class="rm_mask_right"></div>
 <div id="rm_corner_left" class="rm_corner_left"></div>
 <div id="rm_corner_right" class="rm_corner_right"></div>
 <h2>Fashion Explosion 2012</h2>
 <div style="display:none;">
  <div id="rm_container_1">
   <img src="images/1.jpg"/>
   <img src="images/5.jpg"/>
   <img src="images/6.jpg"/>
   <img src="images/7.jpg"/>
  </div>
  <div id="rm_container_2">
   <img src="images/2.jpg"/>
   <img src="images/8.jpg"/>
   <img src="images/9.jpg"/>
   <img src="images/10.jpg"/>
  </div>
  <div id="rm_container_3">
   <img src="images/3.jpg"/>
   <img src="images/11.jpg"/>
   <img src="images/12.jpg"/>
   <img src="images/13.jpg"/>
  </div>
  <div id="rm_container_4">
   <img src="images/4.jpg"/>
   <img src="images/14.jpg"/>
   <img src="images/15.jpg"/>
   <img src="images/16.jpg"/>
  </div>
 </div>
</div>
Así que las listas no ordenadas tendrá la primera serie de cuatro imágenes en la que cada elemento de la lista tiene algunos datos de los atributos de los conjuntos de la imagen y el grado de rotación. Vamos a utilizar esos datos para saber qué imágenes venir a continuación y la cantidad de cada imagen debe ser rotado.
La máscara de divs y esquina serán elementos absoluta de que vamos a colocar en la parte superior de la corredera, ligeramente girada con el fin de cubrir algunas áreas. Puesto que vamos a utilizar el mismo color de fondo de estos elementos como el color de fondo del cuerpo, vamos a crear la ilusión de las imágenes que se forma en cierto modo.
A continuación vamos a añadir los elementos para la navegación y los controles de reproducción automática:
<div class="rm_nav">
 <a id="rm_next" href="#" class="rm_next"></a>
 <a id="rm_prev" href="#" class="rm_prev"></a>
</div>
<div class="rm_controls">
 <a id="rm_play" href="#" class="rm_play">Play</a>
 <a id="rm_pause" href="#" class="rm_pause">Pause</a>
</div>

2. Echemos un vistaso al CSS:
En primer lugar, vamos a restablecer algunos estilos y definir las propiedades para el cuerpo. (Recuerde que, si queremos tener otro color de fondo, nos gustaría cambiar los colores de fondo y el borde de algunos de los elementos de nuestro control deslizante, también.)
@import url('reset.css');
body{
 background:#f0f0f0;
 color:#000;
 font-family: 'PT Sans Narrow', Arial, sans-serif;
 font-size:16px;
}
a{
 color:#000;
 text-decoration:none;
}
h1{
 padding:10px;
 margin:20px;
 font-size:40px;
 text-transform:uppercase;
 text-shadow:0px 0px 1px #fff;
 color:#333;
 background:transparent url(../images/line.png) 
repeat-x bottom left;
}

El contenedor principal tendrá el siguiente estilo:

.rm_wrapper{
 width:1160px;
 margin:0 auto;
 position:relative;
}

El contenedor para el regulador tendrá ningún desbordamiento oculta, lo que ayudará a dar forma a nuestro control deslizante ya que cortará los lados exteriores de la misma:

.rm_container{
 width:1050px;
 overflow:hidden;
 position:relative;
 height:530px;
 margin:0 auto;
}
   
El título tendrá el siguiente estilo:

.rm_container h2{
 background:transparent url(../images/lines.png)
repeat top left;
 padding:10px 30px;
 position:absolute;
 bottom:170px;
 right:0px;
 color:#000;
 font-size:36px;
 text-transform:uppercase;
 text-shadow:1px 0px 1px #fff;
}

Vamos a definir el ancho de la UL para ser más grande que el recipiente ya que queremos que el elemento de la lista flotar junto a la otra:

.rm_container ul{
 width:1170px;
}

Al dar un margen negativo a la izquierda y un borde grueso para el elemento de lista, que se superponen las imágenes y le cortó el lado derecho, para que creamos nuestras formas asimétricas girando los elementos a continuación. El color del borde será el mismo que el color de fondo del cuerpo (o el envase).

.rm_container ul li{
 float:left;
 margin-left:-80px;
 position:relative;
 overflow:hidden;
 width:310px;
 height:465px;
 border:30px solid #f0f0f0;
 border-width:50px 30px 0px 30px;
 background-color:#f0f0f0;
}
    
Vamos a la posición de las imágenes absolutamente:

.rm_container ul li img{
 position:absolute;
 top:0px;
 left:0px;
}

En lo que sigue vamos a estilo de la máscara y los elementos de esquina. Serán todos posicionados absolutamente y vamos a darles el color de fondo gris. Al girar ellos, vamos a hacer que aparezcan las imágenes como "forma":

.rm_mask_right, .rm_mask_left{
 position: absolute;
 height: 110px;
 background: #f0f0f0;
 width: 530px;
 bottom: -30px;
 left: 0px;
 -moz-transform:rotate(-3deg);
 -webkit-transform:rotate(-3deg);
 transform:rotate(-3deg);
}
.rm_mask_right{
 left:auto;
 right:0px;
 -moz-transform:rotate(3deg);
 -webkit-transform:rotate(3deg);
 transform:rotate(3deg);
}
.rm_corner_right, .rm_corner_left{
 background: #f0f0f0;
 position:absolute;
 width:200px;
 height:100px;
 bottom:0px;
 left:-65px;
 -moz-transform:rotate(45deg);
 -webkit-transform:rotate(45deg);
 transform:rotate(45deg);
}
.rm_corner_right{
 left:auto;
 right:-65px;
 -moz-transform:rotate(-45deg);
 -webkit-transform:rotate(-45deg);
 transform:rotate(-45deg);
} 

Los elementos de navegación se coloca a la izquierda ya la derecha del contenedor principal:

.rm_nav a{
 position:absolute;
 top:200px;
 width:38px;
 height:87px;
 cursor:pointer;
 opacity:0.7;
}
.rm_nav a:hover{
 opacity:1.0;
}
.rm_nav a.rm_next{
 background:transparent url(../images/next.png)
no-repeat top left;
 right:0px;
}
.rm_nav a.rm_prev{
 background:transparent url(../images/prev.png) 
no-repeat top left;
 left:0px;
}

La pausa / control de juego se colocará en la parte superior izquierda del contenedor principal:

.rm_controls{
 position:absolute;
 top:0px;
 left:-40px;
 height:20px;
}
.rm_controls a{
 cursor:pointer;
 opacity:0.7;
 padding-left:24px;
 font-size:16px;
 text-transform:uppercase;
 height:20px;
 float:left;
 line-height:20px;
}
.rm_controls a:hover{
 opacity:1.0;
}
.rm_controls a.rm_play{
 display:none;
 background:transparent url(../images/play.png) 
no-repeat center left;
}
.rm_controls a.rm_pause{
 background:transparent url(../images/pause.png)
no-repeat center left;
}

Y eso es todo el estilo!

3. El JavaScript:
La idea principal para la funcionalidad de control deslizante es añadir otra imagen antes de la actual con un grado de rotación ligeramente mayor que el elemento actual. A continuación, vamos a animar la rotación y que las imágenes aparecen nuevos.
Así que vamos a empezar por el almacenamiento en caché algunos elementos y comprobar si se trata de un navegador de necesidades especiales con el fin de hacer frente a algunas cuestiones:

//our 4 items
var $listItems   = $('#rm_container > ul > li'),
 totalItems  = $listItems.length,

 //the controls
 $rm_next  = $('#rm_next'),
 $rm_prev  = $('#rm_prev'),
 $rm_play  = $('#rm_play'),
 $rm_pause  = $('#rm_pause'),

 //the masks and corners of the slider
 $rm_mask_left = $('#rm_mask_left'),
 $rm_mask_right = $('#rm_mask_right'),
 $rm_corner_left = $('#rm_corner_left'),
 $rm_corner_right= $('#rm_corner_right'),

 //check if the browser is <= IE8
 ieLte8   = ($.browser.msie && parseInt
($.browser.version) <= 8),

A continuación vamos a definir nuestra función principal:

RotateImageMenu = (function() {
...
})();

RotateImageMenu.init(); 

Y luego definimos lo siguiente en nuestra función:

//difference of animation time between the items
var timeDiff   = 300,
 //time between each image animation (slideshow)
 slideshowTime  = 3000,
 slideshowInterval,
 //checks if the images are rotating
 isRotating   = false,
 //how many images completed each slideshow iteration
 completed   = 0,
 /*
 all our images have 310 of width and 465 of height.
 this could / should be dynamically calculated
 if we would have different image sizes.

 we will set the rotation origin at
 x = width/2 and y = height*2
 */
 origin    = ['155px', '930px'],
 init    = function() {
  configure();
  initEventsHandler();
 },
 //initialize some events
 initEventsHandler = function() {
  /*
  next and previous arrows:
  we will stop the slideshow if active,
  and rotate each items images.
  1  rotate right
  -1  rotate left
  */
  $rm_next.bind('click', function(e) {
   stopSlideshow();
   rotateImages(1);
   return false;
  });
  $rm_prev.bind('click', function(e) {
   stopSlideshow();
   rotateImages(-1);
   return false;
  });
  /*
  start and stop the slideshow
  */
  $rm_play.bind('click', function(e) {
   startSlideshow();
   return false;
  });
  $rm_pause.bind('click', function(e) {
   stopSlideshow();
   return false;
  });
  /*
  adds events to the mouse and left / right keys
  */
  $(document).bind('mousewheel', function(e, delta) {
   if(delta > 0) {
    stopSlideshow();
    rotateImages(0);
   }
   else {
    stopSlideshow();
    rotateImages(1);
   }
   return false;
  }).keydown(function(e){
   switch(e.which){
    case 37:
     stopSlideshow();
     rotateImages(0);
     break;
    case 39:
     stopSlideshow();
     rotateImages(1);
     break;
   }
  });
 },
 /*
 rotates each items images.
 we set a delay between each item animation
 */
 rotateImages  = function(dir) {
  //if the animation is in progress return
  if(isRotating) return false;

  isRotating = true;

  $listItems.each(function(i) {
   var $item     = $(this),
    /*
    the delay calculation.
    if rotation is to the right,
    then the first item to rotate is the first one,
    otherwise the last one
    */
    interval   = (dir === 1) ? i * timeDiff : 
(totalItems - 1 - i) * timeDiff;

   setTimeout(function() {
     //the images associated to this item
    var $otherImages  = $('#' + $item.data
('images')).children('img'),
     totalOtherImages = $otherImages.length;

     //the current one
     $img    = $item.children('img:last'),
     //keep track of each items current image
     current    = $item.data('current');
     //out of bounds
     if(current > totalOtherImages - 1)
      current = 0;
     else if(current < 0)
      current = totalOtherImages - 1;

     //the next image to show and its
     //initial rotation (depends on dir)
     var otherRotation = (dir === 1) ? '-30deg' : '30deg',
      $other   = $otherImages.eq(current).clone();

     //for IE <= 8 we will not rotate,
     //but fade out / fade in ...
     //better than nothing :)
     if(!ieLte8)
      $other.css({
       rotate : otherRotation,
       origin : origin
      });

     (dir === 1) ? ++current : --current;

     //prepend the next image to the <li>
     $item.data('current', current).prepend($other);

     //the final rotation for the current image
     var rotateTo  = (dir === 1) ? '80deg' : '-80deg';

     if(!ieLte8) {
      $img.animate({
       rotate : rotateTo
      }, 1200, function(){
       $(this).remove();
       ++completed;
       if(completed === 4) {
        completed = 0;
        isRotating = false;
       }
      });
      $other.animate({
       rotate : '0deg'
      }, 600);
     }
     else {
      $img.fadeOut(1200, function(){
       $(this).remove();
       ++completed;
       if(completed === 4) {
        completed = 0;
        isRotating = false;
       }
      });
     }

   }, interval );
  });

 },
 //set initial rotations
 configure   = function() {
  if($.browser.msie && !ieLte8)
   rotateMaskCorners();
  else if(ieLte8)
   hideMaskCorners();

  $listItems.each(function(i) {
   //the initial current is 1
   //since we already showing the first image
   var $item = $(this).data('current', 1);

   if(!ieLte8)
   $item.transform({rotate: $item.data('rotation') + 'deg'})
     .find('img')
     .transform({origin: origin});
  });
 },
 //rotates the masks and corners
 rotateMaskCorners = function() {
  $rm_mask_left.transform({rotate: '-3deg'});
  $rm_mask_right.transform({rotate: '3deg'});
  $rm_corner_left.transform({rotate: '45deg'});
  $rm_corner_right.transform({rotate: '-45deg'});
 },
 //hides the masks and corners
 hideMaskCorners  = function() {
  $rm_mask_left.hide();
  $rm_mask_right.hide();
  $rm_corner_left.hide();
  $rm_corner_right.hide();
 },
 startSlideshow  = function() {
  clearInterval(slideshowInterval);
  rotateImages(1);
  slideshowInterval = setInterval(function() {
   rotateImages(1);
  }, slideshowTime);
  //show the pause button and hide the play button
  $rm_play.hide();
  $rm_pause.show();
 },
 stopSlideshow  = function() {
  clearInterval(slideshowInterval);
  //show the play button and hide the pause button
  $rm_pause.hide();
  $rm_play.show();
 };

return {init : init};

Como habrá notado, vamos a tratar los navegadores más antiguos un poco diferente, para que el regulador funciona correctamente.
Y eso es todo! Realmente esperamos que hayan disfrutado el tutorial y como el resultado!

No hay comentarios:

Publicar un comentario