Skip to content

Commit e0b575f

Browse files
committed
feat(core): add NgtObjectEvents directive to pass-through pointer event system
We can use NgtObjectEvents as a directive on elements: ngtObjectEvents. This approach requires the consumers to pass in a `target` as `Object3D` or `ElementRef<Object3D>` to attach the events on. Alternatively, we can use this directive as `hostDirective`; this approach can inject the `NgtObjectEvents` and call `ngtObjectEvents.set()` to set the Object3D value
1 parent 0f2c63a commit e0b575f

File tree

1 file changed

+77
-1
lines changed

1 file changed

+77
-1
lines changed

libs/core/src/lib/utils/object-events.ts

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,87 @@
1-
import { afterNextRender, DestroyRef, ElementRef, inject, Injector, Renderer2 } from '@angular/core';
1+
import {
2+
afterNextRender,
3+
DestroyRef,
4+
Directive,
5+
ElementRef,
6+
inject,
7+
Injector,
8+
model,
9+
output,
10+
Renderer2,
11+
} from '@angular/core';
212
import { assertInjector } from 'ngxtension/assert-injector';
313
import { injectAutoEffect } from 'ngxtension/auto-effect';
414
import { Object3D } from 'three';
515
import { supportedEvents } from '../dom/events';
616
import { NgtDomEvent, NgtThreeEvent } from '../types';
717
import { resolveRef } from './resolve-ref';
818

19+
@Directive({ standalone: true, selector: '[ngtObjectEvents]' })
20+
export class NgtObjectEvents {
21+
click = output<NgtThreeEvent<MouseEvent>>();
22+
dblclick = output<NgtThreeEvent<MouseEvent>>();
23+
contextmenu = output<NgtThreeEvent<MouseEvent>>();
24+
pointerup = output<NgtThreeEvent<PointerEvent>>();
25+
pointerdown = output<NgtThreeEvent<PointerEvent>>();
26+
pointerover = output<NgtThreeEvent<PointerEvent>>();
27+
pointerout = output<NgtThreeEvent<PointerEvent>>();
28+
pointerenter = output<NgtThreeEvent<PointerEvent>>();
29+
pointerleave = output<NgtThreeEvent<PointerEvent>>();
30+
pointermove = output<NgtThreeEvent<PointerEvent>>();
31+
pointermissed = output<NgtThreeEvent<MouseEvent>>();
32+
pointercancel = output<NgtThreeEvent<PointerEvent>>();
33+
wheel = output<NgtThreeEvent<WheelEvent>>();
34+
35+
// NOTE: we use model here to allow for the hostDirective host to set this value
36+
ngtObjectEvents = model<ElementRef<Object3D> | Object3D | null | undefined>();
37+
38+
constructor() {
39+
const injector = inject(Injector);
40+
41+
afterNextRender(() => {
42+
injectObjectEvents(
43+
this.ngtObjectEvents,
44+
{
45+
click: (event) => this.click.emit(event),
46+
dblclick: (event) => this.dblclick.emit(event),
47+
contextmenu: (event) => this.contextmenu.emit(event),
48+
pointerup: (event) => this.pointerup.emit(event as NgtThreeEvent<PointerEvent>),
49+
pointerdown: (event) => this.pointerdown.emit(event as NgtThreeEvent<PointerEvent>),
50+
pointerover: (event) => this.pointerover.emit(event as NgtThreeEvent<PointerEvent>),
51+
pointerout: (event) => this.pointerout.emit(event as NgtThreeEvent<PointerEvent>),
52+
pointerenter: (event) => this.pointerenter.emit(event as NgtThreeEvent<PointerEvent>),
53+
pointerleave: (event) => this.pointerleave.emit(event as NgtThreeEvent<PointerEvent>),
54+
pointermove: (event) => this.pointermove.emit(event as NgtThreeEvent<PointerEvent>),
55+
pointermissed: (event) => this.pointermissed.emit(event),
56+
pointercancel: (event) => this.pointercancel.emit(event as NgtThreeEvent<PointerEvent>),
57+
wheel: (event) => this.wheel.emit(event as NgtThreeEvent<WheelEvent>),
58+
},
59+
{ injector },
60+
);
61+
});
62+
}
63+
}
64+
65+
export const NgtObjectEventsHostDirective = {
66+
directive: NgtObjectEvents,
67+
inputs: ['ngtObjectEvents'],
68+
outputs: [
69+
'click',
70+
'dblclick',
71+
'contextmenu',
72+
'pointerup',
73+
'pointerdown',
74+
'pointerover',
75+
'pointerout',
76+
'pointerenter',
77+
'pointerleave',
78+
'pointermove',
79+
'pointermissed',
80+
'pointercancel',
81+
'wheel',
82+
],
83+
};
84+
985
export function injectObjectEvents(
1086
target: () => ElementRef<Object3D> | Object3D | null | undefined,
1187
events: {

0 commit comments

Comments
 (0)