【问题标题】:A-Frame: mouseenter/mouseleave for parent entity onlyA-Frame: mouseenter/mouseleave 仅用于父实体
【发布时间】:2018-05-28 04:10:35
【问题描述】:

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

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

是否可行/仅获取进入/离开整个父实体的事件的最佳方式是什么?

演示: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>

【问题讨论】:

  • 你想让鼠标进入/离开在空白区域的环内工作吗?
  • 我希望它在整个组件上工作,这样当您的光标进入外部黑色环时,您会得到一个 mouseenter。然后当您进入空白区域或内圈时没有任何事件,如果您退出外黑圈到场景的其余部分,最后是鼠标离开。谢谢! :)
  • 使用指针事件:无;子元素的 CSS 属性

标签: javascript aframe


【解决方案1】:

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

因为您的整个实体由一个环和内部的一个小圆圈组成,所以父实体只是子实体的空持有人。
当您离开圆环时会触发 mouseleave 事件,因为在圆环和圆环之间实际上什么都没有。如果你想填充空间(二维),你需要:

  • 创建一个子实体,它将是一个以外环为半径的不可见圆。不可见是指opacity = 0,而不是visible = false(因为可见属性负责渲染,而不是可见性),并将其放在其他孩子的前面。
  • 使父实体成为圆形图元,具有与上述相同的属性。

如果您想在 3D 空间中填充它,而不是圆形,请创建一个不可见的圆柱体,如纸一样薄,这样它就可以阻挡来自四面八方的光线投射。
工作小提琴here

【讨论】:

  • 谢谢皮奥特。我之前尝试了这两种方法(它们是等价的),并发现由于像素与透明层重叠(它们位于相同的 3D 空间坐标),它仍然会触发重复的 mouseenter/mouseleave 事件。见output.jsbin.com/nemuqut/quiet(例如透明的红色)。如果您将光标移动到中心小圆圈上,您将重复触发进入/离开事件。
  • 啊,我发布了你的更新。可能是愚蠢的问题,但位置0 0 0.01 不适用于所有坐标/角度,对吧?我想我需要将最热门的圆圈沿着一个向量朝向相机平移才能完全正确。
  • @Stephen 我已经更新了我的anwser,因为我在为你制作小提琴时发现了这种行为,我希望它现在会令人满意:)
  • @Stephen 1. 圆圈总是在目标的前面。 2. 我会在那里放置一个隐形圆柱体,厚如环/圆,所以它会覆盖所有角度,怎么样?
  • @Stephen 已更新,如果正确,请整理一下我的 anwser :)
【解决方案2】:

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

pointer-events: none;

【讨论】:

  • 你该死的CSS忍者,这真的很棒,它会忽略所有的光线投射/激光控制等吗?
  • 是的,应该的。
  • @Stephen,你试过了吗?
  • 抱歉,我可能误解了,但output.jsbin.com/nemuqut(根据您的想法更新)似乎不起作用?我仍然在外环和内环上收到事件。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    相关资源
    最近更新 更多