An issue arises in vue.js where the v class binding takes precedence over other bindings and fails to properly remove

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.

Answer №1

It's not recommended to have multiple class bindings on one element. Simplify your code by using a computed property to handle the logic of adding/removing classes:

computed: {
  className () {
      let classes= [];
          if (this.animationToggle){
             classes.push(this.activeClass)
          }
          else{
             classes.push('swingLeft')
          }
      return classes;

      }
  }
}


<div id="bag" :class="className"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unveiling the intricacies of CSS specificity

Struggling with the specificity of this particular CSS rule. Despite researching extensively, I still can't seem to grasp it. Can someone help me determine the specificity of the following: #sidebar h1, p em, p a:hover{ ... } ...

Fetching the exchanged messages between the sender and recipient - utilizing MongoDB, Express, and React for chat functionality

I am dealing with two collections named students and teachers in the mongodb database. The structure of a conversation between a student and a teacher involves arrays of messages within each object, as well as the IDs of the sender and receiver. I am seeki ...

"Disappearing Act: The Mysterious Vanishing of the JS

When I run my project using a node server, I have to execute three commands in the command prompt every time: npm install node server grunt serve I included a pagination directive from Git-hub in my project. However, every time I initialize the project ...

Jose authentication is encountering issues with verifying JWT

My Next.js/Clerk.js middleware setup looks like this: import { authMiddleware } from "@clerk/nextjs"; import { jwtVerify } from "jose"; export default authMiddleware({ publicRoutes: ["/", "/contact", "/pricin ...

Django DRF functions properly, however it returns an error when sending a response to an AJAX request

Successfully implemented an AJAX request using PUT in DRF. All functionalities are functioning correctly except for the error callback being triggered: DRF section: class ProductDataViewSet(viewsets.ViewSet): authentication_classes = [SessionAuthentic ...

Guide on transferring object between two $states using ui-router

Visit this link for more information Expected Behavior Upon logging in, selecting a Ticker button is expected to trigger the display of matching Tags for that specific Ticker. Actual Results However, upon clicking a Ticker button after logging in, the ...

Using Firebase with Angular 4 to fetch data from the database and show it in the browser

Currently diving into Angular 4 and utilizing Firebase database, but feeling a bit lost on how to showcase objects on my application's browser. I'm looking to extract user data and present it beautifully for the end-user. import { Component, OnI ...

Is there a way to retrieve the field names from a JSON array within a for loop?

Here is the structure of my Json array: var data = { "categories": { "category1": { "Name": "Maps", "Id": 3, "orderInList": 1 }, "category2": { "Name": "B ...

Converting Epoch timestamp to AM/PM format in a React render function

I am currently working on a personal project using React.js. I have successfully fetched an API, and one of the values returned is an Epoch timestamp. My goal is to display this timestamp in a human-readable format such as am/pm. The Epoch timestamp is dis ...

Exploring ways to customize the input color of Material UI TextField when it is disabled [Version: 5.0.8]

I am having trouble changing the border color and text color when an input is disabled. I have tried multiple variations, as seen below: const textFieldStyle = { '& label': { color: darkMode?'#1976d2':'', } ...

Insert an element at the start of a sorted array object

I am currently working on a small application that has the following structure: Posts -> Post -> Comments -> Comment. The Posts component sends a request for an array of posts sorted by date in descending order. Each post also fetches its comments through ...

When attempting to download a PDF file from Flask to the client, the file appears to be

I am encountering an issue with my Flask server that sends a PDF file using the send_file function. When testing this route on Postman, I am able to view and download the PDF successfully. However, when attempting to download it through my React frontend, ...

Other options besides re-flowing and repainting

After doing some research on various platforms like Stack Overflow, I've come across information stating that re-paints and re-flows can be quite taxing on a browser's resources. I am interested in learning about alternative CSS/JS techniques to ...

Troublesome CSS conflicts arise when using minified assets with AngularJS and Webpack

After transitioning my Angular project to the Webpack build system, I encountered issues with Angular Dependency Injection in the JS source code. Surprisingly, now I am facing JS errors that are targeting CSS files, leaving me completely bewildered about w ...

Ways to access text content in an HtmlTableCellElement

I am currently working on a jQuery tic-tac-toe project and facing an issue with iterating through the board to save the values of each cell in an array. I have tried using .text() and .value(), but both returned undefined index.html: <html> < ...

mobile-exclusive wordpress text area problem

There seems to be a padding issue that is only affecting mobile devices. https://i.stack.imgur.com/2Tbuc.png The cause of this problem has been somewhat identified, but the solution isn't clear without impacting the preview on computers. Here is th ...

Resolving a CSS Layout Dilemma: How to Overlay Sidebar on Wrappers

I've run into a challenge while attempting to position a sidebar over page wrappers. The issue with absolute positioning arises when the sidebar needs to align with the corner of the blue header. I have contemplated using JavaScript to maintain its cu ...

Tips for achieving a precise amount of boxes in each row

Is it possible to only have 5 boxes per line and then the next one goes to the next line using CSS? https://i.stack.imgur.com/L7vr4.png .box { border-color: #32ff00; border-width: 4px; border-style: dotted; width: 170px; height: 200px; fl ...

Error: The code is unable to access the '0' property of an undefined variable, but it is functioning properly

I am working with two arrays in my code: bookingHistory: Booking[] = []; currentBookings: any[] = []; Both arrays are populated later in the code. The bookingHistory array consists of instances of Booking, while currentBookings contains arrays of Booking ...

Tips for adding a CSS marker to the Videogular timeline at a designated time

My HTML player application allows users to search for a term and then displays the results along with the time when those words appear. By clicking on a specific sentence, the HTML player will start playing from that location. However, I would like to enha ...