diff --git a/packages/pointer-events/src/combine.ts b/packages/pointer-events/src/combine.ts index 4d5f42b..792f937 100644 --- a/packages/pointer-events/src/combine.ts +++ b/packages/pointer-events/src/combine.ts @@ -127,7 +127,7 @@ export class CombinedPointer { //we only need to intersect the scene if no pointer is captured or (in case one or more pointers are captured) if mulitple pointers can be enabled if (!anyPointerIsCaptured || this.enableMultiplePointers) { //intersect scene using the non captured pointers - intersectPointerEventTargets(scene, this.nonCapturedPointers) + intersectPointerEventTargets('pointer', scene, this.nonCapturedPointers) //finalize the intersection for the non captured pointers const nonCapturedPointerLength = this.nonCapturedPointers.length diff --git a/packages/pointer-events/src/forward.ts b/packages/pointer-events/src/forward.ts index 6e2c741..3061b4d 100644 --- a/packages/pointer-events/src/forward.ts +++ b/packages/pointer-events/src/forward.ts @@ -135,7 +135,7 @@ function forwardEvents( if (eventType != 'move' && eventType != 'wheel') { //if we start with a non-move event no, we intersect and commit //this allows enter, down, ... events to be forwarded to the scene even when they dont come with a move event - innerPointer.setIntersection(innerPointer.computeIntersection(scene, event)) + innerPointer.setIntersection(innerPointer.computeIntersection('pointer', scene, event)) innerPointer.commit(event, false) } pointerMap.set(event.pointerId, innerPointer) diff --git a/packages/pointer-events/src/intersections/intersector.ts b/packages/pointer-events/src/intersections/intersector.ts index 8c919b0..8f5b793 100644 --- a/packages/pointer-events/src/intersections/intersector.ts +++ b/packages/pointer-events/src/intersections/intersector.ts @@ -1,4 +1,4 @@ -import { Mesh, Object3D, Sphere, SphereGeometry } from 'three' +import { Mesh, Object3D, SphereGeometry } from 'three' import { Intersection } from '../index.js' import { PointerCapture } from '../pointer.js' diff --git a/packages/pointer-events/src/intersections/utils.ts b/packages/pointer-events/src/intersections/utils.ts index 64df975..31ce37a 100644 --- a/packages/pointer-events/src/intersections/utils.ts +++ b/packages/pointer-events/src/intersections/utils.ts @@ -55,6 +55,7 @@ function invertIf(toInvert: boolean, ifIsTrue: boolean): boolean { } export function intersectPointerEventTargets( + type: 'wheel' | 'pointer', object: Object3D, pointers: Array, parentHasListener: boolean = false, @@ -62,7 +63,7 @@ export function intersectPointerEventTargets( parentPointerEventsType?: AllowedPointerEventsType, parentPointerEventsOrder?: number, ): void { - const hasListener = parentHasListener || hasObjectListeners(object) + const hasListener = parentHasListener || hasObjectListeners(type, object) const pointerEvents = object.pointerEvents ?? parentPointerEvents const pointerEventsOrDefault = pointerEvents ?? object.defaultPointerEvents ?? 'listener' const pointerEventsType = object.pointerEventsType ?? parentPointerEventsType ?? 'all' @@ -96,6 +97,7 @@ export function intersectPointerEventTargets( const descendantsLength = descendants.length for (let i = 0; i < descendantsLength; i++) { intersectPointerEventTargets( + type, descendants[i], pointers, hasListener, @@ -106,20 +108,40 @@ export function intersectPointerEventTargets( } } -function hasObjectListeners(object: Object3D): boolean { +function hasObjectListeners(type: 'wheel' | 'pointer', object: Object3D): boolean { if (object.ancestorsHaveListeners) { return true } - if (object.__r3f != null && object.__r3f?.eventCount > 0) { + if (type === 'pointer' && object.ancestorsHavePointerListeners) { + return true + } + if (type === 'wheel' && object.ancestorsHaveWheelListeners) { return true } + if (object.__r3f != null && object.__r3f?.eventCount > 0) { + if (type === 'wheel' && object.__r3f['handlers']['onWheel'] != null) { + return true + } + if (type === 'pointer' && Object.keys(object.__r3f['handlers']).some((key) => key != 'onWheel')) { + return true + } + } if (object._listeners == null) { return false } + + if (type === 'wheel') { + const wheelListeners = object._listeners.wheel + return wheelListeners != null && wheelListeners.length > 0 + } + const entries = Object.entries(object._listeners) const length = entries.length for (let i = 0; i < length; i++) { const entry = entries[i] + if (entry[0] === 'wheel') { + continue + } if (!listenerNames.includes(entry[0])) { continue } diff --git a/packages/pointer-events/src/pointer.ts b/packages/pointer-events/src/pointer.ts index 824e313..3678003 100644 --- a/packages/pointer-events/src/pointer.ts +++ b/packages/pointer-events/src/pointer.ts @@ -64,7 +64,12 @@ declare module 'three' { intersectChildren?: boolean interactableDescendants?: Array + /** + * @deprecated + */ ancestorsHaveListeners?: boolean + ancestorsHavePointerListeners?: boolean + ancestorsHaveWheelListeners?: boolean } } @@ -179,12 +184,12 @@ export class Pointer { } } - computeIntersection(scene: Object3D, nativeEvent: NativeEvent) { + computeIntersection(type: 'wheel' | 'pointer', scene: Object3D, nativeEvent: NativeEvent) { if (this.pointerCapture != null) { return this.intersector.intersectPointerCapture(this.pointerCapture, nativeEvent) } this.intersector.startIntersection(nativeEvent) - intersectPointerEventTargets(scene, [this]) + intersectPointerEventTargets(type, scene, [this]) return this.intersector.finalizeIntersection(scene) } @@ -249,7 +254,7 @@ export class Pointer { * computes and commits a move */ move(scene: Object3D, nativeEvent: NativeEvent): void { - this.intersection = this.computeIntersection(scene, nativeEvent) + this.intersection = this.computeIntersection('pointer', scene, nativeEvent) this.commit(nativeEvent, true) } @@ -364,7 +369,7 @@ export class Pointer { return } if (!useMoveIntersection) { - this.wheelIntersection = this.computeIntersection(scene, nativeEvent) + this.wheelIntersection = this.computeIntersection('wheel', scene, nativeEvent) } const intersection = useMoveIntersection ? this.intersection : this.wheelIntersection if (intersection == null) {