如何使用 css 动画通过 java 脚本将一个对象移动到另一个对象

how to move an object to another with java script using css animation

我正在尝试仅使用 java 脚本/Vue js 为购物车创建硬币收集动画。所以我决定用原始 java 脚本来做。所以最初我试着看 w3schools 这个教程 https://www.w3schools.com/js/tryit.asp?filename=tryjs_dom_animate_3

某处我有一个目的地div,就是下面的购物车

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

在某处我有 div 将被动画化并朝向 div id "coin"

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

这是我的 css

.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;
  }

下面是我的java脚本函数

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; 
      }
    }
        }

这里我试图沿着目的地 div 的左右 属性 动画不起作用..请帮助我到达 div 到目的地

  1. 你必须定义一个单位。将 px 添加到给定的 topleft

  2. 您应该使用 getClientBoundingRect 而不是 offset,因为 offset return 元素相对于其父元素的偏移量,而不是相对于页。所以如果这两个元素不共享同一个父元素 - 使用 getClientBoundingRect

  3. 现在你试图从第一步开始将元素移动到最终位置..如果你试图以 350 步(就像你的代码中的样子)为它制作动画,你应该移动在任何一步中,元素距离所需路径仅 1/350。

最后,它应该看起来像这样:(我建议减少步骤数):

function collect(){
    var elem = document.getElementById("animate");  
    var testDiv = document.getElementById("coin");
    var diffX = testDiv.getBoundingClientRect().left - elem.getBoundingClientRect().left;
    var diffY = testDiv.getBoundingClientRect().top - elem.getBoundingClientRect().top;
    var dx = diffX / 350;
    var dy = diffY / 350;
    var pos = 0;
    var id = setInterval(frame, 5);
    function frame() {
         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'; 
      }
    }

}
.coin {
  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;
  -webkit-transition: 2s linear;
  -webkit-transform-style: preserve-3d;
 }

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

对于我来说,我更喜欢使用带有递归函数的requestAnimationFrame。像这样:

var elem = document.getElementById("animate");  
var testDiv = document.getElementById("coin");
var rate = 1/75;
var diffX, diffY;
function collect() {
    diffX = testDiv.getBoundingClientRect().left - elem.getBoundingClientRect().left;
    diffY = testDiv.getBoundingClientRect().top - elem.getBoundingClientRect().top;
    frame();
}
function frame() {
  if(Math.abs(testDiv.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(frame);
}
.coin {
  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;
  -webkit-transition: 2s linear;
  -webkit-transform-style: preserve-3d;
 }

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