Skip to content
🎉 Angular Three v4 is here! Read the announcement

Sheet Object

Sheet objects are containers for animatable properties within a Theatre.js sheet.

The sheetObject directive creates a Theatre.js sheet object. Must be applied to an ng-template element.

<ng-template sheetObject="cube" [sheetObjectProps]="{ opacity: 1, scale: 1 }" let-values="values">
<ngt-mesh [scale]="values().scale">
<ngt-box-geometry />
<ngt-mesh-standard-material [opacity]="values().opacity" transparent />
</ngt-mesh>
</ng-template>

The directive provides the following context variables:

<ng-template
sheetObject="myObject"
[sheetObjectProps]="{ opacity: 1 }"
let-values="values"
let-sheetObject="sheetObject"
let-select="select"
let-deselect="deselect"
>
<!-- values() - Signal of current animated values -->
<!-- sheetObject() - Signal of Theatre.js sheet object instance -->
<!-- select() - Select this object in Studio -->
<!-- deselect() - Deselect this object in Studio -->
</ng-template>
OptionTypeDefaultDescription
sheetObjectstringrequiredUnique key for this sheet object
sheetObjectPropsUnknownShorthandCompoundProps{}Initial animatable properties
sheetObjectDetachbooleanfalseRemove object when directive is destroyed
sheetObjectSelectedbooleanfalseTwo-way bindable selection state
MethodDescription
select()Select this object in Theatre.js Studio
deselect()Deselect this object from Studio
addProps(props)Add new properties to the sheet object
removeProps(props)Remove properties from the sheet object
update()Reconfigure the sheet object with current props

The sync directive synchronizes Three.js object properties with Theatre.js animations.

<ng-template sheetObject="myMaterial">
<ngt-mesh-standard-material [sync]="material" [syncProps]="['opacity', 'roughness', 'metalness']" #material />
</ng-template>
<ng-template sheetObject="myLight">
<ngt-point-light
[sync]="light"
[syncProps]="[
['intensity', { label: 'Light Intensity', key: 'lightIntensity' }],
['color', 'lightColor'],
'distance'
]"
#light
/>
</ng-template>
OptionTypeDefaultDescription
syncTObject | ElementRef<TObject> | SignalrequiredThree.js object to sync
syncPropsArray<string | [string, string | PropOptions]>[]Properties to synchronize
PropertyTypeDescription
labelstringDisplay label in Theatre.js Studio
keystringUnique key for the property
transformerTheatreTransformerCustom value transformer
MethodDescription
capture()Capture current values and commit to Theatre.js

You can sync nested properties using dot notation:

<ngt-mesh [sync]="mesh" [syncProps]="['position.x', 'position.y', 'rotation.z']" #mesh />

The theatre-transform component provides transform controls for position, rotation, and scale animation.

<ng-template sheetObject="myCube">
<theatre-transform>
<ngt-mesh>
<ngt-box-geometry />
<ngt-mesh-standard-material />
</ngt-mesh>
</theatre-transform>
</ng-template>
<ng-template sheetObject="scene">
<theatre-transform key="cubeTransform" label="Cube">
<ngt-mesh />
</theatre-transform>
<theatre-transform key="sphereTransform" label="Sphere">
<ngt-mesh />
</theatre-transform>
</ng-template>

When selected in Theatre.js Studio, transform gizmos appear for direct manipulation.

OptionTypeDefaultDescription
labelstringundefinedDisplay label in Studio
keystringundefinedGroup key for transform properties
optionsTransformOptions{}Transform controls configuration
PropertyTypeDescription
mode'translate' | 'rotate' | 'scale'Active transform mode
translationSnapnumberSnap increment for translation
rotationSnapnumberSnap increment for rotation
scaleSnapnumberSnap increment for scale
space'world' | 'local'Coordinate space

Theatre.js uses transformers to convert between Three.js and Theatre.js values:

TransformerDescription
colorRGBA color picker
degreesRadian to degrees conversion
eulerEuler rotation controls
normalized0-1 range slider
sideMaterial side property
genericFallback for common types
import { createTransformer } from 'angular-three-theatre';
import { types } from '@theatre/core';
export const percentage = createTransformer({
transform: (value) => types.number(value * 100, { range: [0, 100] }),
apply: (target, property, value) => {
target[property] = value / 100;
},
});

Use it with sync:

<ngt-mesh-standard-material [sync]="material" [syncProps]="[['opacity', { transformer: percentage }]]" #material />
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { TheatreProject, TheatreSheet, TheatreSheetObject, TheatreStudio } from 'angular-three-theatre';
import { environment } from '../environments/environment';
@Component({
template: `
<theatre-project name="Demo" [studio]="!environment.production">
<ng-container sheet="Scene" [sequence]="{ autoplay: true }">
<!-- Custom properties -->
<ng-template
sheetObject="settings"
[sheetObjectProps]="{ intensity: 1, ambient: 0.5 }"
let-values="values"
>
<ngt-ambient-light [intensity]="values().ambient" />
<ngt-directional-light [intensity]="values().intensity" />
</ng-template>
<!-- Transform animation -->
<ng-template sheetObject="cube">
<theatre-transform label="Animated Cube">
<ngt-mesh>
<ngt-box-geometry />
<ngt-mesh-standard-material
[sync]="material"
[syncProps]="['color', 'roughness', 'metalness']"
#material
/>
</ngt-mesh>
</theatre-transform>
</ng-template>
</ng-container>
</theatre-project>
`,
imports: [TheatreProject, TheatreSheet, TheatreSheetObject, TheatreStudio],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AnimatedScene {
environment = environment;
}