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
我有一个 '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