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

Using a background image in CSS

I'm having an issue with this code. It doesn't seem to be displaying anything on the screen: <!DOCTYPE HTML> <head> <title> CSS(lab2) </title> <meta charset="UTF-8"> <style type = "text/css"> ...

Is there a way to move a placeholder to a small label in the top left corner when an input field is being used?

I've been searching for functional code, but everything I've tried so far hasn't worked. Does anyone have expertise in creating this animation using React? ...

The jquery error NS_ERROR_XPC_BAD_CONVERT_JS is causing issues on Google Chrome while working fine on Firefox

Currently, I am utilizing jQuery to dynamically add fields to a form. These are considered "repeatable" fields since users can click an "add more" button. Here is the code snippet: $(".add-attacker-scores").click(function() { count = count + 1; ...

Tips for retrieving the value of a tag within a modal popup

I am trying to extract the value from an 'a' tag using the code below. <div class="modal fade show" id="myModal" tabindex="-1" role="dialog" aria- labelledby="myModalLabel" style="display: block;"> <div class="modal-d ...

I have chosen Next.js for my frontend development, while our backend developer is crafting the API in Express and MySQL. I am looking for ways to secure and protect the

As a beginner frontend developer learning Next.js, I've been tasked with integrating authentication into our app. The backend developer is working on creating the API using Express and MySQL. After successful login, an accessToken is received. However ...

Solidjs: Implementing a Map in createStore does not trigger updates upon changes

As a beginner in solidjs, I might have missed something important. In the code snippet below, I am trying to understand an issue: const [state, setState] = createStore({ items: new Map() }); // e.g. Map<number, string> In a component, suppose I want ...

Troubleshooting Node.js TypeScript breakpoints in Visual Studio Code

I've attempted multiple solutions, but none seem to be working for me. Although the code is running, I'm having trouble setting breakpoints and debugging it. Can you offer any assistance? Below is the configuration script I've tried in VSCo ...

Why are the variables not reflecting the changes when an event is triggered?

I'm a beginner in programming and would really appreciate some guidance. Why are my variables not updating when I click the button?? Here is the HTML code snippet: <h1>NIM</h1> <p>Welcome to a simple edition of the game NIM</p& ...

Ways to combine and run the outcomes of several functions with Lodash

Imagine you have two distinct functions (or more) that take one argument from an executor and return the result object. Let's illustrate this with an example: const style_1 = theme => ({ header : { color : theme.primary } }) const sty ...

Emphasizing the text while making edits to an item within the dhtmlx tree

Whenever I need the user to rename an item on the tree, I trigger the editor for them: tree.editItem(tree.getSelectedItemId()); However, I want the text in the editor to be automatically selected (highlighted). Currently, the cursor is placed at the end ...

Manipulating AngularJS with Sass variables

Currently, I am developing a theme changer using AngularJS and I'm facing difficulty in figuring out how to swap one SASS file with another (both containing variables) when the user changes their theme. I understand that once SASS is compiled to CSS, ...

The styled-components in CSS are causing some issues with the color themes

Link to Image Showing the Issue. I have implemented themes and colors in my React application successfully, but I am encountering a peculiar problem with the labels. Whenever I switch the theme from green to blue and then back to green, focusing on the inp ...

XMLHttpRequest Error: The elusive 404 code appears despite the existence of the file

This is the organization of my project files: The folders Voice, Text, and Template are included. https://i.stack.imgur.com/9un9X.png When I execute python app.py and navigate to localhost http://0.0.0.0:8080/, the index.html page is displayed with conte ...

"Exploring the World of Mobile Development and Screen Size

Currently, I am in the process of creating a basic mobile website that can be accessed through a QR code leading to the page linked below. However, I have encountered an issue where viewing it on my Android or Apple phone results in excess width. Any advic ...

Is `h` equal to `createVNode` function?

Both h and createVNode are exposed from vue. The documentation on this page seems to imply that they are interchangeable: The h() function is a utility to create VNodes. It could perhaps more accurately be named createVNode(). However, replacing h with ...

Sharing and displaying images on Sails JS platform

Using Sails JS, I am attempting to upload an image and display it in a view. Queries: The uploaded image is located in .tmp/uploads, how can I retrieve it from a view? Is there a method to access the uploaded image? The image's name is altered in ...

Run some code and then enter interactive mode

Is there a method to run certain code (from a file or a string) before entering interactive mode in node.js? For instance, if I have script called __preamble__.js with the following content: console.log("preamble executed! poor guy!"); and a user enters ...

Insert a character or icon into a :value

I am faced with a situation where I have two input text fields, each being assigned a value from an array stored in a state. The array contains two elements, one for each input field. However, I wish to append a symbol such as % or some additional text at ...

The issue with the transition element not functioning properly in the hamburger menu is being encountered while using Tailwind CSS alongside

I am currently working on creating a responsive navigation bar in nuxt3/vue. <template> <nav class="flex justify-between items-center w-[92%] mx-auto gap-4 border border-2 border-black p-2" > <div> <span cla ...

The action of POSTing to the api/signup endpoint is

Currently delving into the MEAN stack, I have successfully created a signup api. However, when testing it using POSTMAN, I encountered an unexpected error stating that it cannot POST to api/signup. Here is a snapshot of the error: Error Screenshot This ...