Skip to content

Commit 1a491da

Browse files
committed
Support multiple event listeners, add support for .stop event modifier
1 parent 4ef245b commit 1a491da

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

playground/src/pages/raycaster/Propogation.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const gl = {
4141
<primitive :object="meshWithMaterial" :position="[3, 1.5, 2]" @click="event => event.object.material.color.set('red')" />
4242
<Box :position="[-5, 1.5, 2]" name="Moving"></Box>
4343
<Box :position="[0, 1.5, 0]" name="A0">
44-
<Box :position="[-0.66, -1, 0]" name="B0" blocks-pointer-events>
44+
<Box :position="[-0.66, -1, 0]" name="B0">
4545
<Box :position="[-0.66, -1, 0]" name="C0">
4646
<Box :position="[-0.66, -1, 0]" name="D0" />
4747
<Box :position="[0.66, -1, 0]" name="D1" />

src/composables/useEventStore/index.ts

+22-15
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ export const useEventStore = createGlobalState(
1717
return _scene.value ? _scene.value.children : []
1818
})
1919

20+
function executeEventListeners(listeners: Function | Function[], intersection, event){
21+
// Components with multiple event listeners will have an array of functions
22+
if (Array.isArray(listeners)) {
23+
for (const listener of listeners) {
24+
listener(intersection, event);
25+
}
26+
}
27+
28+
// Single listener will be a function
29+
if (typeof listeners === 'function') {
30+
listeners(intersection, event);
31+
}
32+
}
33+
2034
/**
2135
* propogateEvent
2236
*
@@ -26,28 +40,21 @@ export const useEventStore = createGlobalState(
2640
* @param intersects - An array of intersections
2741
*/
2842
function propogateEvent(eventName: string, event, intersects) {
29-
// console.log(`propogateEvent: ${eventName}` , event, intersects);
30-
43+
let stopPropagating = true;
44+
3145
// Loop through all intersected objects and call their event handler
3246
if (intersects.length) {
3347
for(const intersection of intersects) {
48+
if (stopPropagating) return;
49+
intersection.stopPropagation = () => stopPropagating = true;
50+
3451
const { object } = intersection
35-
object[eventName]?.(intersection, event)
52+
executeEventListeners(object[eventName], intersection, event)
3653

37-
// Todo: Flesh out event modifiers, blocking, stopPropagation, etc here and below
38-
if ("blocks-pointer-events" in object) {
39-
return;
40-
}
41-
4254
// Propogate the event up the parent chain before moving on to the next intersected object
4355
let parent = object.parent
44-
while(parent !== null) {
45-
parent[eventName]?.(intersection, event)
46-
47-
if ("blocks-pointer-events" in parent) {
48-
return;
49-
}
50-
56+
while(parent !== null && !stopPropagating) {
57+
executeEventListeners(parent[eventName], intersection, event)
5158
parent = parent.parent
5259
}
5360

0 commit comments

Comments
 (0)