A-Frame:mouseenter/mouseleave 仅适用于父实体

A-Frame: mouseenter/mouseleave for parent entity only

我有一个 'target-circle' 组件,它是一个简单的圆圈,外面有一个环。我正在尝试为 entire 组件获取 mouseenter 和 mouseleave 事件,但是附加到 parent 元素的事件侦听器为子实体触发并且仅当光线投射器击中某物时。

我尝试了各种方法来放置不可见的命中测试 circles/rings 来尝试缓解这个问题,但它们都有一个核心问题,即为子实体触发多个 enter/leave 事件。

feasible/what 是只获取 entering/leaving 整个父实体事件的最佳方式吗?

演示:https://output.jsbin.com/tucuxas/quiet

<!DOCTYPE html>
<html>
  <head>
    <script src="https://aframe.io/releases/0.6.0/aframe.min.js"></script>
    <script>
      AFRAME.registerComponent('target-circle', {
        schema: {
          position: {type: 'vec3', default: {x: 0, y: 0, z: 0}}
        },

        init: function() {
          var el = this.el;

          el.setAttribute('position', this.data.position);
          el.object3D.lookAt(new THREE.Vector3(0, 0, 0));

          var outerRing = document.createElement('a-entity');
          outerRing.setAttribute('class', 'outerRing');
          outerRing.setAttribute('material', {
            color: 'black'
          });
          outerRing.setAttribute('geometry', {
            primitive: 'ring',
            radiusInner: '1.2',
            radiusOuter: '1.4'
          });

          var innerCircle = document.createElement('a-entity');
          innerCircle.setAttribute('class', 'innerCircle');
          innerCircle.setAttribute('material', {
            color: 'black'
          });
          innerCircle.setAttribute('geometry', {
            primitive: 'circle',
            radius: '0.3'
          });
          
          el.appendChild(outerRing);
          el.appendChild(innerCircle);
          
          el.addEventListener('mouseenter', function() {
            console.log('mouseenter');
          });
          
          el.addEventListener('mouseleave', function() {
            console.log('mouseleave');
          });
        }
      });
    </script>
  </head>
  <body>
    <a-scene>
      <a-entity target-circle='position: 0 3 -10'></a-entity>
      <a-entity camera look-controls>
        <a-entity id="cursor" cursor="fuse: false;" material="color: black; shader: flat;"
                  position="0 0 -1"
                  geometry="primitive: ring; radiusInner: 0.001; radiusOuter: .005;  "></a-entity>
      </a-entity>
    </a-scene>
  </body>
</html>

虽然 SamB 的答案在这种情况下是正确的,但我不确定 css 中的阻塞指针事件是否适用于所有光线投射器(即使它应该),这是我包装容器实体中的子项,仅用于光线投射:

因为您的整个实体由一个环和一个小圆圈组成,父实体只是子实体的空容器。
mouseleave 事件在您离开圆环时触发,因为在圆环和圆圈之间,几乎什么都没有。如果你想填写 space (在 2D 中),你需要:

  • 创建一个子实体,它将是一个不可见的圆,外圈的半径。 Invisible的意思是opacity = 0,不是visible = false(因为visible属性负责渲染,不是visibility),放在其他children前面。
  • 将父实体设为圆形基元,具有与上述相同的属性。

如果你想在 3D 中填充它 space,而不是一个圆,创建一个不可见的圆柱体,薄如纸,这样它就可以阻挡来自四面八方的光线投射。
工作 fiddle here.

在您的 CSS 类 中为 innerCircle 和 outerCircle 添加以下 属性

pointer-events: none;

A-Frame 0.8.0 的更新解决方案:

  • 创建透明 a-circle 作为父级
  • a-ring 添加为 a-circle
  • 的子项
  • raycaster="objects: a-circle (and comma-separated selectors of any other elements you need the cursor to interact with in the scene); recursive: false"添加到场景中的光标实体

此处的 raycaster 组件设置将防止您的光标与场景中的元素相交,除了那些选择器与 objects 属性 中列出的元素相匹配的元素,以及将交叉点限制为匹配的顶级元素,忽略所有后代。

有关 raycaster 组件的更多信息:https://github.com/aframevr/aframe/blob/master/docs/components/raycaster.md