Animación de rotación continua CSS3 (como un reloj de sol de carga)

120

Estoy tratando de replicar un indicador de actividad al estilo de Apple (icono de carga del reloj de sol) usando una animación PNG y CSS3. Tengo la imagen girando y haciéndolo continuamente, pero parece haber un retraso después de que la animación ha terminado antes de que haga la siguiente rotación.

@-webkit-keyframes rotate {
  from {
    -webkit-transform: rotate(0deg);
  }
  to { 
    -webkit-transform: rotate(360deg);
  }
}
#loading img
{
    -webkit-animation-name:             rotate; 
    -webkit-animation-duration:         0.5s; 
    -webkit-animation-iteration-count:  infinite;
    -webkit-transition-timing-function: linear;
    }

He intentado cambiar la duración de la animación, pero no hace ninguna diferencia, si la ralentizas, digamos 5 s, es más evidente que después de la primera rotación hay una pausa antes de que vuelva a girar. Es esta pausa de la que quiero deshacerme.

Cualquier ayuda es muy apreciada, gracias.

Gcoop
fuente
14
El código específico de Webkit no lo hace menos CSS3 ... considerando que ninguno de los otros proveedores proporcionó funciones iguales en ese momento :)
19h
4
¿No debería la animación correr de 0 a 359? Si se ejecutara de 0 a 360, entonces el cuadro en 0 se reproduciría dos veces, ya que el cuadro 0 y el cuadro 360 serían iguales ...
Brad Parks
1
@BradParks Por otro lado, si pasa de 0 a 359, la animación que debería tener lugar en 359,5 se salta por completo. En la mayoría de los casos, la superposición de 0 y 360 será tan rápida que pasará desapercibida.
Blazemonger
@Blazemonger no necesariamente. Puede probarlo usted mismo en un jsfiddle y ver que, dependiendo de la duración de la animación, puede que no sea tan sutil.
Ilan Biala
1
Todo esto de los '359 grados' es una tontería: no tienes control sobre el paso de la animación. asumiendo una animación de 1 segundo con 60 fps que son 6 grados por cuadro, por lo que debe detenerse en '354 grados'. pero como dije, aquí no tienes control sobre la velocidad de fotogramas, por lo que es bastante inútil. Me imagino que una implementación inteligente podría detectar 0-360 y ajustarse en consecuencia. Simplemente multipliqué el tiempo y el ángulo por 100, es decir. 0 grados a 36000 grados, por lo que la falla teórica solo ocurrirá cada 100 rotaciones. pero descubrí que vas a tener fallas de animación sin importar lo que hagas de todos modos
Simon_Weaver

Respuestas:

71

Su problema aquí es que ha proporcionado un -webkit-TRANSITION-timing-functioncuando lo desea -webkit-ANIMATION-timing-function. Sus valores de 0 a 360 funcionarán correctamente.

rrahlf
fuente
Un error típico de copiar y pegar. ¡Muchas gracias! (De hecho, obtuve mi css de shareaholic y debido a la propiedad mal nombrada, usé la easefunción de sincronización predeterminada ).
doekman
55

También puede notar un pequeño retraso porque 0deg y 360deg son el mismo lugar, por lo que va desde el punto 1 en un círculo al punto 1. Es realmente insignificante, pero para solucionarlo, todo lo que tiene que hacer es cambiar 360deg a 359 grados

my jsfiddle ilustra tu animación:

#myImg {
    -webkit-animation: rotation 2s infinite linear;
}

@-webkit-keyframes rotation {
    from {-webkit-transform: rotate(0deg);}
    to   {-webkit-transform: rotate(359deg);}
}

Además, lo que podría parecerse más al icono de carga de Apple sería una animación que cambia la opacidad / color de las franjas de gris en lugar de girar el icono.

Ilan Biala
fuente
3
Su JS Fiddle contiene la implementación más sucinta que he visto para la rotación de imágenes simple: perfecta (y gracias por publicar).
Philip Murphy
gracias, avíseme si necesita alguna otra ayuda, por cierto, usé los prefijos de webkit para la animación, pero también debe incluir los prefijos de mozilla porque usan la regla -moz-css en su lugar.
Ilan Biala
también puede multiplicar el tiempo y el ángulo por 100, es decir. 0 grados a 36000 grados :-)
Simon_Weaver
@Simon_Weaver aún necesitaría ser 35999deg para no ver marcos dobles.
Ilan Biala
2
@IlanBiala excepto que dudo mucho que su tarjeta gráfica funcione a 720 fps ;-) Es imposible que sepa cuál es el incremento entre cuadros sin conocer la velocidad de cuadros. En todo caso, también puede poner 348 grados porque a medio segundo a 60 fps cada cuadro avanzaría 12 grados. Prefiero poner 360 y esperar que alguien inteligente programe el navegador para que se ajuste automáticamente
Simon_Weaver
27

Podrías usar una animación como esta:

-webkit-animation: spin 1s infinite linear;

@-webkit-keyframes spin {
    0%   {-webkit-transform: rotate(0deg)}
    100% {-webkit-transform: rotate(360deg)}
}
Kinglybird
fuente
2
¡Solución increíble y fácil!
TheLD
1

Tu código parece correcto. Supongo que tiene algo que ver con el hecho de que está utilizando un .png y la forma en que el navegador vuelve a dibujar el objeto al girar es ineficiente, lo que provoca el bloqueo (¿con qué navegador está probando?)

Si es posible, reemplace el .png con algo nativo.

ver; http://kilianvalkhof.com/2010/css-xhtml/css3-loading-spinners-without-images/

Chrome no me da pausas al usar este método.

Alex
fuente
Perfecto, estoy bastante seguro de que su suposición es correcta, sin embargo, estoy usando un PNG porque mi icono de carga no es un reloj de sol, es un símbolo de estilo nuclear ... No tiene que ser así, así que puedo cambiarlo al método que usted sugiero - ¡gracias!
Gcoop
1

Hice una pequeña biblioteca que te permite usar fácilmente un vibrador sin imágenes.

Utiliza CSS3 pero recurre a JavaScript si el navegador no lo admite.

// First argument is a reference to a container element in which you
// wish to add a throbber to.
// Second argument is the duration in which you want the throbber to
// complete one full circle.
var throbber = throbbage(document.getElementById("container"), 1000);

// Start the throbber.
throbber.play();

// Pause the throbber.
throbber.pause();

Ejemplo .

alex
fuente