如何同步实体相对于框架中同一实体标签内存在的两个动画的位置?

How to sync the position of entity with respect to two animations present inside same entity tag in aframe?

我的项目中有两个动画:'animation' 和 'animation__mouseenter'。我试图通过使用以下属性来控制动画:startEvents、resumeEvents 和 pauseEvents。一切正常,直到实体从 'animation__mouseenter' 切换到 'animation'。完成后animation__mouseenter'。该实体从 'animation' 离开实体的最后位置开始,而我正在寻找的是它应该从 'animation__mouseenter'.

指定的新位置继续

我也尝试使用 JavaScript 中的 .setAttribute 并尝试在滴答函数的帮助下为 'animation' 调整 from 属性将不断更新实体的新位置。

<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
  <script>
  AFRAME.registerComponent('eventhandling', {
            tick: function () {
                var el = this.el;
              var entity = document.querySelector('#duck1');
                el.addEventListener('animationcomplete', function(){
                   entity.emit('starteventforAnimation'); 
                });
          }
        });
    
  </script>
</head>

<body>
    <a-scene>
<a-entity class="rota" id="duck1" color="#FF0000" scale="0.1 0.1 .1" position="2 0 -7" animation="property: rotation;from: ; to:0 -360 0; loop:true; easing:linear; dur:30000; pauseEvents: mouseenter; resumeEvents: starteventforAnimation " animation__mouseenter="property: rotation;from: ; to:0 360 0; easing:linear; dur:4000; startEvents: mouseenter ;pauseEvents: starteventforAnimation; resumeEvents: mouseenter" eventhandling>
            <a-box class="rota" color="#FF0000" gltf-model="spaceship.glb"  position="20 0 -10"  scale="2 3 3" collison-check="el: #otherduck; radius: 0.15; other-radius: 0.15;"> </a-box>
        </a-entity>
<a-camera position="0 1.2 1.3"><a-cursor objects=".rota" ></a-cursor></a-camera>        <

    </a-scene>
</body>
</html>

据我了解,您想随时更改旋转方向(并减慢速度等)。

您正在通过旋转父对象来四处移动对象。这意味着位置在这里不起主要作用 - 轮换。

我只使用一个动画和一个组件:

  • 抓取当前旋转,加减360
  • 更改持续时间
  • 用新值更新现有动画。

下面是一个带有几个巧妙技巧的示例:

<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
  AFRAME.registerComponent("animation-manager", {
    init: function() {
      // bind updateAnimation() so that we have new functions
      // doing exactly what we need
      this.rotateClockwise = this.updateAnimation.bind(this, 1);
      this.rotateCounterClockwise = this.updateAnimation.bind(this, -1);

      // bind the above functions to mouseenter/mouseleave
      this.el.addEventListener("mouseenter", this.rotateClockwise)
      this.el.addEventListener("mouseleave", this.rotateCounterClockwise)
    },
    updateAnimation: (function() {
      // this is an IIFE - there two vectors are created only once
      // even though the returned function is called multiple times
      const fromRotation = new THREE.Vector3();
      const toRotation = new THREE.Vector3();

      return function(dir) {
        // get current rotation, and move the target rotation by 360 or -360
        // depending on the direction
        fromRotation.copy(this.el.getAttribute("rotation"));
        toRotation.copy(this.el.getAttribute("rotation"));
        toRotation.y += dir * 360

        // update the animation
        this.el.setAttribute("animation", {
          "from": AFRAME.utils.coordinates.stringify(fromRotation),
          "to": AFRAME.utils.coordinates.stringify(toRotation),
          "dur": dir == -1 ? "8000" : "1000"
        })
      }
    })()
  })
</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: a-box">
  <a-box position="0 1 -4" color="blue" animation-manager 
         animation="property: rotation; to:0 -360 0; loop:true; easing:linear; dur:8000">
    <a-sphere position="2 0 0" color="green" radius="0.25" foo></a-sphere>
  </a-box>
</a-scene>

巧妙的技巧是function binding, IIFEs, and AFRAME.Utils