Brixsta
Brixsta

Reputation: 625

JavaScript CSS animation only works once

I have an bank application that has a super cool hand come down and drop a coin into a piggy bank. Problem is, the hand only drops the coin once then stops working.

Here is my code:

* {
  margin:0px;
  padding:0px;
}

body {
  background-image:url('../images/bg.png');
}

@keyframes moveDown {
  0% {}
  100% {margin-top:-220px;}
}

@keyframes fadeIn {
  0% {opacity:0;}
  90%{opacity:1}
  100%{opacity:0;}
}

#hand {
  height:300px;
  width:300px;
  position:absolute;
  left:50%;
  margin-left:-120px;
  margin-top:-350px;
  background-image:url("../images/hand.png");
  opacity:0;
}

#pigBox {
  margin-left:auto;
  margin-right:auto;
  height:600px;
  width:500px;
  margin-top:250px;
  position:relative;

  img {
    margin:0px 50px;
  }

}

input[type=text] {
  float:left;
  display:block;
  font-size:2em;
  width:500px;
  border-radius:10px;
  border:solid 2px pink;
  margin-top:10px;
  font-family: 'Gochi Hand', cursive;
  text-align:center;
  padding:2px;
}

#deposit {
  float:left;
  display:block;
  font-family: 'Gochi Hand', cursive;
  font-size:2em;
  clear:left;
  width:200px;
  margin:10px 25px;
  border-radius:10px;
  background-color:pink;
  border:solid 2px pink;
  padding:2px;
  cursor:pointer;

  &:hover {
    background-color:white;
  }
}

#withdraw {
  float:left;
  display:block;
  font-family: 'Gochi Hand', cursive;
  font-size:2em;
  width:200px;
  margin:10px 25px;
  border-radius:10px;
  background-color:pink;
  border:solid 2px pink;
  padding:2px;
  cursor:pointer;

  &:hover {
    background-color:white;
  }
}

label {
  text-align:center;
  display:block;
  font-family: 'Gochi Hand', cursive;
  font-size:2.5em;
  border-radius:10px;
  width:300px;
  margin-left:100px;
  margin-right:100px;
  margin-top:5px;
  margin-bottom:-15px;
}

document.getElementById('balance').value = "1000"

var balance = document.getElementById('balance').value;
var deposit = document.getElementById('deposit');
var withdraw = document.getElementById('withdraw');
var hand = document.getElementById('hand');

deposit.addEventListener('click', depositCash);
withdraw.addEventListener('click', withdrawCash);

function depositCash() {
  var depositAmt = prompt('How much would you like to deposit?');

  if(depositAmt != Number(depositAmt)) {
    return alert('Please enter a valid integer.');
  }
  else if (Number(depositAmt) < 0) {
    return alert('Please enter a positive integer.');
  }

  hand.style.animation = 'moveDown 1.5s ease-in-out, fadeIn 1.5s ease-in-out';
  balance = Number(balance) + Number(depositAmt);
  document.getElementById('balance').value = balance;
}

function withdrawCash() {
  var withdrawAmt = prompt('How much you you like to withdraw?');

  if(withdrawAmt != Number(withdrawAmt)) {
    return alert('Please enter a valid integer.');
  }
  else if (Number(withdrawAmt) < 0) {
    return alert('Please enter a positive integer.');
  }
  else if(withdrawAmt > balance) {
    return alert("Your balance isn't large enough to withdraw that amount!")
  }


  balance = Number(balance) - Number(withdrawAmt);
  document.getElementById('balance').value = balance;
}

<section id="pigBox">
      <div id="hand"></div><!-- end of hand-->
      <img src="images/pig.png" />
      <label>Balance: </label><input type="text" id="balance" />
      <button id="deposit"> Deposit </button>
      <button id="withdraw"> Withdraw </button>
  </section><!-- end of pigBox-->

<a href="http://imgur.com/FxwmGFi"><img src="http://i.imgur.com/FxwmGFi.png" title="source: imgur.com" /></a>

notice the hand.style animation when you deposit money into the piggy bank.

Any thoughts guys?

Thank you!

Upvotes: 4

Views: 9234

Answers (4)

Abel
Abel

Reputation: 1

A quick and simple solution with animated svgs is to Load the image with a random query like for example;

Assuming a javascript environment with an existing function loadImage,

loadImage('image.svg?u='+new Date().getMilliseconds());

You trick the browser into thinking its not the same file and animation begins.

Upvotes: 0

Tejas Chavan
Tejas Chavan

Reputation: 11

Faced the same issue.

For those using jQuery, here is my solution.

I realized that if we string together .addClass().removeClass(), jQuery interprets and negates the two commands, resulting in no change. So I suggest a workaround using Timeout function:

let animationTimeout

clearTimeout( animationTimeout )

$('#animatedElement').addClass('animation')

animationTimeout = setTimeout(() => {$('#animatedElement').removeClass('animation')}, animationDuration)

