Understanding the Scene
Learn how to access and traverse the Lottie Creator scene.
Lottie Creator organizes animation content in a hierarchy:
Every Lottie Creator file can have one or more scene
Scenes and elements in a scene are referred to as nodes
Okay, that's probably confusing at first glance, so let's go through this step-by-step:
Node types
Scenes
Every Lottie Creator file can have one or more scene
A scene defines the content of an animation. It has its own canvas, canvas size, framerate, duration, layers, etc.
Nested scenes and scene layers
Nested scene
A scene can be nestable (can be a child of another scene via a scene layer) or non-nestable
Scene layer
A layer that points to a nestable scene. It behaves like a regular layer (you can position, scale, and animate it), but its content comes from the referenced scene.
Changes to the source scene automatically reflect in all instances
Use
sceneLayer.sceneto access the referenced sceneUse
sceneLayer.break()to convert it to a regular layer, breaking the link
Layers
Layers are top-level elements of a scene:
| Type | Description |
Shape layer | A layer containing shapes |
Image layer | A layer containing an image |
Text layer | A layer containing text |
Scene layer | A layer that references another scene |
Null layer | A transform parent for other layers |
Audio layer | A layer that plays an audio asset |
Shapes
Shapes are nodes that represent, well, shapes. They can be children of containers or groups:
| Type | Description |
Group | Contains other shapes or groups |
Rectangle | Rectangle shape |
Ellipse | Ellipse shape |
Polygon | Polygon shape |
Star | Star shape |
Path | Any shape with custom vector data |
Accessing scene content through scene
To access scene content, you can use:
| Entry Point | Description | API |
| Active scene | Access the current active scene | creator.activeScene |
| All scenes | Access all scenes in the current file | creator.scenes |
From there, you can access the contents of a scene by traversing its layers:
const scene = creator.activeScene;
const layers = scene.layers;
for (const layer of layers) {
// do something with the active scene's layers
console.log(layer.name, layer.type);
}Accessing scene content through selection
Instead of accessing scene content through the scene object, you might want to access it through the current selection:
| Entry Point | API |
| Selected nodes | creator.selection.nodes |
| Selected keyframes | creator.selection.keyframes |
Common patterns
When navigating the scene hierarchy, here are patterns you might find helpful:
1. Node filtering
Filter nodes by type to work only with specific node types.
Useful for: working with selections or nodes that may contain a mix of different node types.
// Get only image layers from selection
const imageLayers = creator.selection.nodes.filter((node): node is ImageLayer => node.type === 'IMAGE_LAYER');2. Traverse down
Walk down the node tree to process all children.
Useful for: finding all shapes within a layer or applying changes recursively.
// Recursively visit all shapes in a layer
function visitShapes(parent: ShapeLayer | Group, callback: (shape: Shape) => void) {
const shapes = parent.shapes;
for (const shape of shapes) {
callback(shape);
// Groups can contain shapes, so recurse into them
if (shape.type === 'GROUP') {
visitShapes(shape, callback);
}
}
}
// Example: Find all shapes of the selected layer(s)
const selection = creator.selection.nodes;
const shapes: Shape[] = [];
selection.forEach((node) => {
if (node.type === 'SHAPE_LAYER') {
visitShapes(node, (shape) => {
shapes.push(shape);
});
}
});Handling unknown node types
Some APIs, such as creator.selection.nodes, can return types your plugin does not support.
To avoid errors and crashes in your plugin, check type before reading type-specific members, and provide fallback handling for unknown types.
Checking a node's type
Every layer, shape and asset has a type string, such as "SHAPE_LAYER", "RECTANGLE" or "AUDIO". Compare it with if or switch. In TypeScript, this also narrows the node, so the members of that type become available:
for (const node of creator.selection.nodes) {
switch (node.type) {
case 'SHAPE_LAYER':
node.fills; // ShapeLayer members
break;
case 'TEXT_LAYER':
node.text; // TextLayer members
break;
case 'RECTANGLE':
node.size; // Rectangle members
break;
default:
// Unsupported or unknown type: provide fallback handling
break;
}
}creator.utils has type guards for broader groups:
| Guard | Returns true for |
creator.utils.isLayer(node) | Any layer |
creator.utils.isShape(node) | Any shape |
creator.utils.isTransformableLayer(node) | Layers with a transform (every layer except audio) |
Assets work the same way: check asset.type ("SCENE", "IMAGE", "FONT", "AUDIO") before reading asset-specific members.
Falling back on unsupported types
Keep a list of the types your plugin supports and skip the rest:
const SUPPORTED_TYPES: ReadonlySet<string> = new Set(['SHAPE_LAYER', 'TEXT_LAYER', 'RECTANGLE', 'ELLIPSE']);
const supported = creator.selection.nodes.filter((node) => SUPPORTED_TYPES.has(node.type));Decide what your plugin does with the nodes it skips:
Skip them and notify the user when the plugin works on many nodes at once, such as batch-renaming. Tell the user that some layers could not be updated.
Notify the user upfront when they selected only unsupported nodes. Show a message in your plugin UI, such as "Select a shape or text layer".
if (supported.length === 0) {
creator.ui.postMessage({ type: 'unsupported-selection' });
return;
}creator.utils.isTransformableLayer only exists in Creator builds that support audio layers. A plugin that must also run on older builds should use its own type list instead.