Skip to content

How it works

Import NgtcPhysics from angular-three-cannon

import { NgtcPhysics } from 'angular-three-cannon';

Render the NgtcPhysics component in your scene graph

@Component({
standalone: true,
imports: [NgtcPhysics],
template: `
<ngtc-physics>
<!-- objects that are subject to physics -->
</ngtc-physics>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class SceneGraph {}

Pick a Body shape

angular-three-cannon/body provides a variety of body shapes in form of Custom Inject Function that can be used to create physics bodies.

import { injectBox } from 'angular-three-cannon/body';
@Component({
selector: 'app-box',
standalone: true,
template: `
<ngt-mesh #mesh [receiveShadow]="true" [castShadow]="true">
<ngt-box-geometry />
</ngt-mesh>
`,
imports: [NgtArgs],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class Box {
mesh = viewChild.required<ElementRef<Mesh>>('mesh');
box = injectBox(() => ({ mass: 1 }), this.mesh);
}

injectBox accepts some physics properties as an argument and an () => ElementRef<Object3D> as the second argument to tie the body to the object.

The returned value is a Signal<NgtcBodyPublicApi | null> that can be used to control the body, set position, rotation, and subscribe to changes.

import { injectBox } from 'angular-three-cannon/body';
@Component({
selector: 'app-box',
standalone: true,
template: `
<ngt-mesh #mesh [receiveShadow]="true" [castShadow]="true">
<ngt-box-geometry />
</ngt-mesh>
`,
imports: [NgtArgs],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class Box {
mesh = viewChild.required<ElementRef<Mesh>>('mesh');
box = injectBox(() => ({ mass: 1 }), this.mesh);
constructor() {
injectBeforeRender(({ clock }) => {
const api = this.box();
if (!api) return;
api.position.set(Math.sin(clock.getElapsedTime()) * 5, 0, 0);
})
}
}

Example