Upvotes: 0

Serge Andreev
Serge Andreev

Reputation: 310

You should delete style for Hand after animation (add 3 line to your script):

...

var myHand = false;

deposit.addEventListener('click', depositCash);

withdraw.addEventListener('click', withdrawCash);

function depositCash() {

if (myHand) clearTimeout(myHand);

...

hand.style.animation = 'moveDown 1.5s ease-in-out, fadeIn 1.5s ease-in-out';

balance = Number(balance) + Number(depositAmt);

document.getElementById('balance').value = balance;

myHand = setTimeout(function(){hand.style.animation = '';}, 2000);

}

Upvotes: 2

John Vandivier
John Vandivier

Reputation: 2426

It's because CSS animations don't automatically restart. In particular because you didn't define a time loop, so it just executes once.

One approach is for you to use .addClass('x').removeClass('x') to retrigger an animation defined on class X.

.addClass() is jQuery of course. You can do the same in vanilla JS using, for example, hand.className += ' my-animation'; and resetting at the top of the method as per below.

//ref: https://css-tricks.com/restart-css-animation/

document.getElementById('balance').value = "1000"

var balance = document.getElementById('balance').value;
var deposit = document.getElementById('deposit');
var withdraw = document.getElementById('withdraw');
var hand = document.getElementById('hand');

deposit.addEventListener('click', depositCash);
withdraw.addEventListener('click', withdrawCash);

function depositCash() {
  hand.className = 'randoImage';
  var depositAmt = prompt('How much would you like to deposit?');

  if(depositAmt != Number(depositAmt)) {
    return alert('Please enter a valid integer.');
  }
  else if (Number(depositAmt) < 0) {
    return alert('Please enter a positive integer.');
  }

  hand.className += ' my-animation';
  balance = Number(balance) + Number(depositAmt);
  document.getElementById('balance').value = balance;
}

function withdrawCash() {
  var withdrawAmt = prompt('How much you you like to withdraw?');

  if(withdrawAmt != Number(withdrawAmt)) {
    return alert('Please enter a valid integer.');
  }
  else if (Number(withdrawAmt) < 0) {
    return alert('Please enter a positive integer.');
  }
  else if(withdrawAmt > balance) {
    return alert("Your balance isn't large enough to withdraw that amount!")
  }


  balance = Number(balance) - Number(withdrawAmt);
  document.getElementById('balance').value = balance;
}
.randoImage {
  width: 25px;
  height: 25px;
  background-image: url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7);
}

* {
  margin:0px;
  padding:0px;
}

@keyframes moveDown {
  0% {}
  100% {margin-top:-220px;}
}

@keyframes fadeIn {
  0% {opacity:0;}
  90%{opacity:1}
  100%{opacity:0;}
}

#hand {
  height:300px;
  width:300px;
  position:absolute;
  left:50%;
  margin-left:-120px;
  margin-top:-350px;
  /*background-image:url("../images/hand.png");*/
  opacity:0;
}

#pigBox {
  margin-left:auto;
  margin-right:auto;
  height:600px;
  width:500px;
  margin-top:250px;
  position:relative;

  img {
    margin:0px 50px;
  }

}

input[type=text] {
  float:left;
  display:block;
  font-size:2em;
  width:500px;
  border-radius:10px;
  border:solid 2px pink;
  margin-top:10px;
  font-family: 'Gochi Hand', cursive;
  text-align:center;
  padding:2px;
}

#deposit {
  float:left;
  display:block;
  font-family: 'Gochi Hand', cursive;
  font-size:2em;
  clear:left;
  width:200px;
  margin:10px 25px;
  border-radius:10px;
  background-color:pink;
  border:solid 2px pink;
  padding:2px;
  cursor:pointer;

  &:hover {
    background-color:white;
  }
}

#withdraw {
  float:left;
  display:block;
  font-family: 'Gochi Hand', cursive;
  font-size:2em;
  width:200px;
  margin:10px 25px;
  border-radius:10px;
  background-color:pink;
  border:solid 2px pink;
  padding:2px;
  cursor:pointer;

  &:hover {
    background-color:white;
  }
}

label {
  text-align:center;
  display:block;
  font-family: 'Gochi Hand', cursive;
  font-size:2.5em;
  border-radius:10px;
  width:300px;
  margin-left:100px;
  margin-right:100px;
  margin-top:5px;
  margin-bottom:-15px;
}

.my-animation {
  animation: moveDown 1.5s ease-in-out, fadeIn 1.5s ease-in-out;
}
<section id="pigBox">
      <div class="randoImage" id="hand"></div><!-- end of hand-->
      <img class="randoImage" />
      <!--<img src="images/pig.png" />-->
      <label>Balance: </label><input type="text" id="balance" />
      <button id="deposit"> Deposit </button>
      <button id="withdraw"> Withdraw </button>
  </section><!-- end of pigBox-->

Upvotes: 4

Related Questions