Skip to content

injectBeforeRender

injectBeforeRender 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

injectBeforeRender 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() {
injectBeforeRender(({ camera, delta }) => {
camera.position.x = Math.sin(Date.now() / 1000) * delta;
});
}
}

Optional injector

Since injectBeforeRender is a CIF, it has to be invoked in an Injection Context. In order to invoke injectBeforeRender outside of an Injection Context, you can provide an Injector to the injector property of the 2nd argument to injectBeforeRender

export class MyCmp {
constructor() {
const injector = inject(Injector);
afterNextRender(() => {
// outside of Injection Context, provide Injector ✅
injectBeforeRender(() => {}, { injector })
})
}
}

Optional priority

The priority parameter determines the order of execution when multiple before render callbacks are registered:

// executes first
injectBeforeRender(cb1, { priority: 1 });
// executes second
injectBeforeRender(cb2, { priority: 2 });

priority can also be dynamic using a Signal<number>

export class MyCmp {
priority = input(0);
constructor() {
injectBeforeRender(
({ camera, delta }) => {
camera.position.x = Math.sin(Date.now() / 1000) * delta;
},
{
priority: this.priority
}
);
}
}

How it works

injectBeforeRender 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.