Animaciones iniciadas por scroll

Contenidos

Scroll viene del inglés y se refiere originalmente a un rollo de papel, pero hacer scroll down hoy en día es desplazarse para abajo, en el navegador hacer scroll down es avanzar en el contenido. Animaciones iniciadas por scroll serían esas que se activan conforme avanzamos en el sitio.

Existe un tipo de animación que es disparada por el ese desplazamiento para abajo y se conocen como animaciones de scroll down, de aquí en adelante las conoceremos como animaciones de scroll.

Para poder hacer estas animaciones con scroll se requieren de animaciones de css y gatillos de javascript.

Animaciones de CSS

Las animaciones de css constan de dos partes la propiedad animation que puede tener hasta 8 valores.

animation: name duration timing-function delay iteration-count direction fill-mode play-state;

Esta propiedad se le asigna al objeto que queremos animar, y la segunda son los key frames en donde establecemos el movimiento. Por ejemplo:

<article class="rectangulo"></article>
.rectangulo {
width: 200px;
height: 100px;
animation: movimiento 2s linear;
}

@keyframes movimiento {
from {left:1%;}
to {left:100%;}
}

Los keyframes “from” y “to” pueden ser cambiados por porcentajes desde 0% hasta 100% o se pueden mezclar, cómo se muestra en el ejemplo, en este caso “from” es igual a 0% y “to” 100% respectivamente. Se vería algo así:

@keyframes movimiento {
from, to {left:1%;}
 100% {left:100%;}
}

En el ejemplo anterior el movimiento empieza donde termina y el 50% es el lado opuesto de los dos primeros, entonces primero está a la izquierda luego el objeto se va derecha y al final regresa a la izquierda.

Una animación un poquito más compleja se vería de la siguiente forma:

.pelota {
animation: rebotes 5s 3 linear;
}

@keyframes rebotes {
0% {
left:-20%;
transform: rotate(0deg);
top: 100px;
}

10% {top: 90px;}
20% {top: 300px;}
30% {top: 100px;}
40% {top: 300px;}
50% {top: 120px;}
60% {top: 300px;}
70% {top: 140px;}
80% {top: 300px;}
90% {top: 160px;}

100% {
top: 300px;
left:120%;
transform: rotate(1080deg);
}
}

En la propiedad “animation” está el nombre de la animación, después tenemos dos números el primero “5s” que representan los segundos, el tiempo que va a durar la reproducción y un “3” que representa las iteraciones, cuantas veces se va a repetir la animación y por último la “función del tiempo de la animación” ( animation-timing-function ).

Los keyframes son más complicados y cada uno de ellos es un punto de quiebre en el movimiento del objeto:

Librerías

Si bien es divertido jugar con las animaciones de css a veces no tenemos el tiempo o puede ser que también carezcamos de la experiencia para animar lo que queremos… O simplemente ya alguien lo hizo mejor. Y esto no sólo aplica para css…

Existen varias librerías que se pueden utilizar como WOW y como AOS que además tiene su propia biblioteca de js. Pero acá utilizaremos Animate.css para facilitarnos la vida.

Para descargar es obvio que se hace en el botón que dice “Download Animate.css” lo que no es obvio hasta que lo piensas un poco es que las opciones que están en el “select” son las clases que hay que establecer para ejecutar la animación. Lo que si es cierto es que cuando carguemos el sitio todas las animaciones se van a ejecutar al mismo tiempo. Por esa razón vamos a necesitar javascript para “racionar” las animaciones.

Javascript

Para poder empezar con esto vamos a recurrir a dos librerías de javascript, la primera jQuery para los funcionamientos y la otra Modernizr que la usaremos para detectar si hay un dispositivo “touch”.

$(function() {

  var $window           = $(window),
      win_height_padded = $window.height() * 1.1,
      isTouch           = Modernizr.touch;

  if (isTouch) { $('.revealOnScroll').addClass('animated'); }

  $window.on('scroll', revealOnScroll);

  function revealOnScroll() {
    var scrolled = $window.scrollTop(),
        win_height_padded = $window.height() * 1.1;

    // Motrar...
    $(".revealOnScroll:not(.animated)").each(function () {
      var $this     = $(this),
          offsetTop = $this.offset().top;

      if (scrolled + win_height_padded > offsetTop) {
        if ($this.data('timeout')) {
          window.setTimeout(function(){
            $this.addClass('animated ' + $this.data('animation'));
          }, parseInt($this.data('timeout'),10));
        } else {
          $this.addClass('animated ' + $this.data('animation'));
        }
      }
    });
    // Esconder...
   $(".revealOnScroll.animated").each(function (index) {
      var $this     = $(this),
          offsetTop = $this.offset().top;
      if (scrolled + win_height_padded < offsetTop) {
        $(this).removeClass('animated fadeInUp flipInX lightSpeedIn')
      }
    });
  }

  revealOnScroll();
});

