Animation de rotation continue CSS3 (comme un cadran de chargement)

120

J'essaie de reproduire un indicateur d'activité de style Apple (icône de chargement du cadran solaire) en utilisant une animation PNG et CSS3. L'image tourne et le fait en continu, mais il semble y avoir un délai après la fin de l'animation avant de faire la rotation suivante.

@-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;
    }

J'ai essayé de changer la durée de l'animation, mais cela ne fait aucune différence, si vous la ralentissez, disons 5 secondes, il est juste plus évident qu'après la première rotation, il y a une pause avant de tourner à nouveau. C'est cette pause dont je veux me débarrasser.

Toute aide est très appréciée, merci.

Gcoop
la source
14
Le code spécifique à Webkit n'en fait pas moins CSS3 .. étant donné qu'aucun des autres fournisseurs n'a fourni des fonctions égales à ce moment-là :)
19h
4
L'animation ne devrait-elle pas aller de 0 à 359? Si elle allait de 0 à 360, alors l'image à 0 serait lue deux fois, car l'image 0 et l'image 360 ​​seraient les mêmes ...
Brad Parks
1
@BradParks Par contre, si vous passez de 0 à 359, alors l'animation qui devrait avoir lieu à 359,5 est complètement ignorée. Dans la plupart des cas, le chevauchement de 0 et 360 sera si rapide qu'il sera imperceptible.
Blazemonger le
@Blazemonger pas nécessairement. Vous pouvez l'essayer vous-même dans un jsfiddle et voir que selon la durée de l'animation, il peut ne pas être si subtil.
Ilan Biala
1
tout ce truc à «359 degrés» est idiot - vous n'avez aucun contrôle sur l'étape de l'animation. en supposant une animation de 1 seconde avec 60 ips soit 6 degrés par image, vous devez donc vous arrêter à «354 degrés». mais comme je l'ai dit, vous n'avez pas de contrôle sur la fréquence d'images ici, donc c'est assez futile. J'imagine qu'une mise en œuvre intelligente pourrait détecter 0-360 et s'ajuster en conséquence. Je viens de multiplier le temps et l'angle par 100 - c'est à dire. De 0 ° à 36000 °, le problème théorique ne se produira donc que toutes les 100 rotations. mais j'ai découvert que vous allez avoir des problèmes d'animation quoi que vous fassiez de toute façon
Simon_Weaver

Réponses:

71

Votre problème ici est que vous avez fourni un -webkit-TRANSITION-timing-functionlorsque vous voulez un fichier -webkit-ANIMATION-timing-function. Vos valeurs de 0 à 360 fonctionneront correctement.

rrahlf
la source
Une erreur typique de copier-coller. Merci beaucoup! (J'ai en fait obtenu mon css de shareaholic et à cause de la propriété mal nommée, il a utilisé la easefonction de synchronisation par défaut ).
doekman
55

Vous remarquerez peut-être également un petit décalage car 0deg et 360deg sont au même endroit, donc cela va du point 1 dans un cercle au point 1. C'est vraiment insignifiant, mais pour y remédier, tout ce que vous avez à faire est de changer 360deg en 359deg

mon jsfiddle illustre votre animation:

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

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

De plus, ce qui pourrait ressembler le plus à l'icône de chargement de pomme serait une animation qui transforme l'opacité / la couleur des rayures de gris au lieu de faire pivoter l'icône.

Ilan Biala
la source
3
Votre JS Fiddle contient l'implémentation la plus succincte que j'ai vue pour une rotation d'image simple - parfaite (et merci pour la publication).
Philip Murphy
merci faites-moi savoir si vous avez besoin d'une autre aide, au fait, j'ai utilisé les préfixes du kit Web pour l'animation, mais vous devriez également inclure les préfixes mozilla car ils utilisent la règle -moz-css à la place.
Ilan Biala
vous pouvez également multiplier le temps et l'angle par 100 - c'est-à-dire. 0 degrés à 36000 degrés :-)
Simon_Weaver
@Simon_Weaver aurait toujours besoin d'être à 35999deg pour ne pas voir de double trame.
Ilan Biala
2
@IlanBiala sauf que je doute fort que votre carte graphique fonctionne à 720fps ;-) Il est impossible que vous sachiez quel est l'incrément entre les images sans connaître le framerate. Si quoi que ce soit, vous pouvez aussi bien mettre 348 degrés, car à une demi-seconde à 60fps, chaque image avancerait de 12 degrés. Je préfère simplement mettre 360 ​​et espérer que quelqu'un d'intelligent a programmé le navigateur pour qu'il s'ajuste automatiquement
Simon_Weaver
27

Vous pouvez utiliser une animation comme celle-ci:

-webkit-animation: spin 1s infinite linear;

@-webkit-keyframes spin {
    0%   {-webkit-transform: rotate(0deg)}
    100% {-webkit-transform: rotate(360deg)}
}
Kinglybird
la source
2
Solution géniale et facile!
TheLD
1

Votre code semble correct. Je suppose que cela a quelque chose à voir avec le fait que vous utilisez un .png et que la façon dont le navigateur redessine l'objet lors de la rotation est inefficace, ce qui provoque le blocage (sous quel navigateur testez-vous?)

Si possible, remplacez le .png par quelque chose de natif.

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

Chrome ne me donne aucune pause en utilisant cette méthode.

Alex
la source
Parfait, je suis à peu près sûr que votre hypothèse est correcte, mais j'utilise un PNG parce que mon icône de chargement n'est pas un cadran solaire, c'est un symbole de style nucléaire ... Il n'est pas nécessaire que je puisse le changer pour la méthode que vous suggérer - merci!
Gcoop
1

J'ai créé une petite bibliothèque qui vous permet d'utiliser facilement un throbber sans images.

Il utilise CSS3 mais retombe sur JavaScript si le navigateur ne le prend pas en charge.

// 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();

Exemple .

Alex
la source