Skip to content

Commit c1c0ffc

Browse files
committed
docs(examples): update cannon routes
1 parent 43070b5 commit c1c0ffc

File tree

22 files changed

+2129
-6
lines changed

22 files changed

+2129
-6
lines changed

apps/kitchen-sink-new/src/app/app.routes.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Route } from '@angular/router';
22

33
export const appRoutes: Route[] = [
4-
// {
5-
// path: 'cannon',
6-
// loadComponent: () => import('./cannon/cannon'),
7-
// loadChildren: () => import('./cannon/cannon.routes'),
8-
// title: 'Cannon - Angular Three Demo',
9-
// },
4+
{
5+
path: 'cannon',
6+
loadComponent: () => import('./cannon/cannon'),
7+
loadChildren: () => import('./cannon/cannon.routes'),
8+
title: 'Cannon - Angular Three Demo',
9+
},
1010
{
1111
path: 'postprocessing',
1212
loadComponent: () => import('./postprocessing/postprocessing'),
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
2+
import { NgtCanvas, NgtCanvasContent } from 'angular-three/dom';
3+
import { SceneGraph } from './scene';
4+
import { State } from './state';
5+
6+
@Component({
7+
template: `
8+
<ngt-canvas [shadows]="true" [camera]="{ position: [0, 0, 15] }">
9+
<app-scene-graph *canvasContent />
10+
</ngt-canvas>
11+
<div class="font-mono absolute top-0 right-0 flex gap-4 text-white">
12+
<button (click)="state.toggleDebugging()">Toggle debugging: {{ state.isDebugging() }}</button>
13+
<span>|</span>
14+
<button (click)="state.changeGravity()">Change gravity: {{ state.gravity() }}</button>
15+
</div>
16+
`,
17+
imports: [NgtCanvas, SceneGraph, NgtCanvasContent],
18+
changeDetection: ChangeDetectionStrategy.OnPush,
19+
host: { class: 'basic-cannon ' },
20+
providers: [State],
21+
})
22+
export default class Basic {
23+
protected state = inject(State);
24+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import {
2+
CUSTOM_ELEMENTS_SCHEMA,
3+
ChangeDetectionStrategy,
4+
Component,
5+
ElementRef,
6+
afterNextRender,
7+
inject,
8+
input,
9+
signal,
10+
viewChild,
11+
} from '@angular/core';
12+
import { Triplet } from '@pmndrs/cannon-worker-api';
13+
import { NgtArgs } from 'angular-three';
14+
import { NgtcPhysics } from 'angular-three-cannon';
15+
import { injectBox, injectPlane } from 'angular-three-cannon/body';
16+
import { NgtcDebug } from 'angular-three-cannon/debug';
17+
import { Mesh } from 'three';
18+
import { State } from './state';
19+
20+
@Component({
21+
selector: 'app-plane',
22+
template: `
23+
<ngt-mesh #mesh [receiveShadow]="true">
24+
<ngt-plane-geometry *args="args" />
25+
<ngt-mesh-standard-material color="#171717" />
26+
</ngt-mesh>
27+
`,
28+
imports: [NgtArgs],
29+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
30+
changeDetection: ChangeDetectionStrategy.OnPush,
31+
})
32+
export class Plane {
33+
position = input<Triplet>([0, 0, 0]);
34+
protected args = [1000, 1000];
35+
private mesh = viewChild.required<ElementRef<Mesh>>('mesh');
36+
37+
constructor() {
38+
injectPlane(() => ({ mass: 0, position: this.position(), args: this.args }), this.mesh);
39+
}
40+
}
41+
42+
@Component({
43+
selector: 'app-box',
44+
template: `
45+
<ngt-mesh #mesh [receiveShadow]="true" [castShadow]="true">
46+
<ngt-box-geometry *args="args" />
47+
<ngt-mesh-standard-material [roughness]="0.5" color="#575757" />
48+
</ngt-mesh>
49+
`,
50+
imports: [NgtArgs],
51+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
52+
changeDetection: ChangeDetectionStrategy.OnPush,
53+
})
54+
export class Box {
55+
position = input<Triplet>([0, 0, 0]);
56+
protected args: Triplet = [2, 2, 2];
57+
private mesh = viewChild.required<ElementRef<Mesh>>('mesh');
58+
59+
constructor() {
60+
injectBox(() => ({ mass: 10000, position: this.position(), args: this.args }), this.mesh);
61+
}
62+
}
63+
64+
@Component({
65+
selector: 'app-scene-graph',
66+
template: `
67+
<ngt-point-light [position]="[-10, -10, 30]" [intensity]="0.25 * Math.PI" [decay]="0" />
68+
<ngt-spot-light
69+
[intensity]="0.3 * Math.PI"
70+
[position]="[30, 30, 50]"
71+
[angle]="0.2"
72+
[penumbra]="1"
73+
[decay]="0"
74+
[castShadow]="true"
75+
/>
76+
77+
<ngtc-physics
78+
[options]="{ gravity: [0, 0, state.gravity()], iterations: 10 }"
79+
[debug]="{ enabled: state.isDebugging(), color: 'white' }"
80+
>
81+
<app-plane [position]="[0, 0, -10]" />
82+
@if (showPlane()) {
83+
<app-plane />
84+
}
85+
86+
<app-box [position]="[1, 0, 1]" />
87+
<app-box [position]="[2, 1, 5]" />
88+
<app-box [position]="[0, 0, 6]" />
89+
<app-box [position]="[-1, 1, 8]" />
90+
<app-box [position]="[-2, 2, 13]" />
91+
<app-box [position]="[2, -1, 13]" />
92+
93+
@if (!showPlane()) {
94+
<app-box [position]="[0.5, 1.0, 20]" />
95+
}
96+
</ngtc-physics>
97+
`,
98+
imports: [Box, Plane, NgtcPhysics, NgtcDebug],
99+
changeDetection: ChangeDetectionStrategy.OnPush,
100+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
101+
host: { class: 'basic-experience' },
102+
})
103+
export class SceneGraph {
104+
protected Math = Math;
105+
protected state = inject(State);
106+
protected showPlane = signal(true);
107+
108+
constructor() {
109+
afterNextRender(() => {
110+
setTimeout(() => {
111+
this.showPlane.set(false);
112+
}, 5000);
113+
});
114+
}
115+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { signal } from '@angular/core';
2+
import { createInjectable } from 'ngxtension/create-injectable';
3+
4+
export const State = createInjectable(
5+
() => {
6+
const isDebugging = signal(false);
7+
const gravity = signal(-20);
8+
9+
return {
10+
gravity: gravity.asReadonly(),
11+
isDebugging: isDebugging.asReadonly(),
12+
changeGravity: () => gravity.update((prev) => (prev === -20 ? -10 : -20)),
13+
toggleDebugging: () => isDebugging.update((prev) => !prev),
14+
};
15+
},
16+
{ providedIn: 'scoped' },
17+
);
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { Routes } from '@angular/router';
2+
3+
const routes: Routes = [
4+
{
5+
path: 'basic',
6+
loadComponent: () => import('./basic/basic'),
7+
},
8+
{
9+
path: 'kinematic-cube',
10+
loadComponent: () => import('./kinematic-cube/kinematic-cube'),
11+
data: {
12+
credits: {
13+
title: 'Kinematic Cube',
14+
link: 'https://cannon.pmnd.rs/#/demo/KinematicCube',
15+
},
16+
},
17+
},
18+
{
19+
path: 'compound',
20+
loadComponent: () => import('./compound/compound'),
21+
data: {
22+
credits: {
23+
title: 'Compound Body',
24+
link: 'https://cannon.pmnd.rs/#/demo/CompoundBody',
25+
},
26+
},
27+
},
28+
{
29+
path: 'chain',
30+
loadComponent: () => import('./chain/chain'),
31+
data: {
32+
credits: {
33+
title: 'Chain',
34+
link: 'https://cannon.pmnd.rs/#/demo/Chain',
35+
class: 'text-white',
36+
},
37+
},
38+
},
39+
{
40+
path: 'cube-heap',
41+
loadComponent: () => import('./cube-heap/cube-heap'),
42+
data: {
43+
credits: {
44+
title: 'Cube Heap',
45+
link: 'https://cannon.pmnd.rs/#/demo/CubeHeap',
46+
},
47+
},
48+
},
49+
{
50+
path: 'convexpolyhedron',
51+
loadComponent: () => import('./convexpolyhedron/convexpolyhedron'),
52+
data: {
53+
credits: {
54+
title: 'Convex Polyhedron',
55+
link: 'https://cannon.pmnd.rs/#/demo/ConvexPolyhedron',
56+
},
57+
},
58+
},
59+
{
60+
path: 'monday-morning',
61+
loadComponent: () => import('./monday-morning/monday-morning'),
62+
data: {
63+
credits: {
64+
title: 'Monday Morning',
65+
link: 'https://cannon.pmnd.rs/#/demo/MondayMorning',
66+
class: 'text-white',
67+
},
68+
},
69+
},
70+
{
71+
path: '',
72+
redirectTo: 'basic',
73+
pathMatch: 'full',
74+
},
75+
];
76+
77+
export default routes;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { ChangeDetectionStrategy, Component } from '@angular/core';
2+
import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';
3+
import { extend } from 'angular-three';
4+
import * as THREE from 'three';
5+
import routes from './cannon.routes';
6+
7+
extend(THREE);
8+
9+
@Component({
10+
template: `
11+
<div class="h-svh">
12+
<router-outlet />
13+
</div>
14+
15+
<ul class=" absolute left-12 bottom-12 grid grid-cols-6 gap-4">
16+
@for (example of examples; track example) {
17+
<li class="h-6 w-6">
18+
<a
19+
routerLinkActive
20+
#rla="routerLinkActive"
21+
class="inline-block h-full w-full rounded-full"
22+
[class]="rla.isActive ? 'bg-red-500' : 'bg-white'"
23+
[routerLinkActiveOptions]="{ exact: true }"
24+
[routerLink]="['/cannon', example]"
25+
[title]="'Navigate to ' + example"
26+
></a>
27+
</li>
28+
}
29+
</ul>
30+
`,
31+
imports: [RouterOutlet, RouterLink, RouterLinkActive],
32+
changeDetection: ChangeDetectionStrategy.OnPush,
33+
host: { class: 'cannon' },
34+
})
35+
export default class Cannon {
36+
protected examples = routes.filter((route) => !!route.path).map((route) => route.path);
37+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { ChangeDetectionStrategy, Component } from '@angular/core';
2+
import { NgtCanvas, NgtCanvasContent } from 'angular-three/dom';
3+
import { SceneGraph } from './scene';
4+
5+
@Component({
6+
template: `
7+
<ngt-canvas shadows [camera]="{ fov: 50, position: [0, 5, 20] }">
8+
<app-scene-graph *canvasContent />
9+
</ngt-canvas>
10+
<div class="absolute bottom-4 right-4 font-mono text-white">* Click to reset</div>
11+
`,
12+
imports: [NgtCanvas, NgtCanvasContent, SceneGraph],
13+
changeDetection: ChangeDetectionStrategy.OnPush,
14+
host: { class: 'chain-cannon' },
15+
})
16+
export default class Chain {}

0 commit comments

Comments
 (0)