El $(function() {}); que envuelve todo el código es para asegurarnos que la función se ejecute inmediatamente después de cargar el último elemento del DOM.

Luego creamos tres variables, la primera, “$window” contiene el selector “window” para facilitar la selección de la ventana, la segunda, “win_height_padded” que detecta el alto de la ventana y lo multiplica por 1.1 que le agrega un 10% al alto y la tercera “isTouch” la detección del “touch”.

El if en el renglón 7 en caso de “touch” le establece a todos los objetos que tienen la clase “revealOnScroll” la clase “animated” que es la que entrega la duración y hace que la animación siga las reglas del movimiento para adelante y para atrás por igual.

CSS necesario

.animated {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}

En el renglón once inicia la función “revealOnScroll” que va a dar la posibilidad que se ejecute una animación y también que se esconda.

Seguido hay dos variables, la primera variable nos establece la posición de la barra del scroll en pixeles y la segunda variable de nuevo el alto de la ventana más el 10%.

Seguido entre el renglón 16 al 29 se hace una selección en la que se toman todos los elementos que tienen la clase “revealOnScroll” pero tiene una excepción para los objetos que tienen la clase “animated”. También hay un each que es una iteración para la creación del arreglo que va a darnos las posiciones de todos los objetos.

    $(".revealOnScroll:not(.animated)").each(function () {
      var $this     = $(this),
          offsetTop = $this.offset().top;

      if (scrolled + win_height_padded > offsetTop) {
        if ($this.data('timeout')) {
          window.setTimeout(function(){
            $this.addClass('animated ' + $this.data('animation'));
          }, parseInt($this.data('timeout'),10));
        } else {
          $this.addClass('animated ' + $this.data('animation'));
        }
      }
    });

Dentro hay otras dos variables, la primera establece la selección del objeto a partir de un “this” (esto o este) que habla del objeto seleccionado y la segunda variable establece las coordenadas del top del objeto en cuestión.

Aparece una condición: Si los pixeles del avanzados por la barra de scroll sumados a el tamaño de la ventana más el 10% son mayor que el top del objeto.

Y ya por último para establecer cuando se muestra el objeto, con otra condicional se establece que si hay algún dato guardado en el elemento con “.data()”, entonces se le establece un “time out” pero si no se le agrega la clase “animation”, esta es la que ejecuta la animación como tal de la librería “Animate.css”.

Escondiendo y terminando

$(".revealOnScroll.animated").each(function (index) {
      var $this     = $(this),
          offsetTop = $this.offset().top;
      if (scrolled + win_height_padded < offsetTop) {
        $(this).removeClass('animated fadeInUp fadeInDown flipInX lightSpeedIn tada shake zoomInUp zoomInDown') //Clases para la animación dentro del parentesis
      }
 });

Me voy a enfocar e la parte del condicionante porque lo demás es similar a lo ya explicado antes, en el paréntesis de la condicionante establecemos que si el pixelaje de la barra de scroll es menor al top del objeto se le remuevan las clases de la animación.

Estas son las clases de las aminaciones que vemos en la librería de “Animate.css” en el menú dropdown del sitio.

Pero veamos ya la animación funcionando:

ver ejemplo

Conclusión

Todo este ensayo de ejecutar una animación css con javascript es, por supuesto una de tantas formas, desde las ya terminadas como puede ser el ejemplo de AOS que ya viene horneada, empaquetada y lista para servirse o como todo el texto anterior que puede hacerse desde crear las animaciones css y a partir de jQuery construir todo el comportamiento.

Espero sea útil esta guía, si tienen alguna duda o un aporte, por favor dejen un comentario… Enjoy!

Referencias

http://blog.webbb.be/trigger-css-animation-scroll/

Imágenes: Naranja, Limones, Lima, Refresco de naranja.

otros artículos
¿Estás listo para asesorarte sobre tus necesidades web?
Ponte en contacto hoy y recibe una consulta gratuita.

¿Estás listo para asesorarte sobre tus necesidades web?

Ponte en contacto hoy y recibe una consulta gratuita.

Solicite consulta o cotización

Request a consultation or quote