Routing
Sometimes, we might have use-cases where we need to load different Scene graph while keeping the Canvas alive on the route level.
To help with this, angular-three
provides the component NgtRoutedScene
To start, we can create two Scene components: RedScene
and BlueScene
- red-scene.component.ts
- blue-scene.component.ts
import { Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, ViewChild } from '@angular/core';
import { injectBeforeRender } from 'angular-three';
@Component({
standalone: true,
template: `
<ngt-mesh #cube>
<ngt-box-geometry />
<ngt-mesh-basic-material color="red" />
</ngt-mesh>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export default class RedScene {
@ViewChild('cube', { static: true }) cube!: ElementRef<THREE.Mesh>;
constructor() {
injectBeforeRender(({ clock }) => {
this.cube.nativeElement.rotation.x = clock.elapsedTime;
this.cube.nativeElement.rotation.y = clock.elapsedTime;
});
}
}
import { Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, ViewChild } from '@angular/core';
import { injectBeforeRender } from 'angular-three';
@Component({
standalone: true,
template: `
<ngt-mesh #cube>
<ngt-box-geometry />
<ngt-mesh-basic-material color="blue" />
</ngt-mesh>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export default class BlueScene {
@ViewChild('cube', { static: true }) cube!: ElementRef<THREE.Mesh>;
constructor() {
injectBeforeRender(({ clock }) => {
this.cube.nativeElement.rotation.x = clock.elapsedTime;
this.cube.nativeElement.rotation.y = clock.elapsedTime;
});
}
}
Next, we'll provide RedScene
and BlueScene
as lazy-load component in our route configuration.
main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [
provideRouter([
{
path: '',
loadComponent: () => import('./app/red-scene.component'),
},
{
path: 'blue',
loadComponent: () => import('./app/blue-scene.component'),
},
]),
],
}).catch((err) => console.error(err));
Finally, we'll use NgtRoutedScene
as the [sceneGraph]
app.component.ts
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { extend, NgtCanvas, NgtRoutedScene } from 'angular-three';
import * as THREE from 'three';
extend(THREE);
@Component({
standalone: true,
selector: 'angular-three-root',
template: `
<ul>
<li>
<a routerLink="/">Red</a>
</li>
<li>
<a routerLink="/blue">Blue</a>
</li>
</ul>
<ngt-canvas [sceneGraph]="scene" />
`,
imports: [NgtCanvas, RouterLink],
})
export class AppComponent {
readonly scene = NgtRoutedScene;
}