Quellcode durchsuchen

Second stab at this, now when registering object with event listeners we check if an object isGroup. If it is, we run through it's children and set their event listeners as the parents. If the child already has event listeners wired up, then we combine the functions

Garrett Walker vor 1 Jahr
Ursprung
Commit
96a3955dc9
1 geänderte Dateien mit 25 neuen und 17 gelöschten Zeilen
  1. 25 17
      src/composables/usePointerEventHandler/index.ts

+ 25 - 17
src/composables/usePointerEventHandler/index.ts

@@ -1,4 +1,4 @@
-import type { Intersection, Event, Object3D  } from 'three'
+import type { Intersection, Event, Object3D } from 'three'
 import type { TresScene } from 'src/types'
 import { computed, reactive, ref } from 'vue'
 import { uniqueBy } from '../../utils'
@@ -45,6 +45,14 @@ export const usePointerEventHandler = (
     deregisterBlockingObject(object)
   }
 
+  const combineFunctions = (groupFn: CallbackFn, childFn: CallbackFn): CallbackFn | CallbackFnPointerLeave => {
+    return (intersection: Intersection<Object3D<Event>>, event: PointerEvent) => {
+      // Emit child events first
+      childFn?.(intersection, event);
+      groupFn?.(intersection, event);
+    }
+  }
+
   const registerObject = (object: Object3D & EventProps) => {
     const { onClick, onPointerMove, onPointerEnter, onPointerLeave } = object
 
@@ -52,6 +60,19 @@ export const usePointerEventHandler = (
     if (onPointerMove) objectsWithEventListeners.pointerMove.set(object, onPointerMove)
     if (onPointerEnter) objectsWithEventListeners.pointerEnter.set(object, onPointerEnter)
     if (onPointerLeave) objectsWithEventListeners.pointerLeave.set(object, onPointerLeave)
+
+    // If object is a TresGroup, attach it's event handlers to all children.
+    // If child already has an event attached, join the 2 functions via a callback
+    if(object?.isGroup){
+      for(const child of object?.children) {
+        const { onClick: onChildClick, onPointerMove: onChildPointerMove, onPointerEnter: onChildPointerEnter, onPointerLeave: onChildPointerLeave } = child
+
+        if (onClick) objectsWithEventListeners.click.set(child, combineFunctions(onClick, onChildClick))
+        if (onPointerMove) objectsWithEventListeners.pointerMove.set(child, combineFunctions(onPointerMove, onChildPointerMove))
+        if (onPointerEnter) objectsWithEventListeners.pointerEnter.set(child, combineFunctions(onPointerEnter, onChildPointerEnter))
+        if (onPointerLeave) objectsWithEventListeners.pointerLeave.set(child, combineFunctions(onPointerLeave, onChildPointerLeave))
+      }
+    }
   }
 
   // to make the registerObject available in the custom renderer (nodeOps), it is attached to the scene
@@ -77,37 +98,24 @@ export const usePointerEventHandler = (
 
   onClick(({ intersects, event }) => {
     if (intersects.length) objectsWithEventListeners.click.get(intersects[0].object)?.(intersects[0], event)
-    if (intersects.length && intersects[0].object?.parent?.isGroup) objectsWithEventListeners.click.get(intersects[0].object?.parent)?.(intersects[0], event);
   })
 
   let previouslyIntersectedObject: Object3D<Event> | null
 
   onPointerMove(({ intersects, event }) => {
-    if (intersects?.length > 0) 
-      console.log(intersects)
     const firstObject = intersects?.[0]?.object
-    const parentObject = intersects?.[0]?.object?.parent
 
     const { pointerLeave, pointerEnter, pointerMove } = objectsWithEventListeners
 
-    if (previouslyIntersectedObject && previouslyIntersectedObject !== firstObject){
+    if (previouslyIntersectedObject && previouslyIntersectedObject !== firstObject)
       pointerLeave.get(previouslyIntersectedObject)?.(previouslyIntersectedObject, event)
-
-      if(parentObject ?? parentObject?.isGroup)
-        pointerLeave.get(parentObject)?.(previouslyIntersectedObject, event)
-    }
+    
 
     if (firstObject) {
-      if (previouslyIntersectedObject !== firstObject) {
+      if (previouslyIntersectedObject !== firstObject) 
         pointerEnter.get(firstObject)?.(intersects[0], event)
 
-        if(parentObject ?? parentObject?.isGroup)
-          pointerEnter.get(parentObject)?.(previouslyIntersectedObject, event)
-      }
-
       pointerMove.get(firstObject)?.(intersects[0], event)
-      if(parentObject ?? parentObject?.isGroup)
-        pointerMove.get(parentObject)?.(previouslyIntersectedObject, event)
     }
 
     previouslyIntersectedObject = firstObject || null