I have a game with a punching bag where I want to incorporate an animation class each time the bag is clicked. Once the health meter hits zero, I intend to replace the bag image with one depicting a burst bag.
Things are running smoothly up until the point where I try to integrate the animation classes. As soon as I attempt to add animations, both functionalities stop working.
You can access the code at this link: https://codepen.io/damianocel/pen/mqXady
This is the HTML:
<div id="vue-app-one">
<!-- the bag images -->
<div id="bag" v-bind:class="[animationToggle ? activeClass : 'swingLeft',
'noSwing']" v-bind:class="{ burst: ended }"></div>
<!-- health meter -->
<div id="bag-health">
<div v-bind:class="[danger ? activeClass : 'dangerous', 'safe']" v-
bind:style="{ width: health + '%'}"></div>
</div>
<!-- the game buttons -->
<div id="controls">
<button v-on:click="punch" v-show="!ended">Punch it!</button>
<button v-on:click="restart">Restart game</button>
</div>
</div>
The problematical segment is here:
<div id="bag" v-bind:class="[animationToggle ? activeClass : 'swingLeft',
'noSwing']" v-bind:class="{ burst: ended }"></div>
// Above, I am attempting to link the noSwing CSS class by default and change it to swingLeft if the animationToggle property changes. However, upon inspection in dev tools, both classes get added, leading to no animation taking place. Can two class bindings be applied to one element like this?
// Additionally, I'm binding the ended property to the burst CSS class - this only functions when I remove the animationToggle binding and all corresponding CSS.
The Vue instance looks like this:
var one = new Vue({
el: '#vue-app-one',
data: {
health: 100, //initializing the health bar
ended: false, // initializing the state of being ended
punched: false, // doesn't currently need for now
danger: false, // is operational
animationToggle: false, // causing issues
activeClass: "" // need to initialize to avoid errors in the console
},
methods: {
punch: function(){
this.health -=10;
this.animationToggle= true;
if(this.health <= 0){
this.ended = true;
}
if(this.health <= 20){
this.danger = true;
}
else{
this.danger = false;
}
setTimeout(function () {
this.animationToggle = false
}.bind(this),500);
},
restart: function(){
this.health =100;
this.ended = false;
}
}
});
The relevant CSS:
#bag.noSwing {
width: 300px;
height: 500px;
margin: -80px auto;
background: url("https://3.imimg.com/data3/VM/TI/MY-18093/classical-heavy-
bag-250x250.png") center no-repeat;
background-size: 70%;
-webkit-animation-name: swingRight;
-webkit-animation-duration:1s;
-webkit-animation-iteration-count: 1;
-webkit-transition-timing-function: cubic-bezier(.11,.91,.91,.39);
-webkit-animation-fill-mode: forwards;
-webkit-transform-origin: center;
transform-origin: center;
}
#bag.swingLeft {
width: 300px;
height: 500px;
margin: -80px auto;
background: url("https://3.imimg.com/data3/VM/TI/MY-18093/classical-heavy-
bag-250x250.png") center no-repeat;
background-size: 70%;
-webkit-animation-name: swingLeft;
-webkit-animation-duration:1s;
-webkit-animation-iteration-count: 1;
-webkit-transform-origin: right;
transform-origin: right;
-webkit-transition-timing-function: cubic-bezier(.91,.11,.31,.69);
}
@keyframes swingLeft {
0% { -webkit-transform: rotate (0deg); transform: rotate (0deg); }
20% { -webkit-transform: rotate (-20deg); transform: rotate (-20deg); }
50% { -webkit-transform: rotate (20deg); transform: rotate (20deg); }
70% { -webkit-transform: rotate (-10deg); transform: rotate (-10deg); }
100% { -webkit-transform: rotate (0deg); transform: rotate (0deg); }
}
@keyframes swingRight {
0% { -webkit-transform: rotate (0deg); transform: rotate (0deg); }
20% { -webkit-transform: rotate (20deg); transform: rotate (20deg); }
50% { -webkit-transform: rotate (-20deg); transform: rotate (-20deg); }
70% { -webkit-transform: rotate (10deg); transform: rotate (10deg); }
100% { -webkit-transform: rotate (0deg); transform: rotate (0deg); }
}
#bag.burst {
background: url("http://i.imgur.com/oRUzTNx.jpg") center no-repeat;
background-size: 70%;
}
#bag-health {
width: 200px;
border: 2px solid #004;
margin: -80px auto 20px auto;
}
#bag-health div.safe {
height: 20px;
background: #44c466;
}
#bag-health div.dangerous {
background: #00ffff; }
Therefore, the issue lies in why the animations fail once the "punch it" button is pressed, why both the noSwing and swingLeft classes are appended, overriding the function that should change the background image to a burst bag when the health reaches zero.