Al Ex Tsm
Al Ex Tsm

Reputation: 2102

how to avoid re-scale on hover?

I have a div with two classes box and shake, both of them with attached animations. When mouse goes over the box I remove the shake class. When this happens I expect it to only stop shaking but it also plays the box animation from the beginning re-scaling the element. Why does this happen and how to avoid it?

Also I expected the box animation(scaling) to happen on document load. Why does it not happen? Can an element only have assigned one animation at a time? else does it overwrite?

$("#boxDiv").on("mouseenter", function(){
  $("#boxDiv").removeClass('shake');
});

$("#boxDiv").on("mouseleave", function(){
  $("#boxDiv").addClass('shake');
});
.box{
  display:block;
  width:100px;
  height:100px; 
  background:green;
  animation: scaleOnLoad .5s ease 1s;
}

@keyframes scaleOnLoad {
  0%{    
    transform: scale(.2);
  }
  100%{
    transform: scale(1);
  }
}

.shake {
  animation: shakeOnHover .1s linear infinite;
}

@keyframes shakeOnHover {
  0% { transform: rotate(1deg); }
  33% { transform: rotate(0deg); }
  66% {  transform: rotate(-1deg); }
  100% { transform: rotate(0deg); }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="boxDiv" class="box shake"></div>

Upvotes: 1

Views: 50

Answers (2)

rafaelcastrocouto
rafaelcastrocouto

Reputation: 12161

You can separate your animations with animationend event like this:

$(".box.loading").on("animationend", function(event){
  let box = $(event.target);
  box.removeClass('loading');
  box.addClass('shake');
});

$(".box").on("mouseenter", function(event){
  let box = $(event.target);
  if (!box.hasClass("loading")) {
    box.removeClass('shake');
  }
});

$(".box").on("mouseleave", function(){
  let box = $(event.target);
  if (!box.hasClass("loading")) {
    $(".box").addClass('shake');
  }
});
.box {
  display:block;
  width:100px;
  height:100px; 
  background:green;
}

.loading {
  animation: scaleOnLoad .5s ease;
}

@keyframes scaleOnLoad {
  0%{    
    transform: scale(.2);
  }
  100%{
    transform: scale(1);
  }
}

.shake {
  animation: shakeOnHover .1s linear infinite;
}

@keyframes shakeOnHover {
  0% { transform: rotate(1deg); }
  33% { transform: rotate(0deg); }
  66% {  transform: rotate(-1deg); }
  100% { transform: rotate(0deg); }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="box loading"></div>

Upvotes: 1

A Haworth
A Haworth

Reputation: 36656

From the description it sounds as though the boxDiv has both class box and class shake set.

As .shake comes after .box in the CSS any values set in .shake will overwrite any set in .box. You would expect this to happen if it were say setting background-color to red. So it is with the animation - the shake one overwrites the box one.

Hence, on loading the box shakes but doesnt scale. Try having boxDiv with just the box class to start with.

Then when you add and remove the box and shake classes the div will have only one.

Upvotes: 0

Related Questions