Home > Back-end >  JavaScript animate element when key is pressed
JavaScript animate element when key is pressed

Time:06-21

I want to create a script where my HTML-div is being animated everytime a key is pressed. Here is my code:

let square = document.querySelector("div")

document.addEventListener("keydown", function(e) {
    square.style.animation = "shake 0.5s"
    square.style.animationIterationCount = "infinite"   
})

My problem is, if I exclude the last line where I set animation-iteration-count to "infinite", it works once, and if I press the button again, it won't work anymore. But if I set it to "infinite", the animation won't stop. How can I set it so that I see the animation every time I press a button, but without having the animation all the time? Thanks for any suggestion!

CodePudding user response:

The point is to add an animationend Event to div

let square = document.querySelector("div.square");

document.addEventListener("keydown", function(e) {
  square.classList.add('shake-square')
})
square.addEventListener("animationend", function(e) {
  square.classList.remove('shake-square')
});
.square {
  border: 1px solid black;
}

.shake-square {
  animation: shake 0.5s;
}

@keyframes shake {
  10%,
  90% {
    transform: translate3d(-1px, 0, 0);
  }
  20%,
  80% {
    transform: translate3d(2px, 0, 0);
  }
  30%,
  50%,
  70% {
    transform: translate3d(-4px, 0, 0);
  }
  40%,
  60% {
    transform: translate3d(4px, 0, 0);
  }
}
<div >
  this is a square
</div>

This example will keep shaking until the keyup event

If you only want to trigger shaking once on keydown, modify keydown event to

document.addEventListener("keydown", function (e) {
  if (!e.repeat)
    square.classList.add('shake-square')
})

CodePudding user response:

CSS animation Properties

Let CSS do the heavy lifting when doing simple animation in the DOM. Add a ruleset in CSS with a class selector and all of the animation properties in it. This is the shorthand of all the animation properties, see example CSS for the long version:

.anim {
  animation: shake 0.05s ease-in-out 0s infinite alternate forwards running;
}

Add the keyframes (see example CSS last ruleset @keyframes shake)

JavaScript Event Handling

Bind the document or window to both "keydown" and "keyup" events and call the same event handler animate(e):

document.onkeydown = animate;
document.onkeyup = animate;

By defining an event handler using Event Object properties/bubbling and specifying elements and/or actions we can have granular control of user interaction, this paradigm is called event delegation. Here are the key parts of the event handler animate(e):

// Determining the current triggered with Event property `Event.type`
const eType = e.type;
// Dictate the action taken according to current event ("keydown/up")
switch(eType) {
  /* 
  All animation is tied into the CSS ruleset `.anim {...}` so we just flip the
  .anim class on/off
  */
  case "keydown":
    square.classList.add('anim');
    break;
  case "keyup":
    square.classList.remove('anim');
    break;

Click the snippet area to get focus first, then press any key (you can keep key pressed as well like the deprecated "keypress" event)

document.onkeydown = animate;
document.onkeyup = animate;

function animate(e) {
  const square = document.querySelector('div');
  const eType = e.type;
  switch(eType) {
    case "keydown":
      square.classList.add('anim');
      break;
    case "keyup":
      square.classList.remove('anim');
      break;
    default:
      break;
  }
}
div {
  width: 128px;
  height: 128px;
  margin: 50px auto;
  border: 3px ridge blue;
}

.anim {
  animation-name: shake;
  animation-duration: 0.05s;
  animation-timing-function: ease-in-out;
  animation-delay: 0s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-fill-mode: forwards;
  animation-play-state: running;
}

@keyframes shake {
  from {
    transform: translateX(0px);
  }
  to {
    transform: translateX(64px);
  }
}
<div></div>

  • Related