From f7ae3342551578c9d322f5014edf118909de59c9 Mon Sep 17 00:00:00 2001 From: Bela Bohlender Date: Sun, 3 Nov 2024 13:27:29 +0100 Subject: [PATCH] improve declare module 'three' placements --- packages/pointer-events/src/event.ts | 47 +++++++++++- packages/pointer-events/src/index.ts | 38 ++++++++++ .../pointer-events/src/intersections/utils.ts | 23 +++++- packages/pointer-events/src/pointer.ts | 20 ----- packages/pointer-events/src/utils.ts | 76 ------------------- 5 files changed, 106 insertions(+), 98 deletions(-) diff --git a/packages/pointer-events/src/event.ts b/packages/pointer-events/src/event.ts index d1b88d7..2470bc6 100644 --- a/packages/pointer-events/src/event.ts +++ b/packages/pointer-events/src/event.ts @@ -1,7 +1,6 @@ import { BaseEvent, Face, Object3D, Quaternion, Ray, Vector2, Vector3 } from 'three' import { Intersection as ThreeIntersection } from './intersections/index.js' import { Pointer } from './pointer.js' -import { getObjectListeners } from './utils.js' import type { Camera, IntersectionEvent, Intersection } from '@react-three/fiber/dist/declarations/src/core/events.js' import { HtmlEvent, Properties } from './html-event.js' @@ -268,3 +267,49 @@ function emitPointerEventRec(baseEvent: PointerEvent, currentObject } emitPointerEventRec(baseEvent, currentObject.parent) } + +const r3fEventToHandlerMap: Record = { + click: 'onClick', + contextmenu: 'onContextMenu', + dblclick: 'onDoubleClick', + pointercancel: 'onPointerCancel', + pointerdown: 'onPointerDown', + pointerenter: 'onPointerEnter', + pointerleave: 'onPointerLeave', + pointermove: 'onPointerMove', + pointerout: 'onPointerOut', + pointerover: 'onPointerOver', + pointerup: 'onPointerUp', + wheel: 'onWheel', +} + +export const listenerNames = Object.keys(r3fEventToHandlerMap) + +declare module 'three' { + interface Object3D { + _listeners?: Record void> | undefined> + } +} + +function getObjectListeners( + object: Object3D, + forEvent: keyof PointerEventsMap, +): Array<(event: E) => void> | undefined { + if (object._listeners != null && forEvent in object._listeners) { + return object._listeners[forEvent] + } + + //R3F compatibility + let handler: ((e: any) => void) | undefined + if (object.isVoidObject && forEvent === 'click' && object.parent?.__r3f != null) { + handler = object.parent.__r3f.root.getState().onPointerMissed + } + if (object.__r3f != null) { + handler = object.__r3f.handlers[r3fEventToHandlerMap[forEvent]] + } + + if (handler == null) { + return undefined + } + return [handler] +} diff --git a/packages/pointer-events/src/index.ts b/packages/pointer-events/src/index.ts index e5c7a73..ed7991d 100644 --- a/packages/pointer-events/src/index.ts +++ b/packages/pointer-events/src/index.ts @@ -1,3 +1,41 @@ +import type { Root } from '@react-three/fiber/dist/declarations/src/core/renderer.js' +import type { AllowedPointerEvents, AllowedPointerEventsType } from './pointer.js' + +declare module 'three' { + interface Object3D { + __r3f?: { + eventCount: number + handlers: Record void) | undefined> + root: Root['store'] + } + /** + * undefined and true means the transformation is ready + * false means transformation is not ready + */ + transformReady?: boolean + + /** + * @default parent.pointerEvents ?? this.defaultPointerEvents + */ + pointerEvents?: AllowedPointerEvents + /** + * @default "listener" + */ + defaultPointerEvents?: AllowedPointerEvents + /** + * @default "all" + */ + pointerEventsType?: AllowedPointerEventsType + /** + * @default 0 + * sorted by highest number first + * (just like a higher renderOrder number will result in rendering over the previous - if depthTest is false) + */ + pointerEventsOrder?: number + isVoidObject?: boolean + } +} + export * from './pointer.js' export * from './event.js' export * from './intersections/index.js' diff --git a/packages/pointer-events/src/intersections/utils.ts b/packages/pointer-events/src/intersections/utils.ts index 5245f84..e1be6ac 100644 --- a/packages/pointer-events/src/intersections/utils.ts +++ b/packages/pointer-events/src/intersections/utils.ts @@ -1,8 +1,8 @@ import { Plane, Intersection as ThreeIntersection, Object3D, Vector3, Ray, Quaternion } from 'three' import { Intersection, IntersectionOptions } from './index.js' import { AllowedPointerEventsType, Pointer, type AllowedPointerEvents } from '../pointer.js' -import { hasObjectListeners } from '../utils.js' import { getVoidObject, VoidObjectCollider } from './intersector.js' +import { listenerNames } from '../event.js' export function computeIntersectionWorldPlane(target: Plane, intersection: Intersection, object: Object3D): boolean { const normal = intersection.normal ?? intersection.face?.normal @@ -103,6 +103,27 @@ export function intersectPointerEventTargets( } } +function hasObjectListeners({ _listeners, __r3f }: Object3D): boolean { + if (__r3f != null && __r3f?.eventCount > 0) { + return true + } + if (_listeners == null) { + return false + } + const entries = Object.entries(_listeners) + const length = entries.length + for (let i = 0; i < length; i++) { + const entry = entries[i] + if (!listenerNames.includes(entry[0])) { + continue + } + if (entry[1] != null && entry[1].length > 0) { + return true + } + } + return false +} + function filterAndInteresct( { intersector, options }: Pointer, object: Object3D, diff --git a/packages/pointer-events/src/pointer.ts b/packages/pointer-events/src/pointer.ts index ee86f02..9651a87 100644 --- a/packages/pointer-events/src/pointer.ts +++ b/packages/pointer-events/src/pointer.ts @@ -17,28 +17,8 @@ export type AllowedPointerEventsType = declare module 'three' { interface Object3D { - _listeners?: Record void> | undefined> - /** - * @default parent.pointerEvents ?? this.defaultPointerEvents - */ - pointerEvents?: AllowedPointerEvents - /** - * @default "listener" - */ - defaultPointerEvents?: AllowedPointerEvents - /** - * @default "all" - */ - pointerEventsType?: AllowedPointerEventsType - /** - * @default 0 - * sorted by highest number first - * (just like a higher renderOrder number will result in rendering over the previous - if depthTest is false) - */ - pointerEventsOrder?: number [buttonsDownTimeKey]?: ButtonsTime [buttonsClickTimeKey]?: ButtonsTime - isVoidObject?: boolean } } diff --git a/packages/pointer-events/src/utils.ts b/packages/pointer-events/src/utils.ts index 692423f..107445e 100644 --- a/packages/pointer-events/src/utils.ts +++ b/packages/pointer-events/src/utils.ts @@ -1,21 +1,5 @@ import { BufferAttribute, Matrix4, Mesh, Object3D, Triangle, Vector2, Vector3 } from 'three' import { PointerEventsMap } from './event.js' -import type { Root } from '@react-three/fiber/dist/declarations/src/core/renderer.js' - -declare module 'three' { - interface Object3D { - __r3f?: { - eventCount: number - handlers: Record void) | undefined> - root: Root['store'] - } - /** - * undefined and true means the transformation is ready - * false means transformation is not ready - */ - transformReady?: boolean - } -} export function updateAndCheckWorldTransformation({ transformReady, parent, matrix, matrixWorld }: Object3D): boolean { if (transformReady === false) { @@ -31,66 +15,6 @@ export function updateAndCheckWorldTransformation({ transformReady, parent, matr return true } -export function hasObjectListeners({ _listeners, __r3f }: Object3D): boolean { - if (__r3f != null && __r3f?.eventCount > 0) { - return true - } - if (_listeners == null) { - return false - } - const entries = Object.entries(_listeners) - const length = entries.length - for (let i = 0; i < length; i++) { - const entry = entries[i] - if (!listenerNames.includes(entry[0])) { - continue - } - if (entry[1] != null && entry[1].length > 0) { - return true - } - } - return false -} - -export function getObjectListeners( - object: Object3D, - forEvent: keyof PointerEventsMap, -): Array<(event: E) => void> | undefined { - if (object._listeners != null && forEvent in object._listeners) { - return object._listeners[forEvent] - } - - //R3F compatibility - let handler: ((e: any) => void) | undefined - if (object.isVoidObject && forEvent === 'click' && object.parent?.__r3f != null) { - handler = object.parent.__r3f.root.getState().onPointerMissed - } - if (object.__r3f != null) { - handler = object.__r3f.handlers[r3fEventToHandlerMap[forEvent]] - } - - if (handler == null) { - return undefined - } - return [handler] -} - -const r3fEventToHandlerMap: Record = { - click: 'onClick', - contextmenu: 'onContextMenu', - dblclick: 'onDoubleClick', - pointercancel: 'onPointerCancel', - pointerdown: 'onPointerDown', - pointerenter: 'onPointerEnter', - pointerleave: 'onPointerLeave', - pointermove: 'onPointerMove', - pointerout: 'onPointerOut', - pointerover: 'onPointerOver', - pointerup: 'onPointerUp', - wheel: 'onWheel', -} -const listenerNames = Object.keys(r3fEventToHandlerMap) - const triangleHelper1 = new Triangle() const triangleHelper2 = new Triangle() const aVec2Helper = new Vector2()