# Helpers

Transform

{schema_string:helpers/transform/description} {schema_object:helpers/transform} To make the anchor point properly line up with the center of location, `p` and `a` should have the same value. This example allows you to tweak transform attributes and see how the shape changes. {: .print-site-plugin-ignore } The anchor point is highlighted with an orange dot. {: .print-site-plugin-ignore }
lottie.layers[1].ks
Transforms the parent's coordinate system. When calculating the final transform, properties MUST be applied as follows: 1. Translate by $-a$ 1. Scale by $\frac{s}{100}$ 1. If $sk \neq 0$: 1. Rotate by $-sa$ 1. Skew x by $\tan(-sk)$ 1. Rotate by $sa$ 1. Rotate by $-r$ 1. Translate by $p$ Steps that have no effect MAY be skipped. Assuming a transform matrix with the following layout, with the labels equivalent to the [CSS matrix transform](https://drafts.csswg.org/css-transforms/#MatrixDefined): $$ \begin{pmatrix} a & b & 0 \\ c & d & 0 \\ e & f & 1 \end{pmatrix} $$ The final transform is given by chaining transform matrices for each transform step: $$ \begin{split} & \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ -a.x & -a.y & 1 \end{pmatrix} \times \begin{pmatrix} \frac{s.x}{100} & 0 & 0 \\ 0 & \frac{s.y}{100} & 0 \\ 0 & 0 & 1 \end{pmatrix} \times \\ \times & \begin{pmatrix} \cos(-sa) & \sin(-sa) & 0 \\ -\sin(-sa) & \cos(-sa)& 0 \\ 0 & 0 & 1 \end{pmatrix} \times \begin{pmatrix} 1 & \tan(-sk) & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} \times \begin{pmatrix} \cos(sa) & \sin(sa) & 0 \\ -\sin(sa) & \cos(sa) & 0 \\ 0 & 0 & 1 \end{pmatrix} \times \\ \times & \begin{pmatrix} \cos(-r) & \sin(-r) & 0 \\ -\sin(-r) & \cos(-r) & 0 \\ 0 & 0 & 1 \end{pmatrix} \times \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ p.x & p.y & 1 \end{pmatrix} \end{split} $$ Note that if the transform matrix is transposed compared to the above: $$ \begin{pmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{pmatrix} $$ The operations need to be chained using right multiplication instead of left multiplication.

Visual Object

{schema_string:helpers/visual-object/description} {schema_object:helpers/visual-object}

Marker

{schema_string:helpers/marker/description} {schema_object:helpers/marker}

Slots

Slots are a way to define a property value once and use the value in multiple properties. Slot definitions are in a dictionary, the slot definition key is the key that is used to match all properties with a `sid` field to the same key for replacement.

Slot

{schema_string:helpers/slot/description} {schema_object:helpers/slot}

Slottable Object

{schema_string:helpers/slottable-object/description} {schema_object:helpers/slottable-object}

Slottable Property

{schema_string:helpers/slottable-property/description} {schema_object:helpers/slottable-property}

Slot Validation Rules

**Type Consistency Rule:** - The type of a Slot's `p` property MUST match the type of the property that references it via `sid` - Vector-type slots MAY target Position properties if the number of dimensions match, as implementations perform simple value substitution **Duplicate Slot ID Rule:** - Multiple properties MAY reference the same `sid` value - All properties referencing the same `sid` MUST have compatible types - If multiple `sid` values with identical names but incompatible types exist, implementations SHOULD treat this as an error **Missing Reference Handling:** - If a property's `sid` references a slot that does not exist in the `slots` dictionary, implementations MUST use the property's own `a` and `k` values as fallback - If a property has only `sid` (no `a`/`k` fallback) and the referenced slot is missing, implementations SHOULD ignore the property or use a type-appropriate default value - Slots defined in the `slots` dictionary that are not referenced by any property MAY be ignored **Type Determination:** - The expected type of a slot is determined by its `p` value - When parsing, implementations SHOULD check that properties referencing a slot via `sid` are type-compatible with the slot's `p` value - If a type mismatch is detected, implementations SHOULD treat this as an error Valid example — scalar slot referenced by a scalar property: ```json { "slots": { "my_rotation": { "p": { "a": 0, "k": 45 } } } } ``` ```json { "a": 0, "k": 0, "sid": "my_rotation" } ``` Valid example — vector slot referenced by a position property (dimensions match): ```json { "slots": { "my_position": { "p": { "a": 0, "k": [100, 200] } } } } ``` ```json { "a": 0, "k": [0, 0], "sid": "my_position" } ``` Valid example — bezier slot referenced by a bezier property: ```json { "slots": { "my_path": { "p": { "a": 0, "k": { "c": true, "v": [[0, 0], [100, 0], [100, 100]], "i": [[0, 0], [0, 0], [0, 0]], "o": [[0, 0], [0, 0], [0, 0]] } } } } } ``` ```json { "a": 0, "k": { "c": true, "v": [[0, 0]], "i": [[0, 0]], "o": [[0, 0]] }, "sid": "my_path" } ``` Invalid example — scalar slot referenced by a vector property (type mismatch): ```json { "slots": { "my_scale": { "p": { "a": 0, "k": 50 } } } } ``` ```json { "a": 0, "k": [100, 100], "sid": "my_scale" } ```
lottie.slots

Metadata

{schema_string:helpers/metadata/description} {schema_object:helpers/metadata} Authors can use `custom` to attach tool-specific or workflow-specific data without conflicting with the standard metadata fields above. Implementations SHOULD preserve the `custom` object when reading and writing animations so that data added by other tools is not lost. Because `custom` has no defined schema, implementations MUST NOT require specific keys to be present, assume any particular structure, or fail when encountering unknown content.

Mask

{schema_string:helpers/mask/description} {schema_object:helpers/mask} Masks provide single-channel coverage information (alpha channel) that modulates the layer's content. When multiple masks are specified, they are combined (blended) into a single coverage buffer, in order, based on the [`mode`](constants.md#mask-mode) operator. Masks are specified in terms of a `Path` plus additional properties. For a given mask path, the coverage $C_{path}$ is $1$ inside the path, $0$ outside the path, and possibly in the $[0..1]$ range along the path edges (anti-aliasing). The coverage for a given `Mask` is $$C = \begin{cases}{lr} C_{path} \cdot opacity, & \text{when } inv = false \\ C_{path}^{-1} \cdot opacity, & \text{when } inv = true \\ \end{cases}$$ and the cumulative coverage for all masks is $$C_{cumulative} = \prod_{k=1}^{n} C_k$$ where the product operator is determined by [`mode`](constants.md#mask-mode). Then the final layer coverage (alpha channel) is $$C_{layer}\prime = C_{layer} \cdot C_{cumulative}$$ Example
lottie.layers[1].masksProperties[0]