Bläddra i källkod

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 1 år sedan
förälder
incheckning
96a3955dc9
1 ändrade filer med 25 tillägg och 17 borttagningar
  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