Experience the seamless transition of new CSS animations

I designed a basic HTML game where a moving box disappears when clicked on. However, the animation that follows does not originate from the click location but rather from the original position.

I believe the remove @keyframes at 0% should be based on the click location, but I have been unable to figure out how to achieve this.

Any suggestions on how I can accomplish this?

  (function () {
    const charactersGroup = document.querySelectorAll('.character');
    const stage = document.querySelector('.stage')
    const clickHandler = (e) => {
      const target = e.target;
      if (target.classList.contains('character')) {
        target.classList.remove(`f${target.dataset.id}`);
        target.classList.add('f0');
        target.classList.add('remove');

        setTimeout(() => { stage.removeChild(target) }, 2000);
      }
    }
    stage.addEventListener('click', clickHandler);
  }());
.stage {
      overflow: hidden;
      position: relative;
      background: #eeeeaa;
      width: 40vw;
      height: 20vw;
    }

    @keyframes moving {
      0% {
        transform: translateX(0);
      }
      100% {
        transform: translateX(30vw);
      }
    }
    @keyframes remove {
      0% {
        transform: translate(0);
      }
      100% {
        transform: translateY(60vw);
      }
    }
    .character {
      position: absolute;
      width: 50px;
      height: 50px;
      background-repeat: no-repeat;
      background-position: 50% 50%;
      background-size: contain;
      animation: moving infinite alternate;
    }
    .remove {
      animation: remove 0.2s cubic-bezier(.68,-0.55,.27,1.55) forwards;
    }
    .f0 {
      background-color: black;
      animation-duration: 2s;
    }
    .f1 {
      left: 5%;
      bottom: 5%;
      animation-duration: 2s;
      background-color: red;
    }
<div class="stage">
  <div class="character f1" data-id="1"></div>
</div>

Answer №1

Modify the primary animation to utilize the left property instead of translate, then attach both animations to the element from the start. To activate the transition between the two animations, toggle the animation-play-state when adding the remove class.

(function() {
  const charactersGroup = document.querySelectorAll('.character');
  const stage = document.querySelector('.stage')
  const clickHandler = (e) => {
    const target = e.target;
    if (target.classList.contains('character')) {
      target.classList.add('remove');

      setTimeout(() => {
        stage.removeChild(target)
      }, 2000);
    }
  }
  stage.addEventListener('click', clickHandler);
}());
.stage {
  overflow: hidden;
  position: relative;
  background: #eeeeaa;
  width: 40vw;
  height: 20vw;
}

@keyframes moving {
  100% {
    left:calc(95% - 50px);
  }
}

@keyframes remove {
  50% {
    transform: translateY(-30vh);
  }
  100% {
    transform: translateY(60vw);
  }
}

.character {
  position: absolute;
  width: 50px;
  height: 50px;
  background:red;
  left: 5%;
  bottom: 5%;
  animation: 
     moving 2s infinite alternate,
     remove 1s cubic-bezier(.68, -0.55, .27, 1.55) forwards paused;
}

.remove {
  animation-play-state:paused,running;
  background: black;
}
<div class="stage">
  <div class="character f1" data-id="1"></div>
</div>

Answer №2

If your situation involves handling a large number of these boxes with complexity, it's advisable to manage everything using pure JS. However, I attempted to make this functional with minimal adjustments in both JS and CSS.

I have included explanatory comments in the new JS code.

Additionally, I took the initiative to create a distinct class called moving for the animation feature so that it can be removed upon clicking.

(function () {
    const charactersGroup = document.querySelectorAll('.character');
    const stage = document.querySelector('.stage')
    const clickHandler = (e) => {
      const target = e.target;
      if (target.classList.contains('character')) {
        target.classList.remove(`f${target.dataset.id}`);
        target.classList.add('f0');
        // remove the moving animation
        target.classList.remove('moving');
        // Get offsetWidth which is the half of width to substract later while calculating left for the target i.e our box.
        const offsetWidth  = parseInt(getComputedStyle(target).width)/2;
        // e.clientX gives us the x coordinate of the mouse pointer
        // target.getBoundingClientRect().left gives us left position of the bounding rectangle and acts as a good offset to get the accurate left for our box.
        target.style.left = `${e.clientX -target.getBoundingClientRect().left - offsetWidth}px`;
       target.classList.add('remove');
     setTimeout(() => { stage.removeChild(target) }, 2000);
      } 
    }
    stage.addEventListener('click', clickHandler);
  }());
.stage {
      overflow: hidden;
      position: relative;
      background: #eeeeaa;
      width: 40vw;
      height: 20vw;
    }

    @keyframes moving {
      0% {
        transform: translateX(0);
      }
      100% {
        transform: translateX(30vw);
      }
    }
    @keyframes remove {
      0% {
        transform: translate(0vh);
      }
      100% {
        transform: translateY(60vw);
      }
    }
    .character {
      position: absolute;
      width: 50px;
      height: 50px;
      background-repeat: no-repeat;
      background-position: 50% 50%;
      background-size: contain;
    }
    
    .moving{
      animation: moving infinite alternate;
    }
    .remove {
      animation: remove 0.2s cubic-bezier(.68,-0.55,.27,1.55) forwards;
    }
    .f0 {
      background-color: black;
      animation-duration: 2s;
    }
    .f1 {
      left: 5%;
      bottom: 5%;
      animation-duration: 2s;
      background-color: red;
    }
