11import { Object3D , type Intersection } from "three"
2- import type { Intersect } from "../playground/controls/type-utils.ts"
3- import { $S3C } from "./constants.ts"
4- import type { BaseEvent , Context , EventName , Meta , StoppableEvent } from "./types.ts"
5- import { isInstance } from "./utils.ts"
2+ import type { Context , EventName , Meta , Prettify , ThreeEvent } from "./types.ts"
3+ import { getMeta } from "./utils.ts"
64
75const eventNameMap = {
86 onClick : "click" ,
@@ -60,7 +58,7 @@ export const isEventType = (type: string): type is EventName =>
6058/** Creates a `ThreeEvent` (intersection excluded) from the current `MouseEvent` | `WheelEvent`. */
6159function createThreeEvent <
6260 TEvent extends Event ,
63- TConfig extends { stoppable ?: boolean ; intersections ?: Intersection [ ] } ,
61+ TConfig extends { stoppable ?: boolean ; intersections ?: Array < Intersection > } ,
6462> ( nativeEvent : TEvent , { stoppable = true , intersections } : TConfig = { } ) {
6563 const event : Record < string , any > = stoppable
6664 ? {
@@ -77,21 +75,21 @@ function createThreeEvent<
7775 event . intersection = intersections [ 0 ]
7876 }
7977
80- return event as Intersect <
81- [
82- TConfig [ "stoppable" ] extends false
83- ? TConfig [ "stoppable" ] extends undefined
84- ? StoppableEvent < TEvent >
85- : BaseEvent < TEvent >
86- : StoppableEvent < TEvent > ,
87- TConfig [ "intersections" ] extends Intersection [ ]
88- ? {
89- intersections : Intersection [ ]
90- intersection : Intersection
91- currentIntersection ?: Intersection
92- }
93- : unknown ,
94- ]
78+ return event as Prettify <
79+ Omit <
80+ ThreeEvent <
81+ TEvent ,
82+ {
83+ stoppable : TConfig [ "stoppable" ] extends false
84+ ? TConfig [ "stoppable" ] extends true
85+ ? true
86+ : false
87+ : true
88+ intersections : TConfig [ "intersections" ] extends Intersection [ ] ? true : false
89+ }
90+ > ,
91+ "currentIntersection"
92+ >
9593 >
9694}
9795
@@ -121,9 +119,12 @@ function raycast<TNativeEvent extends MouseEvent | WheelEvent>(
121119 for ( const object of stack ) {
122120 if ( visitedSet . has ( object ) ) continue
123121 visitedSet . add ( object )
124- if ( isInstance ( object ) && object [ $S3C ] . props ?. raycastable !== false ) {
122+
123+ const meta = getMeta ( object )
124+ if ( meta && meta . props . raycastable !== false ) {
125125 nodeSet . add ( object )
126126 }
127+
127128 stack . push ( ...object . children )
128129 }
129130
@@ -162,26 +163,29 @@ function createMissableEventRegistry(
162163 const stoppableEvent = createThreeEvent ( nativeEvent , { intersections } )
163164
164165 for ( const intersection of intersections ) {
165- let node : Object3D | null = intersection . object
166-
166+ // Update currentIntersection
167+ // @ts -expect-error TODO: fix type-error
167168 stoppableEvent . currentIntersection = intersection
168169
170+ // Bubble down
171+ let node : Object3D | null = intersection . object
169172 while ( node && ! stoppableEvent . stopped && ! visitedObjects . has ( node ) ) {
170173 missedObjects . delete ( node )
171174 visitedObjects . add ( node )
172- if ( isInstance ( node ) ) {
173- node [ $S3C ] . props [ type ] ?.( stoppableEvent )
174- }
175+ getMeta ( node ) ?. props [ type ] ?.(
176+ // @ts -expect-error TODO: fix type-error
177+ stoppableEvent ,
178+ )
175179 node = node . parent
176180 }
177181 }
178182
179183 // Call the respective canvas event-handler
180184 // if event propagated all the way down
181185 if ( ! stoppableEvent . stopped ) {
182- if ( "currentIntersection" in stoppableEvent ) {
183- delete stoppableEvent . currentIntersection
184- }
186+ // Remove currentIntersection
187+ // @ts -expect-error TODO: fix type-error
188+ delete stoppableEvent . currentIntersection
185189 context . props [ type ] ?.( stoppableEvent )
186190 }
187191
@@ -207,9 +211,7 @@ function createMissableEventRegistry(
207211 const missedEvent = createThreeEvent ( nativeEvent , { stoppable : false } )
208212
209213 for ( const object of missedObjects ) {
210- if ( isInstance ( object ) ) {
211- object [ $S3C ] . props [ missedType ] ?.( missedEvent )
212- }
214+ getMeta ( object ) ?. props [ missedType ] ?.( missedEvent )
213215 }
214216
215217 if ( visitedObjects . size > 0 ) {
@@ -251,24 +253,31 @@ function createHoverEventRegistry(type: "Mouse" | "Pointer", context: Context) {
251253 const enterSet = new Set < Object3D > ( )
252254
253255 for ( const intersection of intersections ) {
254- // Mutate event
255- enterEvent . intersection = intersection
256+ // Update currentIntersection
257+ // @ts -expect-error TODO: fix type-error
258+ enterEvent . currentIntersection = intersection
256259
257260 // Bubble up
258261 let current : Object3D | null = intersection . object
259262 while ( current && ! enterSet . has ( current ) ) {
260263 enterSet . add ( current )
261-
262- if ( isInstance ( current ) && ! hoveredSet . has ( current ) ) {
263- current [ $S3C ] . props [ `on${ type } Enter` ] ?.( enterEvent )
264+ if ( ! hoveredSet . has ( current ) ) {
265+ getMeta ( current ) ?. props [ `on${ type } Enter` ] ?.(
266+ // @ts -expect-error TODO: fix type-error
267+ enterEvent ,
268+ )
264269 }
270+
265271 // We bubble a layer down.
266272 current = current . parent
267273 }
268274 }
269275
270276 if ( hoveredCanvas === false ) {
271- context . props [ `on${ type } Enter` ] ?.( enterEvent )
277+ context . props [ `on${ type } Enter` ] ?.(
278+ // @ts -expect-error TODO: fix type-error
279+ enterEvent ,
280+ )
272281 hoveredCanvas = true
273282 }
274283
@@ -277,18 +286,21 @@ function createHoverEventRegistry(type: "Mouse" | "Pointer", context: Context) {
277286 const moveSet = new Set ( )
278287
279288 for ( const intersection of intersections ) {
280- // Mutate currentIntersection
289+ // Update currentIntersection
290+ // @ts -expect-error TODO: fix type-error
281291 moveEvent . currentIntersection = intersection
282292
283293 // Bubble up
284294 let current : Object3D | null = intersection . object
285295
286296 while ( current && ! moveSet . has ( current ) ) {
287297 moveSet . add ( current )
288-
289- if ( isInstance ( current ) ) {
290- // @ts -expect-error TODO: fix type-error
291- current [ $S3C ] . props [ `on${ type } Move` ] ?.( moveEvent )
298+ const meta = getMeta ( current )
299+ if ( meta ) {
300+ meta . props [ `on${ type } Move` ] ?.(
301+ // @ts -expect-error TODO: fix type-error
302+ moveEvent ,
303+ )
292304 // Break if event was
293305 if ( moveEvent . stopped ) {
294306 break
@@ -300,32 +312,39 @@ function createHoverEventRegistry(type: "Mouse" | "Pointer", context: Context) {
300312 }
301313
302314 if ( ! moveEvent . stopped ) {
303- // Remove currentIntersection from moveEvent
315+ // Remove currentIntersection
316+ // @ts -expect-error TODO: fix type-error
304317 delete moveEvent . currentIntersection
305- context . props [ `on${ type } Move` ] ?.( moveEvent )
318+ context . props [ `on${ type } Move` ] ?.(
319+ // @ts -expect-error TODO: fix type-error
320+ moveEvent ,
321+ )
306322 }
307323
308324 // Handle leave-event
309- const leaveEvent = createThreeEvent ( nativeEvent )
325+ const leaveEvent = createThreeEvent ( nativeEvent , { intersections , stoppable : false } )
310326 const leaveSet = hoveredSet . difference ( enterSet )
311327 hoveredSet = enterSet
312328
313329 for ( const object of leaveSet . values ( ) ) {
314- if ( isInstance ( object ) ) {
315- object [ $S3C ] . props ?. [ `on${ type } Leave` ] ?.( leaveEvent )
316- }
330+ getMeta ( object ) ?. props [ `on${ type } Leave` ] ?.(
331+ // @ts -expect-error TODO: fix type-error
332+ leaveEvent ,
333+ )
317334 }
318335 } )
319336
320337 context . canvas . addEventListener ( eventNameMap [ `on${ type } Leave` ] , nativeEvent => {
321338 const leaveEvent = createThreeEvent ( nativeEvent , { stoppable : false } )
339+ // @ts -expect-error TODO: fix type-error
322340 context . props [ `on${ type } Leave` ] ?.( leaveEvent )
323341 hoveredCanvas = false
324342
325343 for ( const object of hoveredSet ) {
326- if ( isInstance ( object ) ) {
327- object [ $S3C ] . props [ `on${ type } Leave` ] ?.( leaveEvent )
328- }
344+ getMeta ( object ) ?. props [ `on${ type } Leave` ] ?.(
345+ // @ts -expect-error TODO: fix type-error
346+ leaveEvent ,
347+ )
329348 }
330349 hoveredSet . clear ( )
331350 } )
@@ -361,25 +380,27 @@ function createDefaultEventRegistry(
361380 const event = createThreeEvent ( nativeEvent , { intersections } )
362381
363382 for ( const intersection of intersections ) {
383+ // Update currentIntersection
384+ // @ts -expect-error TODO: fix type-error
385+ event . currentIntersection = intersection
386+
364387 // Bubble up
365388 let node : Object3D | null = intersection . object
366389
367- event . intersection = intersection
368-
369390 while ( node && ! event . stopped ) {
370- if ( isInstance ( intersection . object ) ) {
391+ getMeta ( intersection . object ) ?. props [ type ] ?. (
371392 // @ts -expect-error TODO: fix type-error
372- intersection . object [ $S3C ] . props [ type ] ?. ( event )
373- }
393+ event ,
394+ )
374395 node = node . parent
375396 }
376397 }
377398
378399 if ( ! event . stopped ) {
379- // Remove trailing intersection from event
380- if ( "intersection" in event ) {
381- delete event . intersection
382- }
400+ // Remove currentIntersection
401+ // @ts -expect-error TODO: fix type-error
402+ delete event . currentIntersection
403+
383404 // @ts -expect-error TODO: fix type-error
384405 context . props [ type ] ?.( event )
385406 }
0 commit comments