beforeRender
beforeRender is a Custom Inject Function that allows you to execute logic before each frame render. This is useful for animations, updates, or any computations that need to happen on every frame.
Usage
beforeRender requires a before render callback. This callback is invoked on every frame with NgtRenderState
export interface NgtRenderState extends NgtState { delta: number; frame?: XRFrame;}Check out Store section for details on NgtState.
export class MyCmp { constructor() { beforeRender(({ camera, delta }) => { camera.position.x = Math.sin(Date.now() / 1000) * delta; }); }}Optional injector
Since beforeRender is a CIF, it has to be invoked in an Injection Context. In order to invoke beforeRender outside of an Injection Context, you can provide an Injector to the injector property of the 2nd argument to beforeRender
export class MyCmp { constructor() { const injector = inject(Injector); afterNextRender(() => { // outside of Injection Context, provide Injector ✅ beforeRender(() => {}, { injector }) }) }}Optional priority
The priority parameter determines the order of execution when multiple before render callbacks are registered:
// executes firstbeforeRender(cb1, { priority: 1 });// executes secondbeforeRender(cb2, { priority: 2 });priority can also be dynamic using a Signal<number>
export class MyCmp { priority = input(0);
constructor() { beforeRender( ({ camera, delta }) => { camera.position.x = Math.sin(Date.now() / 1000) * delta; }, { priority: this.priority } ); }}How it works
beforeRender subscribes to the internal render loop of Angular Three.
When using a static priority number, it returns an unsubscribe function, but you typically don’t need to use it as it’s automatically handled by Angular’s DestroyRef
When using a dynamic priority, it sets up an internal effect and returns the EffectRef#destroy function. Again, cleanup is automatically handled through DestroyRef.