<div class="stage">
  <div class="character moving f1" data-id="1"></div>
</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

Insert a new element at the current scroll position without disrupting the existing scroll or view

My goal is to replicate the functionality of the Twitter Mac client. I have a scrollable box with a fixed height and multiple blocks inside. I want to add a new block before all the others, but keep it invisible to the user so they have to scroll to the to ...

Force restart broken socket within Node.js program using Socket.IO programmatically

I have a simple one-to-one client and server Node.js based application. The Node.js is running on Linux (Intel Edison). I am attempting to automatically reboot the Linux server whenever the socket connection is broken. Is this achievable? Below is my unco ...

Issues with POST data not being received by MVC 4 APIController

Although this issue has been addressed numerous times, I am still unable to pinpoint the error! Here is a straightforward JS script that sends data back to the ApiController. function WebCall(url,parameterObject, callBackFunction) { this.callbackfunction ...

Deleting an element from an array in JavaScript

I am working with a JavaScript array that I need to store in local storage. var myArray; myArray = [1,2,3,4,5]; localStorage.setItem('myArray', JSON.stringify(myArray)); The above code snippet sets the values of the 'myArray' ...

Maintain the value of `this` using a recursive setImmediate() function

Hey there! I'm working on a node.js app where I need to utilize setImmediate() to recursively call a function while maintaining its context for the next iteration. Let's take a look at an example: var i=3; function myFunc(){ console.log(i ...

Creating stylistic layouts for text using CSS

After spending the last hour designing a web page, I am stuck on a particular issue that I just can't seem to solve. I need to write several paragraphs while adhering to two specific constraints: 1) The div in which the text resides must be centered ...

Is there a way to replicate the Vista Command Link in HTML?

This particular dialog mimics the design of a Windows Vista Command Link: View image here: http://i.msdn.microsoft.com/Aa511455.commandlinks01(en-us,MSDN.10).png I'm curious if anyone has created HTML code that replicates the appearance and function ...

What steps can be taken to revert this Node.js module to a particular version and ensure it does not automatically update in

While using the Nodemailer module in node.js, I encountered a specific error that read as follows; [Error: Unsupported configuration, downgrade Nodemailer to v0.7.1 or see the migration guide https://github.com/andris9/Nodemailer#migration-guide] A ...

Different ways to adjust the appearance of table borders in HTML

I find myself at a standstill, hence why I am reaching out with this question. This Table presents itself with various border sizes and colors, along with similar complexities in the background of its cells. Could anyone provide me with guidance on how t ...

Invalid extra parameters in the $.ajax function

I am attempting to access a web service in order to retrieve some data. I must include this URL using the GET method: http://localhost/ecosat/ws/api.php?t=vw_motorista However, when I check in Chrome Developer Tools, the link is shown as: http://localho ...

How to eliminate a hyperlink from an HTML element with the help of JQuery

Recently, I was assigned to revamp a website for the company I work for. However, upon closer inspection, I realized that the website is quite messy and relies heavily on templates, resulting in certain elements being auto-generated as active links. The i ...

Troubleshooting CSS Issues in ASP.NET Boilerplate

I am attempting to apply a CSS style to a text input similar to the one found on the CreateUser default page. However, I am encountering an issue where the blue line under the textbox does not appear when I navigate away from and then return to the page. ...

The website is failing to adapt properly to smaller screen sizes

I would share some code here, but it might be easier for you to just check out the URL instead. The issue is that the website was responsive across different screen sizes at first, but after making some changes in the CSS and HTML, it's not working pr ...

`The challenge of properly handling quotation marks within quotation marks in JavaScript string literals

I am having trouble displaying text in a JavaScript tooltip Despite my efforts to escape the quotes and eliminate any line breaks, I keep encountering unterminated string literals. The specific text I want to show is: "No, we can't. This is going t ...

Create code with a form button and showcase the produced code on the webpage

I have created two files: code_generator.html, which takes input in the form of an image URL and landing URL. When I click on the submit button, it calls code_created.php. <html> <head> </head> <body> <form a ...

A guide on utilizing Material UI Fade for smoothly fading in a component when a text field is selected

I am facing an issue with a text field input and a helper component. My goal is to have the helper component fade in when a user focuses on the input field. The helper component is wrapped as follows: <Fade in={checked}> <DynamicHelperText lev ...

Utilize auto-suggestion feature for populating dynamically created input fields with information sourced from the

I have searched through numerous questions on stackoverflow related to my issue, but I was unable to apply any of them to solve my problem. Therefore, I am providing the files that I have been working with. I have successfully implemented autocomplete fe ...

Using database entries to generate dynamic routes in express.js without the need for a server restart

I have created a custom Express instance for my KeystoneJS v5 app that serves data stored in a Postgres database with the following model: CREATE TABLE "Link" ( id integer DEFAULT PRIMARY KEY, customer text, slug text ); I've set up dyna ...

AngularJS - Swipe to update

I've been trying to use the pull to refresh plugin for Angular JS, but unfortunately it's not working for me. Even though I can see the text, when I try to pull nothing happens! I followed all the steps outlined on this GitHub page: https://githu ...

Is there a method to trigger click events on overflow content when clicked?

I am currently tackling a significant issue: I need the drop-down options' width to be wider than where the selected value is displayed, especially in IE7. After conducting some research on Google, I decided to take matters into my own hands and write ...