Skip to main content

Compound Component

Compound Component is a component that wraps at least one THREE.js entity in its template and all Inputs will be forwarded to that THREE.js entity.

There are two steps to create a Compound component

  • Ensure that NGT Custom Renderer recognizes the Compound Component's selector as a compound. We can use [compoundPrefixes] Input on <ngt-canvas> to configure this
  • Add ngtCompound attribute on the THREE.js entity that we want our Compound Component to wrap

Suppose we have the following template

<ngt-mesh>
<ngt-box-geometry *args="args" />
<ngt-mesh-basic-material />
</ngt-mesh>

<ngt-mesh>
<ngt-box-geometry *args="argsTwo" />
<ngt-mesh-standard-material />
</ngt-mesh>

We notice that we keep using <ngt-mesh> and <ngt-box-geometry>. This is a good candidate to make into a Compound Component. In this case, we'll make a Box component.

extend({ Mesh, BoxGeometry });

@Component({
selector: 'tutorial-box',
standalone: true,
template: `
<ngt-mesh ngtCompound [ref]="boxRef">
<ngt-box-geometry *args="boxArgs" />
<ng-content />
</ngt-mesh>
`,
imports: [NgtArgs],
})
export class Box {
@Input() boxRef = injectNgtRef<Mesh>();
@Input() boxArgs: ConstructorParameters<typeof BoxGeometry> = [1, 1, 1];
}

@Component({
template: `<ngt-canvas [compoundPrefixes]="['tutorial']" />`,
})
export class SomeFeature {}
  • We use <ngt-mesh> and <ngt-box-geometry> with <ng-content>. This allows the consumers to pass in any Material, or other objects as children to our <ngt-mesh>

    • We use ngtCompound on the <ngt-mesh>. This lets NGT Custom Renderer knows that Box component will forward its Inputs to <ngt-mesh>

      note

      Inputs that are defined like boxRef and boxArgs will not get forwarded.

  • We extend({Mesh, BoxGeometry}) to ensure that NGT Custom Renderer knows about Mesh and BoxGeometry if they consume Box component

  • We let the NGT Custom Renderer knows that our Box component is a Compound Component by providing ['tutorial'] to compoundPrefixes

Now that we have Box, we can consume it like following

<tutorial-box>
<ngt-mesh-basic-material />
</tutorial-box>

<tutorial-box [position]="[2, 2, 2]">
<ngt-mesh-standard-material />
</tutorial-box>

<tutorial-box [position]="[-2, -2, -2]">
<ngt-mesh-standard-material />
<ngt-mesh>
<ngt-plane-geometry />
</ngt-mesh>
</tutorial-box>

Check out angular-three-soba for more examples on Compound Components.