Animaciones con CSS
Las transiciones son la forma de cambiar una o varias propiedades de una etiqueta con un efecto visual tal que ese cambio no se realiza de manera instantánea sino que demora un cierto tiempo y por lo tanto, parece estar animado. Una animación con CSS es algo similar que requiere de dos partes, primero establecer los datos de esa animación y luego, agregar las propiedades correspondientes en la etiqueta.
Para crear una animación se utiliza la regla @keyframes
donde se irán enumerando los pasos intermedios que existirán entre el inicio y el final. Esa regla debe tener un nombre que puede ser cualquiera pero irrepetible:
@keyframes NOMBRE { 0% { /* las reglas iniciales */ } 50% { /* las reglas al llegar a la mitad */ } 100% { /* las reglas finales */ } }
Una vez que tenemos definidas las reglas, nos falta agregar la propiedad animation
en el elemento. Esta propiedad es una forma resumida de agregar varias propiedades juntas, algunas de las cuales son obligatorias y otras optativas:
animation: name duration timing delay iteration direction fill play;
animation-name
es el nombre del keyframe que asociamos
animation-duration
es el tiempo que durará esa animación
animation-timing-function
define el modo en que se ejecutará ese cambio y los valores son los mismos que se usan en transition-timing-function
animation-delay
es opcional y establece el tiempo para que comience la animación y por defecto es cero
animation-iteration-count
es la cantidad de veces que se ejecutará (por defecto 1) pero podemos usar la palabra infinite para que se repita indefinidamente
animation-direction
indica como se repetirá la animación: normal lo hará secuencialmente (es el modo por defecto); alternate lo hará de modo alternado (normalmente en los intervalos impares y inversamente en los pares); reverse lo hará en sentido inverso y alternate-reverse lo hará de modo inverso en los intervalos impares y normalmente en los pares
animation-fill-mode
indica el estilo del elemento cuando no se está animando o la animación ha terminado; por defecto su valor es none pero admite otros valores: forwards especifica que al terminar, el elemento quedará con las propiedades definidas en el último intervalo; backwards especifica que al terminar, el elemento quedará con las propiedades definidas en el primer intervalo y both utilizará ambas
animation-play-state
indica si la animación se ejecuta (running) o esta pausada (paused)
Las animaciones parecen engorrosas porque son algo engorrosas pero de nada sirve quejarse, es lo que hay ... y vale la pena animarse y experimentar con ellas.
Empecemos con un ejemplo sencillo y aprovechemos que el valor de 0% puede ser reemplazado por la palabra from y el de 100% por la palabra to:
@keyframes recrojo { from { background-color:#fff; } to { background-color:#f00; } } .demo { animation-name: recrojo; animation-duration: 1s; animation-iteration-count: infinite; animation-direction: alternate; /* animation: recrojo 1s infinite alternate; */ background-color: #fff; border: 5px solid #ccc height: 100px; width: 200px; }
Como se ve, puesta de ese modo, la animación es permanente y puede ser todo lo compleja que se quiera aunque también es posible colocarla en el evento hover y de esa manera sólo es lanzada cuando colocamos el cursor encima:
@keyframes recimg { 0% { background-color: #f0ffff; background-position: 0% 50%; background-size: 0 0; font-size: 0em; } 50% { background-color: #d0dddd; } 100% { background-color: #fff; background-position: right 50%; background-size: 136px 200px; font-size:3em; } } .rectanguloimagen { background: #f0ffff url(http://i.imgur.com/viKMNl9.jpg) no-repeat scroll 50% 50%; background-size: 0 0; font-size: 0em; height: 200px; line-height: 200px; width: 450px; } .rectanguloimagen:hover { animation-direction: normal; animation-duration: 2s; animation-iteration-count: 1; animation-name: recimg; animation-fill-mode: forwards; }
Las animaciones CSS se pueden asociar a tres eventos de JavaScript:
animationstart se ejecuta cuando la animación comienza
animationiteration se ejecuta cuando la animación se repite
animationend se ejecuta cuando la animación se ha completado
En este ejemplo, al hacer click en el contenedor comienza la animación y cada vez que se repite, cambia de color:
<style> #rectangulomove { background: white; height: 100px; left: 5%; line-height: 100px; position: relative; width: 100px; } #rectangulomove.efecto { animation: 4s linear 0s alternate none infinite running recmove; } @keyframes recmove { from {left: 5%;} to {left: 85%;} } </style> <div class="demo rec"> <div id="rectangulomove" onclick="iniciar()">click</div> </div> <script> var elDIV = document.getElementById("rectangulomove"); elDIV.addEventListener("animationstart", iniciar); elDIV.addEventListener("animationiteration", repetir); elDIV.addEventListener("animationend", terminar); function iniciar() { // iniciamos la animación y eliminamos el texto elDIV.className = "efecto"; elDIV.innerText = ""; } function repetir() { // permutar colores cada vez que se ejecuta if(elDIV.style.backgroundColor=="yellow"){ elDIV.style.backgroundColor = "white"; } else { elDIV.style.backgroundColor = "yellow"; } } function terminar() { // como la animación es infinita nunca termina y este evento jamás se ejecuta } </script>
De aquí en más, no queda más remedio que salir a investigar un poco.
<style> @keyframes fade { 0% {opacity:0;} 10% {opacity:1;} 100% {opacity:0;} } @keyframes fall { 0% {top:10px;} 100% {top:290px;} } @keyframes accumulate { 0% {height:0px; opacity:0} 100% {height:10px; opacity:75;} } @keyframes spin { 0% {transform: rotate(-180deg) translate(0px, 0px);} 100% {transform: rotate(180deg) translate(10px, 75px);} } #container{ height: 300px; position: relative; width: 350px; } #snow div { position: absolute; top: -40px; animation-name: fall, fade, spin; animation-iteration-count: infinite; animation-direction: normal; animation-timing-function: ease-in; animation-name: fall, fade, spin; animation-iteration-count: infinite; animation-direction: normal; animation-timing-function: ease-in; } .snowflake { color: #fff; position: absolute; } .snowflake.f1 {font-size: 24px; left: 10px; animation-duration: 5s;} .snowflake.f2 {font-size: 48px; left: 290px; animation-duration: 7s;} .snowflake.f3 {font-size: 20px; left: 120px; animation-duration: 6s;} .snowflake.f4 {font-size: 32px; left: 160px; animation-duration: 4s;} </style> <div id="container"> <div id="snow" class="snow"> <div class="snowflake f1">❅</div> <div class="snowflake f2">❄</div> <div class="snowflake f3">❅</div> <div class="snowflake f4">❄</div> </div> </div>