Tips for transferring an item to a different location using JavaScript and CSS animation

I am attempting to implement a coin collection animation into the cart using only JavaScript and Vue.js. I decided to use raw JavaScript for this purpose after initially following a tutorial on W3schools at https://www.w3schools.com/js/tryit.asp?filename=tryjs_dom_animate_3

Somewhere in my code, there is a destination div representing the cart as shown below:

<div class="coin" id="coin" @click="collect()">

And elsewhere, I have another div that needs to be animated towards the "coin" div:

<div id="animate">
</div>

Here is the CSS styling used:

.coin {
  background-image: 
  url("https://i.pinimg.com/originals/15/ce/a6/15cea65c1fadcfcb144f3b41e32bd9b3.png");
  background-size: 100% 100%;
  border-radius: 100%;
  height: 80px;
  position: relative;
  width: 80px;
  -webkit-transition: 2s linear;
  -webkit-transform-style: preserve-3d;
 }

#animate {
   width: 50px;
   height: 50px;
   position: absolute;
   background-color: red;
  }

Below is the JavaScript function being utilized:

collect(){
    var elem = document.getElementById("animate");   
    var pos = 0;
    var id = setInterval(frame, 5);
      function frame() {
         if (pos == 350) {
         clearInterval(id);
     } else {
          pos++; 
          var testDiv = document.getElementById("coin");
          elem.style.top = testDiv.offsetTop; 
          elem.style.left = testDiv.offsetLeft; 
      }
    }
        }

I encountered issues with the animation not working properly as intended according to the left-right properties of the destination div. Any assistance in resolving this issue would be greatly appreciated.

Answer №1

  1. To start, make sure you specify the units by adding px to both the top and left properties.

  2. Instead of using offset, consider using getBoundingClientRect as it provides the position based on the page rather than the parent element.

  3. When animating an element over multiple steps, remember to move the element incrementally towards its final position in each step instead of trying to directly move it to the final destination from the beginning.

Here's a recommended approach (with reduced number of steps) for achieving the desired animation:

function animate(){
    var elem = document.getElementById("animate");  
    var target = document.getElementById("target");
    var diffX = target.getBoundingClientRect().left - elem.getBoundingClientRect().left;
    var diffY = target.getBoundingClientRect().top - elem.getBoundingClientRect().top;
    var dx = diffX / 350;
    var dy = diffY / 350;
    var pos = 0;
    var id = setInterval(moveElement, 5);
    function moveElement() {
         if (pos == 350) {
         clearInterval(id);
     } else {
          pos++; 
          elem.style.top = (parseFloat(elem.style.top)||0) + dy + 'px'; 
          elem.style.left = (parseFloat(elem.style.left)||0) + dx + 'px'; 
      }
    }

}
.target {
  background-image: url("https://i.pinimg.com/originals/15/ce/a6/15cea65c1fadcfcb144f3b41e32bd9b3.png");
  background-size: 100% 100%;
  border-radius: 100%;
  height: 80px;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 80px;
  transition: 2s linear;
}

#animate {
   width: 50px;
   height: 50px;
   position: absolute;
   top:0;
   left:0;
   background-color: red;
}
<div class="target" id="target" onclick="animate()"></div>
<div id ="animate"></div>

If you prefer using requestAnimationFrame with a recursive function for the animation, you can also try this alternative method:

var elem = document.getElementById("animate");  
var target = document.getElementById("target");
var rate = 1/75;
var diffX, diffY;
function animate() {
    diffX = target.getBoundingClientRect().left - elem.getBoundingClientRect().left;
    diffY = target.getBoundingClientRect().top - elem.getBoundingClientRect().top;
    move();
}
function move() {
  if(Math.abs(target.getBoundingClientRect().left - elem.getBoundingClientRect().left) < diffX*rate) return;
  elem.style.top = (parseFloat(elem.style.top)||0) + diffY*rate + 'px'; 
  elem.style.left = (parseFloat(elem.style.left)||0) + diffX*rate + 'px'; 
  requestAnimationFrame(move);
}
.target {
  background-image: url("https://i.pinimg.com/originals/15/ce/a6/15cea65c1fadcfcb144f3b41e32bd9b3.png");
  background-size: 100% 100%;
  border-radius: 100%;
  height: 80px;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 80px;
  transition: 2s linear;
}

#animate {
   width: 50px;
   height: 50px;
   position: absolute;
   top:0;
   left:0;
   background-color: red;
}
<div class="target" id="target" onclick="animate()"></div>
<div id ="animate"></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

Reorder the Polymer dom-repeat element following a modification in the child component's value

My Polymer dom-repeat list is working fine on the initial value sorting for the children. However, when I update a value within a child element, the sort order of the list does not reflect the changes. What is the best way to achieve this? <body> ...

Issue with font selection in Fabric.js

