2 votes

L'animation de rotation CSS dans une boucle while ne fonctionne qu'une seule fois

Je veux une balise div en html qui tourne, lorsque je clique dessus. Voici mon code

$(document).on('click', '.rotate', function() {
    degrees = 0;
    while (degrees >= (-1080)) {
        $(this).css({
            'transform': 'rotate(' + degrees + 'deg)'
        }).css({
            'transition': '3s'
        });
        degrees--;
    }
});

.rotate {
    position: relative;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: linear-gradient(magenta, blue, cyan, magenta);
    margin: 100px auto;
    line-height: 100px;
    cursor: pointer;
    border: 1px solid #fff;
}

.center {
    width: 30px;
    height: 30px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 0 3px 3px rgba(0, 0, 0, 0.7);
    z-index: 5;
}

Cela fonctionne bien au premier clic. Mais aux deuxième et suivants clics, cela ne fonctionne pas. Je ne sais pas pourquoi cela se produit.

4voto

Terry Points 7657

Il n'est pas nécessaire d'utiliser une boucle while : le CSS gérera les animations directement, et vous n'avez pas à définir l'angle à chaque étape.

La raison actuelle pour laquelle l'animation ne se lance pas à nouveau après le premier clic est que vous animez toujours vers -1080deg, ce qui signifie qu'après le premier passage, vous arrêterez de modifier la valeur, car elle est déjà à -1080deg : comme la valeur ne change jamais, l'animation CSS ne se relancera pas car le navigateur ne voit aucune différence, et choisira de ne rien tweener.

Ce que vous voulez, c'est décrémenter l'angle à chaque clic/compteur. Cela peut être fait en enregistrant le nombre de clics, puis en l'incrémentant à chaque clic. Ensuite, la quantité d'angle que vous voulez faire pivoter sera un multiple de ce compteur :

let count = 0;
$(document).on('click', '.rotate', function() {
  count++;
  degrees = -1080 * count;
  $(this).css({
    'transform': 'rotate(' + degrees + 'deg)'
  }).css({
    'transition': '3s'
  });
});

.rotate {
  position: relative;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: linear-gradient(magenta, blue, cyan, magenta);
  margin: 100px auto;
  line-height: 100px;
  cursor: pointer;
  border: 1px solid #fff;
}

.center {
  width: 30px;
  height: 30px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 0 3px 3px rgba(0, 0, 0, 0.7);
  z-index: 5;
}

2voto

Tomalak Points 150423

Vous ne voulez pas vraiment que jQuery fasse l'animation dans une boucle while pour commencer.

Laissez CSS faire l'animation, et utilisez jQuery uniquement pour connecter le gestionnaire d'événements et vous assurer que l'animation de rotation ne se superpose pas.

$(document).on('click', '.rotate:not(.rotating)', function () {
    var $this = $(this);
    $this.addClass("rotating");
    setTimeout(function () {
        $this.removeClass("rotating")
    }, 3000);
});

.rotate {
  height: 50px;
  width: 50px;
  text-align: center;
  border: 1px solid blue;
  padding: 5px;
  margin: 5px;
  display: inline-block;
} 
.rotating {
  transform: rotate(-1080deg);
  transition: 3s;
  border-color: red;
}

rotate 1
rotate 2
rotate 3
rotate 4

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X