-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathraycaster-listen.js
98 lines (90 loc) · 3.55 KB
/
raycaster-listen.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
AFRAME.registerComponent('navigate-on-click', {
schema: {
target: { type: 'string' }, // Target URL
hoverColor: { type: 'color', default: 'yellow' } // Hover color
},
init: function () {
this.originalColors = new Map(); // Store original material colors or textures
// Handle primitive geometries or models
this.storeOriginalProperties();
// Change material color on hover (works in non-VR and VR)
this.el.addEventListener('mouseenter', () => {
const mesh = this.el.getObject3D('mesh');
if (mesh) {
mesh.traverse((node) => {
if (node.isMesh) {
if (!this.originalColors.has(node)) {
this.originalColors.set(
node,
node.material.color ? node.material.color.clone() : null
);
}
if (node.material.color) {
node.material.color.set(this.data.hoverColor);
}
}
});
}
});
// Revert material color on mouse leave
this.el.addEventListener('mouseleave', () => {
const mesh = this.el.getObject3D('mesh');
if (mesh) {
mesh.traverse((node) => {
if (node.isMesh) {
const originalColor = this.originalColors.get(node);
if (originalColor) {
node.material.color.copy(originalColor);
}
}
});
}
});
// Handle navigation on mouse click (non-VR)
this.el.addEventListener('click', (event) => {
this.navigate();
// Stop the event from propagating to underlying objects
event.stopPropagation();
});
// Handle navigation via VR controller trigger (VR)
this.el.sceneEl.addEventListener('triggerdown', (event) => {
const controller = event.target; // The VR controller entity
const intersected = controller.components.raycaster.intersectedEls[0];
if (intersected === this.el) {
this.navigate();
// Stop the event from propagating to underlying objects
event.stopPropagation();
}
});
},
navigate: function () {
if (this.data.target) {
console.log(`Navigating to: ${this.data.target}`);
window.location.href = this.data.target;
} else {
console.warn('No target URL specified for navigation.');
}
},
storeOriginalProperties: function () {
// For primitives, the mesh is immediately available
const mesh = this.el.getObject3D('mesh');
if (mesh) {
mesh.traverse((node) => {
if (node.isMesh && node.material.color) {
this.originalColors.set(node, node.material.color.clone());
}
});
}
// For models, wait for the `model-loaded` event
this.el.addEventListener('model-loaded', () => {
const mesh = this.el.getObject3D('mesh');
if (mesh) {
mesh.traverse((node) => {
if (node.isMesh && node.material.color) {
this.originalColors.set(node, node.material.color.clone());
}
});
}
});
}
});