66 InjectionToken ,
77 Injector ,
88 Signal ,
9+ Type ,
910 afterNextRender ,
1011 computed ,
1112 inject ,
@@ -15,17 +16,23 @@ import {
1516} from '@angular/core' ;
1617import { takeUntilDestroyed } from '@angular/core/rxjs-interop' ;
1718import { CylinderArgs , Triplet } from '@pmndrs/cannon-worker-api' ;
18- import { NgtArgs , extend , injectBeforeRender , injectStore } from 'angular-three' ;
19+ import { NgtArgs , injectBeforeRender , injectStore } from 'angular-three' ;
1920import { NgtcPhysics } from 'angular-three-cannon' ;
2021import { injectBox , injectCylinder , injectSphere } from 'angular-three-cannon/body' ;
2122import { injectConeTwist } from 'angular-three-cannon/constraint' ;
2223import { NgtcDebug } from 'angular-three-cannon/debug' ;
23- import * as THREE from 'three' ;
2424import { Color , ColorRepresentation , Mesh , Object3D } from 'three' ;
2525
26- extend ( THREE ) ;
26+ interface Handle {
27+ position : Signal < Triplet > | ( ( ) => Triplet ) ;
28+ ref : Signal < ElementRef < Object3D > > ;
29+ }
30+
31+ const Parent = new InjectionToken < Handle > ( 'PARENT' ) ;
2732
28- const Parent = new InjectionToken < { position : Signal < Triplet > ; ref : Signal < ElementRef < Object3D > > } > ( 'PARENT' ) ;
33+ function provideParent < THandle extends object > ( handle : Type < THandle > , factory : ( h : THandle ) => Handle ) {
34+ return { provide : Parent , useFactory : factory , deps : [ handle ] } ;
35+ }
2936
3037@Component ( {
3138 selector : 'app-chain-link' ,
@@ -40,35 +47,26 @@ const Parent = new InjectionToken<{ position: Signal<Triplet>; ref: Signal<Eleme
4047 imports : [ NgtArgs ] ,
4148 schemas : [ CUSTOM_ELEMENTS_SCHEMA ] ,
4249 changeDetection : ChangeDetectionStrategy . OnPush ,
43- providers : [
44- {
45- provide : Parent ,
46- useFactory : ( chainLink : ChainLink ) => ( { ref : chainLink . mesh , position : chainLink . position } ) ,
47- deps : [ ChainLink ] ,
48- } ,
49- ] ,
50+ providers : [ provideParent ( ChainLink , ( chainLink ) => ( { ref : chainLink . mesh , position : chainLink . position } ) ) ] ,
5051} )
5152export class ChainLink {
52- parent = inject ( Parent , { skipSelf : true } ) ;
53+ private parent = inject ( Parent , { skipSelf : true } ) ;
5354
5455 maxMultiplier = input < number > ( ) ;
5556 color = input < ColorRepresentation > ( '#575757' ) ;
5657 args = input < CylinderArgs > ( [ 0.5 , 0.5 , 2 , 16 ] ) ;
5758
58- height = computed ( ( ) => this . args ( ) [ 2 ] ?? 2 ) ;
59- position = computed < Triplet > ( ( ) => {
59+ private height = computed ( ( ) => this . args ( ) [ 2 ] ?? 2 ) ;
60+ protected position = computed < Triplet > ( ( ) => {
6061 const [ [ x , y , z ] , height ] = [ this . parent . position ( ) , this . height ( ) ] ;
6162 return [ x , y - height , z ] ;
6263 } ) ;
6364
64- mesh = viewChild . required < ElementRef < Mesh > > ( 'mesh' ) ;
65-
66- cylinder = injectCylinder (
67- ( ) => ( { mass : 1 , args : this . args ( ) , linearDamping : 0.8 , position : this . position ( ) } ) ,
68- this . mesh ,
69- ) ;
65+ protected mesh = viewChild . required < ElementRef < Mesh > > ( 'mesh' ) ;
7066
7167 constructor ( ) {
68+ injectCylinder ( ( ) => ( { mass : 1 , args : this . args ( ) , linearDamping : 0.8 , position : this . position ( ) } ) , this . mesh ) ;
69+
7270 const injector = inject ( Injector ) ;
7371 // NOTE: we want to run this in afterNextRender because we want the input to resolve
7472 afterNextRender ( ( ) => {
@@ -111,7 +109,7 @@ export class Chain {
111109 length = input . required < number > ( ) ;
112110 maxMultiplier = input < number > ( ) ;
113111
114- color = computed ( ( ) => {
112+ protected color = computed ( ( ) => {
115113 const maxMultiplier = this . maxMultiplier ( ) ;
116114 if ( maxMultiplier === undefined ) return '#575757' ;
117115
@@ -128,7 +126,7 @@ export class Chain {
128126 template : `
129127 <ngt-group>
130128 <ngt-mesh #mesh>
131- <ngt-box-geometry *args="args() " />
129+ <ngt-box-geometry *args="args" />
132130 <ngt-mesh-standard-material [roughness]="0.3" color="#575757" />
133131 </ngt-mesh>
134132 <ng-content />
@@ -137,26 +135,19 @@ export class Chain {
137135 imports : [ NgtArgs ] ,
138136 schemas : [ CUSTOM_ELEMENTS_SCHEMA ] ,
139137 changeDetection : ChangeDetectionStrategy . OnPush ,
140- providers : [
141- {
142- provide : Parent ,
143- useFactory : ( handle : PointerHandle ) => ( { ref : handle . mesh , position : ( ) => handle . position } ) ,
144- deps : [ PointerHandle ] ,
145- } ,
146- ] ,
138+ providers : [ provideParent ( PointerHandle , ( handle ) => ( { ref : handle . mesh , position : ( ) => handle . position } ) ) ] ,
147139} )
148140export class PointerHandle {
149- size = input . required < number > ( ) ;
150- args = computed < Triplet > ( ( ) => [ this . size ( ) , this . size ( ) , this . size ( ) * 2 ] ) ;
141+ protected args = [ 1.5 , 1.5 , 1.5 * 2 ] as Triplet ;
151142
152- position : Triplet = [ 0 , 0 , 0 ] ;
153- mesh = viewChild . required < ElementRef < Mesh > > ( 'mesh' ) ;
154-
155- boxApi = injectBox ( ( ) => ( { args : this . args ( ) , position : this . position , type : 'Kinematic' } ) , this . mesh ) ;
143+ protected position : Triplet = [ 0 , 0 , 0 ] ;
144+ protected mesh = viewChild . required < ElementRef < Mesh > > ( 'mesh' ) ;
156145
157146 constructor ( ) {
147+ const boxApi = injectBox ( ( ) => ( { args : this . args , position : this . position , type : 'Kinematic' } ) , this . mesh ) ;
148+
158149 injectBeforeRender ( ( { pointer : { x, y } , viewport : { width, height } } ) => {
159- this . boxApi ( ) ?. position . set ( ( x * width ) / 2 , ( y * height ) / 2 , 0 ) ;
150+ boxApi ( ) ?. position . set ( ( x * width ) / 2 , ( y * height ) / 2 , 0 ) ;
160151 } ) ;
161152 }
162153}
@@ -167,29 +158,25 @@ export class PointerHandle {
167158 template : `
168159 <ngt-group>
169160 <ngt-mesh #mesh>
170- <ngt-sphere-geometry *args="[radius() , 64, 64]" />
161+ <ngt-sphere-geometry *args="[1.5 , 64, 64]" />
171162 <ngt-mesh-standard-material [roughness]="0.3" color="#575757" />
172163 </ngt-mesh>
173164 <ng-content />
174165 </ngt-group>
175166 ` ,
176167 imports : [ NgtArgs ] ,
177- providers : [
178- {
179- provide : Parent ,
180- useFactory : ( handle : StaticHandle ) => ( { ref : handle . mesh , position : handle . position } ) ,
181- deps : [ StaticHandle ] ,
182- } ,
183- ] ,
168+ providers : [ provideParent ( StaticHandle , ( handle ) => ( { ref : handle . mesh , position : handle . position } ) ) ] ,
184169 schemas : [ CUSTOM_ELEMENTS_SCHEMA ] ,
185170 changeDetection : ChangeDetectionStrategy . OnPush ,
186171} )
187172export class StaticHandle {
188173 position = input . required < Triplet > ( ) ;
189- radius = input . required < number > ( ) ;
190- mesh = viewChild . required < ElementRef < Mesh > > ( 'mesh' ) ;
191174
192- sphere = injectSphere ( ( ) => ( { args : [ this . radius ( ) ] , position : this . position ( ) , type : 'Static' } ) , this . mesh ) ;
175+ protected mesh = viewChild . required < ElementRef < Mesh > > ( 'mesh' ) ;
176+
177+ constructor ( ) {
178+ injectSphere ( ( ) => ( { args : [ 1.5 ] , position : this . position ( ) , type : 'Static' } ) , this . mesh ) ;
179+ }
193180}
194181
195182@Component ( {
@@ -208,12 +195,12 @@ export class StaticHandle {
208195 />
209196
210197 <ngtc-physics [options]="{ gravity: [0, -40, 0], allowSleep: false }">
211- <app-pointer-handle [size]="1.5" >
198+ <app-pointer-handle>
212199 <app-chain [length]="7" />
213200 </app-pointer-handle>
214201
215202 @for (maxMultiplier of maxMultiplierExamples(); track maxMultiplier.key) {
216- <app-static-handle [radius]="1.5" [ position]="maxMultiplier.position">
203+ <app-static-handle [position]="maxMultiplier.position">
217204 <app-chain [maxMultiplier]="maxMultiplier.value" [length]="8" />
218205 </app-static-handle>
219206 }
@@ -225,12 +212,12 @@ export class StaticHandle {
225212 host : { class : 'chain-experience' } ,
226213} )
227214export class Experience {
228- Math = Math ;
215+ protected Math = Math ;
229216
230217 private store = injectStore ( ) ;
231218
232- resetCount = signal ( 0 ) ;
233- maxMultiplierExamples = computed ( ( ) =>
219+ private resetCount = signal ( 0 ) ;
220+ protected maxMultiplierExamples = computed ( ( ) =>
234221 maxMultiplierExamples . map ( ( value , index , array ) => ( {
235222 value,
236223 key : `${ value } -${ this . resetCount ( ) } ` ,
0 commit comments