Skip to content

Commit 50f0cea

Browse files
committed
fix(core): change the way NgtSelect works
NgtSelect is now a directive to attach on `ngt-group` OR `ngt-mesh`. Attaching on `ngt-group` will affect all `Mesh` children. Attaching on `ngt-mesh` will only affect itself.
1 parent 60ed395 commit 50f0cea

File tree

2 files changed

+27
-33
lines changed

2 files changed

+27
-33
lines changed

apps/kitchen-sink/src/app/postprocessing/outline/experience.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import { NgtsOrbitControls } from 'angular-three-soba/controls';
1414
*
1515
* 1b. We can wrap `<ng-container ngtSelection>` around the objects we want to select AS WELL AS the Outline effect.
1616
*
17+
* ngtSelect can be used on ngt-group or ngt-mesh. ngt-group will select all children, ngt-mesh will only select itself.
18+
*
1719
* 2. Via selection input on NgtpOutline
1820
* If we want to control the selection ourselves, we can pass in the selection input an Array of Object3D or ElementRef<Object3D>
1921
* then we control this selection collection based on our own logic.
@@ -33,12 +35,20 @@ import { NgtsOrbitControls } from 'angular-three-soba/controls';
3335
<ngt-point-light [position]="[0, -1, -1]" [decay]="0" color="green" />
3436
<ngt-directional-light [position]="[0, 1, 1]" />
3537
36-
<ngt-select [enabled]="hovered()" (pointerenter)="hovered.set(true)" (pointerleave)="hovered.set(false)">
38+
<ngt-group [ngtSelect]="hovered()" (pointerenter)="hovered.set(true)" (pointerleave)="hovered.set(false)">
3739
<ngt-mesh>
3840
<ngt-box-geometry />
3941
<ngt-mesh-standard-material color="hotpink" />
4042
</ngt-mesh>
41-
</ngt-select>
43+
<ngt-mesh [position]="[0.5, -0.25, 0.75]">
44+
<ngt-sphere-geometry *args="[0.25]" />
45+
<ngt-mesh-standard-material color="orange" />
46+
</ngt-mesh>
47+
<ngt-mesh [position]="[-0.5, -0.25, 0.75]">
48+
<ngt-cone-geometry *args="[0.25, 0.5]" />
49+
<ngt-mesh-standard-material color="yellow" />
50+
</ngt-mesh>
51+
</ngt-group>
4252
4353
<ngtp-effect-composer [options]="{ autoClear: false }">
4454
<ngtp-outline [options]="{ edgeStrength: 100, pulseSpeed: 0 }" />

libs/core/src/lib/directives/selection.ts

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
import {
22
afterNextRender,
33
booleanAttribute,
4-
ChangeDetectionStrategy,
5-
Component,
6-
CUSTOM_ELEMENTS_SCHEMA,
74
Directive,
85
ElementRef,
96
inject,
107
input,
118
signal,
129
untracked,
13-
viewChild,
1410
} from '@angular/core';
1511
import { injectAutoEffect } from 'ngxtension/auto-effect';
16-
import { Group, Object3D } from 'three';
12+
import { Group, Mesh, Object3D } from 'three';
1713
import { getLocalState } from '../instance';
18-
import { extend } from '../renderer';
19-
import { NgtGroup } from '../three-types';
20-
import { NgtObjectEvents, NgtObjectEventsHostDirective } from '../utils/object-events';
2114

2215
@Directive({ standalone: true, selector: '[ngtSelection]' })
2316
export class NgtSelection {
@@ -35,47 +28,38 @@ export class NgtSelection {
3528
}
3629
}
3730

38-
@Component({
39-
selector: 'ngt-select',
40-
standalone: true,
41-
template: `
42-
<ngt-group #group [parameters]="options()">
43-
<ng-content />
44-
</ngt-group>
45-
`,
46-
hostDirectives: [NgtObjectEventsHostDirective],
47-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
48-
changeDetection: ChangeDetectionStrategy.OnPush,
49-
})
31+
@Directive({ standalone: true, selector: 'ngt-group[ngtSelect], ngt-mesh[ngtSelect]' })
5032
export class NgtSelect {
51-
enabled = input(false, { transform: booleanAttribute });
52-
options = input({} as Partial<NgtGroup>);
33+
enabled = input(false, { transform: booleanAttribute, alias: 'ngtSelect' });
5334

54-
groupRef = viewChild.required<ElementRef<Group>>('group');
35+
host = inject<ElementRef<Group | Mesh>>(ElementRef);
5536

5637
constructor() {
57-
extend({ Group });
58-
59-
const objectEvents = inject(NgtObjectEvents, { host: true });
6038
const selection = inject(NgtSelection);
6139
const autoEffect = injectAutoEffect();
6240

6341
afterNextRender(() => {
64-
objectEvents.ngtObjectEvents.set(this.groupRef());
65-
6642
autoEffect(
6743
() => {
68-
const group = this.groupRef().nativeElement;
69-
const localState = getLocalState(group);
44+
const host = this.host.nativeElement;
45+
if (!host) return;
46+
47+
const localState = getLocalState(host);
7048
if (!localState) return;
7149

7250
const enabled = this.enabled();
7351
if (!enabled) return;
7452

53+
// ngt-mesh[ngtSelect]
54+
if (host.type === 'Mesh') {
55+
selection.select(host);
56+
return () => selection.unselect(host);
57+
}
58+
7559
const [collection] = [untracked(selection.collection), localState.objects()];
7660
let changed = false;
7761
const current: Object3D[] = [];
78-
group.traverse((child) => {
62+
host.traverse((child) => {
7963
child.type === 'Mesh' && current.push(child);
8064
if (collection.indexOf(child) === -1) changed = true;
8165
});

0 commit comments

Comments
 (0)