I am currently working with fabric js version 1.7.22 alongside angular 7 to create a text editor. I have encountered an issue when trying to add text to the canvas using a custom font as shown in the code snippet below. var canvas= new fabric.Canvas(&apos ...

What could be causing the issue with my hour parameter in node-cron?

Having difficulty setting up a cron job to run with node-cron every Monday at 8:30. I've tried using "30 8 * * Mon" and even "30 08 * * Mon", but it doesn't seem to work. Interestingly, "30 * * * Mon" does work and runs every hour on the 30th min ...

Display a timer on a webpage

Looking to incorporate a count up timer onto my website - essentially, a label displaying 0:00:00 should gradually change to show 0:00:01, and continue in this pattern until the stop button is pressed. Is there an uncomplicated JavaScript/jQuery solutio ...

How can I restrict a plugin to just one component in Nuxt.js?

I'm working on a blog website using nuxt.js and I need to import an editor in only one component without using the nuxt.config.js file. I've tried the following approach, but it doesn't seem to be working. //Inside '~/plugins/vue2-ed ...

Issues with XMLHttpRequest functionality

I'm currently working on a project where I need to update the TextArea element in my HTML every 2 seconds dynamically, without reloading the page. The issue I'm facing is that when I use alert(request.readystate), it returns undefined instead of ...

Achieving a jQuery event on elements that are generated dynamically, without the need to manually code

My issue is as follows: In my HTML, I am generating listings using JavaScript, with each listing structured like this: <div class="row" id="reveal-listing-id"> <div class="large-12 columns"> <div class="panel"> & ...

Issue with Angular custom directive compatibility in version 1.3.0

Check out my code snippet This code snippet is compatible with angular **1.1.3**. However, it does not function properly with 1.3.0 ...

Display the cover image of the page as you scroll through the content

Trying to implement a scrolling effect where the content covers an image from this tutorial video. The issue I'm encountering is that the image is not a background image but an actual image tag. Here's my current code: <section id="home" clas ...

My data is not appearing with ng-repeat or ng-bind

One issue I am encountering is that my ng-repeat / ng-bind is not displaying the data within $scope.articles, even though I am getting the expected data in the console. To help identify the problem more easily, I have created a code snippet below: var A ...

Chart.js malfunctioning - Uncaught reference error:

In an attempt to visualize time series data using chart.js, I am encountering some issues. The data is extracted from a psql database, converted to JSON format, and then passed as a parameter to a JavaScript function for rendering the chart. Although the ...

The AJAX request functions properly when triggered by the .click() method, however, it encounters issues with

This particular code snippet is effective: <form id="myform" action="" method=""> <input type="email" class="form-control" name="inputEmail" id="inputEmail" placeholder="Email address"> <input type="password" class="form-control" na ...

safari application is processing audio recordings with incorrect mime type as application/octate-stream

When attempting to capture a user's recording from a microphone using the Media Recorder API, everything works smoothly in Chrome. However, when trying to record in Safari, the MIME type is reported as application/octet-stream. I need to transmit the ...

Arrangement of elements across rows and columns in a grid pattern

Is it possible to span a column that is equivalent to two columns in the first row and then have one column each for the second row, as shown in the screenshot? (There are two columns in the second row in this case) CSS main section { display: grid; ...

What is the procedure for obtaining the factory of an element in situations where the element's class is not

Currently, I am facing a challenge with React where I have a single React element and I want to generate additional elements with the same class. The issue is that I am not aware of the class name, only the instance of the element. When using React.create ...

"Here's a neat trick for assigning the value of a div to a text box without any identifiers like id or

I needed a way to transfer the value of a .item div into an empty textbox without any specific identifier. Then, when the input loses focus, the value should be sent back to the original .item div. $(document).on("click", ".item", function() { $(this) ...

The submission of the HTML Form is experiencing difficulties in Internet Explorer 9

Having an issue with my basic HTML form not submitting in IE9, although it works fine in Chrome, FF, and IE10. I've attempted to submit the form in IE9 on Windows 7 and IE10 on Windows 8. In IE10, everything is functional. However, if I switch the b ...

Absolute positioning with centering margins

Hey there, I'm facing a little issue where I want to keep my footer at the bottom of the screen using position: absolute. But for some reason, the margin: auto that should center it on the screen isn't working as expected. Here's the HTML s ...

The successful completion of the Ajax post method reveals a difference in the sequence in which data is posted and retrieved

Within my code, I have dynamically created textboxes with various ids. In JavaScript, I am able to fetch the values of these textboxes one by one. Everything seems to be working perfectly up until this point. However, when I pass this data using an AJAX ...

Oh no! There seems to be an unexpected token "<" in my React Native project on Visual Studio Code

When utilizing react-native in VS Code, I encounter an issue where my code fails to compile and throws a syntax error for the "<" symbol. Strangely, many tags work fine with "react-native run-android" from the Terminal. This is the code snippet that I ...