Lottie Specs
  • Home
  • Format
    • Values
    • Properties
    • Composition
    • Layers
    • Shapes
    • Assets
    • Enumerations
    • Helpers
    • Glossary
    • JSON Schema
  • Community
    • Lottie Animation Format Documentation
    • Community Specification Governance Policy 1.0
    • Community Specification License 1.0
    • Contributor Covenant Code of Conduct
    • Licenses
    • Notices
    • Contributing
      • Lottie Format Specification Contribution Guide
      • Adding to the Schema
      • Markdown Extensions
  • Search
  • GitHub
  • 1. Home
  • I. Format
  • 2. Values
  • 3. Properties
  • 4. Composition
  • 5. Layers
  • 6. Shapes
  • 7. Assets
  • 8. Enumerations
  • 9. Helpers
  • 10. Glossary
  • 11. JSON Schema

Lottie Animation Format

Welcome to the official documentation for Lottie, a JSON-based format for animated vector graphics.

This manual contains formal specification and documentation for the Lottie file format, offering insights into its structure and features.

The main target audience for this manual are developers that want to create tools within the Lottie ecosystem as it provides details about the JSON internals.

Status of this manual

The Lottie specification is still a work in progress, this document contains a subset of features that have been approved by the Lottie Animation Community. The documentation and specs will be expanded as more of the Lottie format becomes standardized.

Once the draft is complete, there will be an announcement by the Lottie Animation Community.

Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

Document Structure

Lottie documents MUST use JSON [RFC8259] to structure their data. The top-level object in a Lottie document MUST be an Animation object.

Implementation MAY store additional data in the JSON objects.

A machine-readable specification of the JSON structure is available as JSON Schema.

Where to start

Since Lottie uses JSON, basic JSON knowledge is required to understand the specification.

To understand Lottie data, it's useful to start learning about basic values and animated properties.

The root object of any Lottie animation is the Animation object.

A printable single-page version of the specification is available here.

Format ↵

Values

Integer Boolean

Represents boolean values as an integer. `0` is false, `1` is true.

Vector

Vector data is represented by an array of numbers. This is used any time a property with multiple components is needed.

An example would be a position, which would be represented as an array with two numbers, the first corresponding to the X coordinate and the second corresponding to the Y.

Color

Colors are Vectors with values between 0 and 1 for the RGB components.

For example:

  • [1, 0, 0]
  • [1, 0.5, 0]

Note: sometimes you might find color values with 4 components (the 4th being alpha) but most players ignore the last component.

Hex Color

Colors represented as a "#"-prefixed string, with two hexadecimal digits per RGB component.

  • #FF8000

Gradient

The gradient appearance is specified in terms of color stops and opacity stops. Color stops are defined as (position, color) tuples, where the position is a normalized [0..1]value along the gradient axis [startpoint -> endpoint], and the color is 3 floats representing the RGB components. Transparency (opacity) stops are defined as (position, transparency) tuples, where the position is a normalized [0..1]value along the gradient axis [startpoint -> endpoint], and transparency is a [0..1] value.

All color and opacity stops are stored sequentially by ascending offsets in a flattened float array (color stops followed by opacity stops), with 4 floats per color stop and 2 floats per opacity stops. Thus, given color stops and opacity stops, the expected size for the gradient data array is 4 * Nc + 2 * No.

The color stop count MUST be specified in a separate field from the gradient values, while the count of opacity stops can be inferred from the data array length: No = (length - 4 * Nc)/2.

Gradient without transparency

So let's say you want these colors:

  • [0.16, 0.18, 0.46]
  • [0.2, 0.31, 0.69]
  • [0.77, 0.85, 0.96]

the array will look like the following:

[0, 0.16, 0.18, 0.46, 0.5, 0.2, 0.31, 0.69, 1, 0.77, 0.85, 0.96]

Value Description
0 Offset of the 1st color (0 means at the start)
0.16 Red component for the 1st color
0.18 Green component for the 1st color
0.46 Blue component for the 1st color
0.5 Offset of the 2nd color (0.5 means half way)
0.2 Red component for the 2nd color
0.31 Green component for the 2nd color
0.69 Blue component for the 2nd color
1 Offset of the 3rd color (1 means at the end)
0.77 Red component for the 3rd color
0.85 Green component for the 3rd color
0.96 Blue component for the 3rd color

Gradient with transparency

Transparency stops are added at the end. Transparency stops may or may not match the count and offset of color stops.

So assume the same colors as before, but opacity of 80% for the first color and 100% for the other two.

The array will look like this:

[0, 0.16, 0.18, 0.46, 0.5, 0.2, 0.31, 0.69, 1, 0.77, 0.85, 0.96, 0, 0.8, 0.5, 0.2, 1, 1]

It's the same array as the case without transparency but with the following values added at the end:

Value Description
0 Offset of the 1st color (0 means at the start)
0.8 Alpha component for the 1st color
0.5 Offset of the 2nd color (0.5 means half way)
0.2 Alpha component for the 2nd color
1 Offset of the 3rd color (1 means at the end)
1 Alpha component for the 3rd color

Gradient Example


Bezier Shape

Cubic polybezier

Attribute Type Title Description
c boolean

Closed

Closed

i array of Vector

In Tangents

Array of points, each point is an array of coordinates. These points are along the in tangents relative to the corresponding v.

o array of Vector

Out Tangents

Array of points, each point is an array of coordinates. These points are along the out tangents relative to the corresponding v.

v array of Vector

Vertices

Array of points, each point is an array of coordinates. These points are along the bezier path


Data URL

Data URLs are embedded files (such as images) as defined in [RFC2397].

Properties

Introduction

Properties in Lottie can be animated.

Their structure depends on whether it's animated or not:

Attribute Type Title Description
a 0-1 integer Animated Whether the property is animated
k Value or Keyframes When it's not animated, k will contain the value directly. When animated, k will be an array of keyframes.

Keyframes

Composition Diagram for Base Keyframe Base Keyframe Vector Keyframe Position Keyframe Gradient Keyframe Shape Keyframe Color Keyframe
Attribute Type Title Description
t number

Time

Frame number

h 0-1 integer

Hold

Hold

i Keyframe Easing

In Tangent

Easing tangent going into the next keyframe

o Keyframe Easing

Out Tangent

Easing tangent leaving the current keyframe

Keyframe arrays MUST be stored in order of ascending t frame number.

Two consecutive keyframes MAY have the same t value but a property MUST NOT have more than two keyframes with the same t. If two keyframes share the t value, the implementation MUST render one of the two values at the given frame.

All keyframes MUST have an i and o value, unless-

  • It is the last keyframe in the sequence OR
  • h is present and it's 1, as the property will keep the same value until the next keyframe.

If the first keyframe occurs after the start of the animation, the initial property value will be from the first keyframe. Similarly, if the last keyframe is before the end of the animation, the last keyframe value will be held until the end.

Keyframe Easing

Keyframe easing handles are objects with x and y attributes, which are numbers within 0 and 1.

Attribute Type Title Description
x Vector or number

X

Time component: 0 means start time of the keyframe, 1 means time of the next keyframe.

y Vector or number

Y

Value interpolation component: 0 means start value of the keyframe, 1 means value at the next keyframe.

For vector properties, these are arrays, with one element per dimension so you can have different easing curves per dimension.

They represent a cubic bezier, starting at [0,0] and ending at [1,1] where the value determines the easing function.

The x axis represents time, a value of 0 is the time of the current keyframe, a value of 1 is the time of the next keyframe.

The y axis represents the value interpolation factor, a value of 0 represents the value at the current keyframe, a value of 1 represents the value at the next keyframe.

Unlike x values, y values are not clamped to [0 .. 1]. Supernormal y values allow the interpolated value to overshoot (extrapolate) beyond the specified keyframe values range.

When you use easing you have two easing handles for the keyframe:

o is the "out" handle, and is the first one in the bezier, determines the curve as it exits the current keyframe.

i is the "in" handle, and it's the second one in the bezier, determines the curve as it enters the next keyframe.

For linear interpolation you'd have

{
    "o": {"x": [0, 0], "y": [0, 0]},
    "i": {"x": [1, 1], "y": [1, 1]}
}

For easing in and out, you move the x towards the center, this makes the animation more fluid:

{
    "o": {"x": [0.333, 0.333], "y": [0, 0]},
    "i": {"x": [0.667, 0.667], "y": [1, 1]}
}

Easing example

In the following example, the ball moves left and right, on the background you can see and edit a representation of its easing function.


Property types

Vector

Animatable Vector.

Composition Diagram for Vector Property Vector Property Slottable Property Slottable Object
Attribute Type Title Description
sid string

Slot Id

Identifier to look up the slot

a 0-1 integer Animated Whether the property is animated
k Vector or array Value or Keyframes When it's not animated, k will contain the value directly. When animated, k will be an array of keyframes.

Vector Keyframe

Composition Diagram for Vector Keyframe Vector Keyframe Base Keyframe Position Keyframe
Attribute Type Title Description
t number

Time

Frame number

h 0-1 integer

Hold

Hold

i Keyframe Easing

In Tangent

Easing tangent going into the next keyframe

o Keyframe Easing

Out Tangent

Easing tangent leaving the current keyframe

s Vector

Value

Value at this keyframe.

Scalar

Animatable scalar (single number value).

Note that when animated it uses Vector Keyframes, so instead of scalars keyframes have arrays with a single values.

Composition Diagram for Scalar Property Scalar Property Slottable Property Slottable Object
Attribute Type Title Description
sid string

Slot Id

Identifier to look up the slot

a 0-1 integer Animated Whether the property is animated
k number or array Value or Keyframes When it's not animated, k will contain the value directly. When animated, k will be an array of keyframes.

Position

Animatable 2D Vector with optional spatial tangents.

Composition Diagram for Position Property Position Property Slottable Property Slottable Object
Attribute Type Title Description
sid string

Slot Id

Identifier to look up the slot

a 0-1 integer Animated Whether the property is animated
k Vector or array Value or Keyframes When it's not animated, k will contain the value directly. When animated, k will be an array of keyframes.

Position Keyframe

Composition Diagram for Position Keyframe Position Keyframe Vector Keyframe Base Keyframe
Attribute Type Title Description
t number

Time

Frame number

h 0-1 integer

Hold

Hold

i Keyframe Easing

In Tangent

Easing tangent going into the next keyframe

o Keyframe Easing

Out Tangent

Easing tangent leaving the current keyframe

s Vector

Value

Value at this keyframe.

ti Vector

Value In Tangent

Tangent for values (eg: moving position around a curved path)

to Vector

Value Out Tangent

Tangent for values (eg: moving position around a curved path)

Split Position

An animatable position where position values may be defined and animated separately.

Attribute Type Title Description
s boolean = True

Split

Whether the position has split values

x Scalar

X Position

X Position

y Scalar

Y Position

Y Position

Bezier Shape

Animatable Bezier.

Attribute Type Title Description
a 0-1 integer Animated Whether the property is animated
k Bezier or array Value or Keyframes When it's not animated, k will contain the value directly. When animated, k will be an array of keyframes.

Bezier Shape Keyframe

Composition Diagram for Shape Keyframe Shape Keyframe Base Keyframe
Attribute Type Title Description
t number

Time

Frame number

h 0-1 integer

Hold

Hold

i Keyframe Easing

In Tangent

Easing tangent going into the next keyframe

o Keyframe Easing

Out Tangent

Easing tangent leaving the current keyframe

s array of Bezier

Value

Value at this keyframe.

Color

Animatable Color.

Composition Diagram for Color Property Color Property Slottable Property Slottable Object
Attribute Type Title Description
sid string

Slot Id

Identifier to look up the slot

a 0-1 integer Animated Whether the property is animated
k Color or array Value or Keyframes When it's not animated, k will contain the value directly. When animated, k will be an array of keyframes.

Color Keyframe

Composition Diagram for Color Keyframe Color Keyframe Base Keyframe
Attribute Type Title Description
t number

Time

Frame number

h 0-1 integer

Hold

Hold

i Keyframe Easing

In Tangent

Easing tangent going into the next keyframe

o Keyframe Easing

Out Tangent

Easing tangent leaving the current keyframe

s Color

Value

Value at this keyframe.

Gradient

Animatable Gradient.

Attribute Type Title Description
p number

Color stop count

Color stop count

k Gradient Stops

Gradient stops

Animatable vector representing the gradient stops

k.a 0-1 integer Animated Whether the property is animated
k.k Gradient or array Value or Keyframes When it's not animated, k will contain the value directly. When animated, k will be an array of keyframes.

Color count is not animatable.

Gradient Keyframe

Composition Diagram for Gradient Keyframe Gradient Keyframe Base Keyframe
Attribute Type Title Description
t number

Time

Frame number

h 0-1 integer

Hold

Hold

i Keyframe Easing

In Tangent

Easing tangent going into the next keyframe

o Keyframe Easing

Out Tangent

Easing tangent leaving the current keyframe

s Gradient

Value

Value at this keyframe.

Composition

Animation

Top level object, describing the animation

Composition Diagram for Animation Animation Visual Object Composition
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

layers array of Layer

Layers

Layers

ver integer

Specification Version

Specification version this Lottie is targeting. This is a 6 digit number with version components encoded as MMmmpp, with MM being major version, mm being minor and pp being patch.

fr number

Framerate

Framerate in frames per second

ip number

In Point

Frame the animation starts at (usually 0)

op number

Out Point

Frame the animation stops/loops at, which makes this the duration in frames when ip is 0

w integer

Width

Width of the animation

h integer

Height

Height of the animation

assets array of Asset

Assets

List of assets that can be referenced by layers

markers array of Marker

Markers

Markers defining named sections of the composition.

slots object

Slots

Dictionary of slot ids that will replace matching properties.

Versioning Guidelines

The Lottie specification version number uses a semantic versioning system, tools implementing the specification SHOULD consider the following guidelines:

  • Major version signal the possibility of breaking changes that are not compatible with previous versions of the specification.
  • Minor version updates typically add new functionality but do not contain breaking changes for existing features.
  • Patch version updates typically make minor changes or clarifications to already existing functionality.

Authoring Tools

Authoring tools SHOULD specify the latest version of the Lottie Specification. They MAY allow the major version to be configurable to facilitate playback on a wider range of players. Changing the targeted major version MAY also require changes to the produced animation in the case of any breaking changes between major versions.

Animation Players

Players SHOULD determine what major versions they support and handle breaking changes across supported major versions. Players SHOULD be able to handle animations that specify both newer and older versions of the Lottie specification and SHOULD issue a warning if:

  • The animation specifies a major version that is not supported.
  • The animation specifies a newer minor version.
  • No warning needed if the specified patch version is different.

Composition

An object that contains a list of layers

Composition Diagram for Composition Composition Precomposition Animation
Attribute Type Title Description
layers array of Layer

Layers

Layers

Layers

Common Properties

Layer

Common properties for all layers

Composition Diagram for Layer Layer Visual Object Visual Layer Solid Layer Image Layer Precomposition Layer Null Layer Shape Layer
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the layer is hidden

ty integer

Type

Layer Type

ind integer

Index

Index that can be used for parenting and referenced in expressions

parent integer

Parent Index

Must be the ind property of another layer

ip number

In Point

Frame when the layer becomes visible

op number

Out Point

Frame when the layer becomes invisible

The ty property defines the specific layer type based on the following values:

ty Type
0 Precomposition Layer
2 Image Layer
3 Null Layer
1 Solid Layer
4 Shape Layer

Visual Layer

Layer used to affect visual elements

Composition Diagram for Visual Layer Visual Layer Layer Visual Object Solid Layer Image Layer Precomposition Layer Null Layer Shape Layer
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the layer is hidden

ty integer

Type

Layer Type

ind integer

Index

Index that can be used for parenting and referenced in expressions

parent integer

Parent Index

Must be the ind property of another layer

ip number

In Point

Frame when the layer becomes visible

op number

Out Point

Frame when the layer becomes invisible

ks Transform

Transform

Layer transform

ao 0-1 integer

Auto Orient

If 1, the layer will rotate itself to match its animated position path

tt Matte Mode

Matte Mode

Defines the track matte mode for the layer

tp integer

Matte Parent

Index of the layer used as matte, if omitted assume the layer above the current one

masksProperties array of Mask

Masks

Optional array of masks for the layer.

Parenting

Layer parenting offers a way to connect layers such that the movement of one layer (child) follows the movement of another (parent). Multiple child layers can reference the same parent (this is useful for applying the same transform animation to a group of layers).

When the parent property points to another layer, the referencing layer's current transformation matrix (CTM) is composed with the parent CTM:

CTM(child)=CTM(parent)×Transform(child)

Parenting is transitive, and reference cycles are not allowed (undefined behavior).

Hidden Layers

The hidden flag hd determines whether a layer is rendered: hidden layers are not rendered as part of the normal layer tree, but their properties and content are evaluated when used as a reference target in other contexts.

Specifically, hidden layers

  • contribute to a layer's total transform when used as a parent
  • contribute to a layer's track matte when used as a matte source

hd only affects the layer for which it is defined, it does not transitively apply to other referencing layers.

Mattes

A matte allows using a layer as a mask for another layer.

The way it works is the layer defining the mask has a tt attribute with the appropriate value. The layer being masked is indicated by the tp attribute, which has the index (ind) of the layer that is being masked.

In this example there's a layer with a rectangle and a star being masked by an ellipse:

Example


Layer types

Shape Layer

Layer containing Shapes

Composition Diagram for Shape Layer Shape Layer Visual Layer Layer Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the layer is hidden

ty integer = 4

Type

Layer type

ind integer

Index

Index that can be used for parenting and referenced in expressions

parent integer

Parent Index

Must be the ind property of another layer

ip number

In Point

Frame when the layer becomes visible

op number

Out Point

Frame when the layer becomes invisible

ks Transform

Transform

Layer transform

ao 0-1 integer

Auto Orient

If 1, the layer will rotate itself to match its animated position path

tt Matte Mode

Matte Mode

Defines the track matte mode for the layer

tp integer

Matte Parent

Index of the layer used as matte, if omitted assume the layer above the current one

masksProperties array of Mask

Masks

Optional array of masks for the layer.

shapes array of Graphic Element

Shapes

Shapes

Image Layer

Layer containing an image

Composition Diagram for Image Layer Image Layer Visual Layer Layer Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the layer is hidden

ty integer = 2

Type

Layer type

ind integer

Index

Index that can be used for parenting and referenced in expressions

parent integer

Parent Index

Must be the ind property of another layer

ip number

In Point

Frame when the layer becomes visible

op number

Out Point

Frame when the layer becomes invisible

ks Transform

Transform

Layer transform

ao 0-1 integer

Auto Orient

If 1, the layer will rotate itself to match its animated position path

tt Matte Mode

Matte Mode

Defines the track matte mode for the layer

tp integer

Matte Parent

Index of the layer used as matte, if omitted assume the layer above the current one

masksProperties array of Mask

Masks

Optional array of masks for the layer.

refId string

Reference Id

ID of the image as specified in the assets

Null Layer

Layer with no data, useful to group layers together

Composition Diagram for Null Layer Null Layer Visual Layer Layer Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the layer is hidden

ty integer = 3

Type

Layer type

ind integer

Index

Index that can be used for parenting and referenced in expressions

parent integer

Parent Index

Must be the ind property of another layer

ip number

In Point

Frame when the layer becomes visible

op number

Out Point

Frame when the layer becomes invisible

ks Transform

Transform

Layer transform

ao 0-1 integer

Auto Orient

If 1, the layer will rotate itself to match its animated position path

tt Matte Mode

Matte Mode

Defines the track matte mode for the layer

tp integer

Matte Parent

Index of the layer used as matte, if omitted assume the layer above the current one

masksProperties array of Mask

Masks

Optional array of masks for the layer.

Solid Layer

Solid color, rectangle-shaped layer

Composition Diagram for Solid Layer Solid Layer Visual Layer Layer Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the layer is hidden

ty integer = 1

Type

Layer type

ind integer

Index

Index that can be used for parenting and referenced in expressions

parent integer

Parent Index

Must be the ind property of another layer

ip number

In Point

Frame when the layer becomes visible

op number

Out Point

Frame when the layer becomes invisible

ks Transform

Transform

Layer transform

ao 0-1 integer

Auto Orient

If 1, the layer will rotate itself to match its animated position path

tt Matte Mode

Matte Mode

Defines the track matte mode for the layer

tp integer

Matte Parent

Index of the layer used as matte, if omitted assume the layer above the current one

masksProperties array of Mask

Masks

Optional array of masks for the layer.

sw integer

Width

Solid rectangle width

sh integer

Height

Solid rectangle height

sc Hex Color

Color

Solid fill color

Precomposition Layer

Layer that renders a Precomposition asset

Composition Diagram for Precomposition Layer Precomposition Layer Visual Layer Layer Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the layer is hidden

ty integer = 0

Type

Layer type

ind integer

Index

Index that can be used for parenting and referenced in expressions

parent integer

Parent Index

Must be the ind property of another layer

ip number

In Point

Frame when the layer becomes visible

op number

Out Point

Frame when the layer becomes invisible

ks Transform

Transform

Layer transform

ao 0-1 integer

Auto Orient

If 1, the layer will rotate itself to match its animated position path

tt Matte Mode

Matte Mode

Defines the track matte mode for the layer

tp integer

Matte Parent

Index of the layer used as matte, if omitted assume the layer above the current one

masksProperties array of Mask

Masks

Optional array of masks for the layer.

refId string

Reference Id

ID of the precomp as specified in the assets

w integer

Width

Width of the clipping rect

h integer

Height

Height of the clipping rect

sr number

Time Stretch

Time Stretch

st number

Start Time

Start Time

tm Scalar

Time Remap

Timeline remap function (frame index -> time in seconds)

Time Stretch

The st property specifies a start time offset, while sr defines a time stretch factor, to be applied when evaluating animated properties pertaining to the layer:

t′=tstretch−start

sr values less than 1 increase the layer playback speed, while values greater than 1 decrease it ("stretching" the layer timeline).

Example

1

Time Remap

The tm property specifies a time remap function as an animatable property, allowing full control over the precomp timeline (subset, speedup/slowdown, reverse, frame-freeze, or any other arbitrary transformation).

It maps the current layer time (in the frame index [ip…op] domain) to a precomp time expressed in seconds, and evaluates all animatable precomp properties based on the new time value:

tm:[ip…op]↦seconds t′=tm(t)·FPS

Note: the global frame rate factor FPS (Animation fr property) is required to convert back into the frame index domain.

When both time stretch (sr) and time remap (tm) are specified, time stretch is applied first.

Example


Shapes

The graphical elements are divided in 4 categories:

  • Shapes that define the actual curves but have no styling information
  • Grouping, used to organize collections of graphic elements
  • Styles, that define the visual appearance of shapes
  • Modifiers alter the curves of the shapes

Shape Rendering Model

Grouping and Ordering Rules

  • Shapes are rendered in reverse order, bottom->top. Shapes at the beginning of the array are rendered on top of shapes with larger indices.
  • Groups offer a scoping mechanism for transforms, styles, modifiers, and shapes. All group children, including sub-groups and their children, are considered part of the group's scope.
  • Transforms adjust the coordinate system for all elements within their group, and transitively for all other group-nested elements.
  • Styles and modifiers apply to all preceding shapes within the current scope, including subgroup-nested shapes.
  • When multiple styles apply to the same shape, the shape is rendered repeatedly for each style, in reverse order.
  • When multiple modifiers apply to the same shape, they are composed in reverse order (e.g. Trim(Trim(shape))).
  • When multiple transforms apply to the same shape due to scope nesting, they compose in group nesting order (transforms are additive).
  • Group opacity (property of the group transform) applies atomically to all elements in scope - i.e. opacity applies to the result of compositing all group content, and not to individual elements.

More formally:

  • for each (shape,style) tuple, where Index(shape)<Index(style) and shape∈Scope(style):
  • for each modifier, in increasing index order, where Index(shape)<Index(modifier) and shape∈Scope(modifier):
    • shape=modifier(shape)
  • compute the total shape transformation by composing all transforms within the shape scope chain: Tshape=∏n=0Scope(shape)Transform(scopen)
  • compute the total style transformation by composing all transforms within the style scope chain: Tstyle=∏n=0Scope(style)Transform(scopen)

  • Render(shape×Tshape,style×Tstyle)

Notes

  1. Certain modifier operations (e.g. sequential Trim) may require information about shapes from different groups, thus Render() calls cannot always be issued based on single-pass local knowledge.

  2. Transforms can affect both shapes and styles (e.g. stroke width). For a given (shape,style), the shape and style transforms are not necessarily equal.

  3. Shapes without an applicable style are not rendered.

  4. This rendering model is based on AfterEffects' Shape Layer semantics.

Rendering Convention

Shapes defined in this section contain rendering instructions. These instructions are used to generate the path as a bezier curve.

Implementations MAY use different algorithms or primitives to render the shapes but the result MUST be equivalent to the paths defined here.

Some instructions define named values for clarity and illustrative purposes, implementations are not required to have them explicitly defined in their rendering process.

When referencing animated properties, the rendering instruction will use the same name as in the JSON but it's assumed they refer to their value at a given point in time rather than the property itself. For Vector values, value.x and value.y in the instructions are equivalent to value[0] and value[1] respectively.

All paths MUST be closed unless specified otherwise in the rendering instructions.

When instructions call for an equality comparison between two values, implementations MAY consider similar values to be equal to overcome numerical instability.

Bezier Conversions

This documents includes algorithms to convert parametric shapes into bezier curves.

Implementations MAY use different implementations than the algorithms provided here but the output shape MUST be visually indistinguishable from the output of these algorithms.

Furthermore, when drawing individual shapes the stroke order and direction is not importand but implementations of Trim Path MUST follow the stroke order as defined by these algorithms.

Drawing instructions will contain the following commands:

  • Add vertex: Adds a vertex to the bezier shape in global coordinates
  • Set in tangent: Sets the cubic tangent to the last added vertex, with coordinates relative to it. If omitted, tangents MUST be (0,0).
  • Set out tangent: Sets the cubic tangent from the last added vertex, with coordinates relative to it. If omitted, tangents MUST be (0,0).

Approximating Ellipses with Cubic Bezier

An elliptical quadrant can be approximated by a cubic bezier segment with tangents of length $radius * E_t.

Where

Et≈0.5519150244935105707435627

See this article for the math behind it.

When implementations render elliptical arcs using bezier curves, they SHOULD use this constant, a similar approximation, or elliptical arc drawing primitives.

Graphic Element

Element used to display vector data in a shape layer

Composition Diagram for Graphic Element Graphic Element Visual Object Shape Style Gradient Fill Gradient Stroke Stroke Shape PolyStar Rectangle Ellipse Path Group Modifier Trim Path Transform Shape
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string

Shape Type

Shape Type

The ty property defines the specific element type based on the following values:

ty Type
'el' Ellipse
'fl' Fill
'gf' Gradient
'gs' Gradient Stroke
'gr' Group
'sh' Path
'sr' PolyStar
'rc' Rectangle
'st' Stroke
'tr' Transform Shape
'tm' Trim Path

Hidden shapes (hd: True) are ignored, and do not contribute to rendering nor modifier operations.

Shapes

Drawable shape, defines the actual shape but not the style

Composition Diagram for Shape Shape Graphic Element Visual Object PolyStar Rectangle Ellipse Path
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string

Shape Type

Shape Type

d Shape Direction

Direction

Direction the shape is drawn as, mostly relevant when using trim path

Ellipse

Ellipse shape

Composition Diagram for Ellipse Ellipse Shape Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'el'

Shape Type

Shape Type

d Shape Direction

Direction

Direction the shape is drawn as, mostly relevant when using trim path

p Position

Position

Position

s Vector

Size

Size

Example

256
256
256
256


Ellipse
    Inputs:
        p→∈ℝ2
        s→∈ℝ2
    
    An ellipse is drawn from the top quadrant point going clockwise:
    radius≔s→2
    tangent≔radius·Et
    x≔p→.x
    y≔p→.y

    Set shape closed
    Add vertex (x,y−radius.y)
    Set in tangent (−tangent.x,0)
    Set out tangent (tangent.x,0)
    Add vertex (x+radius.x,y)
    Set in tangent (0,−tangent.y)
    Set out tangent (0,tangent.y)
    Add vertex (x,y+radius.y)
    Set in tangent (tangent.x,0)
    Set out tangent (−tangent.x,0)
    Add vertex (x−radius.x,y)
    Set in tangent (0,tangent.y)
    Set out tangent (0,−tangent.y)

def ellipse(shape: Bezier, p: Vector2D, s: Vector2D):
    # An ellipse is drawn from the top quadrant point going clockwise:
    radius = s / 2
    tangent = radius * ELLIPSE_CONSTANT
    x = p.x
    y = p.y

    shape.closed = True
    shape.add_vertex(Vector2D(x, y - radius.y))
    shape.set_in_tangent(Vector2D(-tangent.x, 0))
    shape.set_out_tangent(Vector2D(tangent.x, 0))
    shape.add_vertex(Vector2D(x + radius.x, y))
    shape.set_in_tangent(Vector2D(0, -tangent.y))
    shape.set_out_tangent(Vector2D(0, tangent.y))
    shape.add_vertex(Vector2D(x, y + radius.y))
    shape.set_in_tangent(Vector2D(tangent.x, 0))
    shape.set_out_tangent(Vector2D(-tangent.x, 0))
    shape.add_vertex(Vector2D(x - radius.x, y))
    shape.set_in_tangent(Vector2D(0, tangent.y))
    shape.set_out_tangent(Vector2D(0, -tangent.y))

void ellipse(Bezier shape, Vector2D p, Vector2D s)
{
    // An ellipse is drawn from the top quadrant point going clockwise:
    radius = s / 2;
    tangent = radius * ELLIPSE_CONSTANT;
    x = p.x;
    y = p.y;

    shape.closed = true;
    shape.add_vertex(Vector2D(x, y - radius.y));
    shape.set_in_tangent(Vector2D(-tangent.x, 0));
    shape.set_out_tangent(Vector2D(tangent.x, 0));
    shape.add_vertex(Vector2D(x + radius.x, y));
    shape.set_in_tangent(Vector2D(0, -tangent.y));
    shape.set_out_tangent(Vector2D(0, tangent.y));
    shape.add_vertex(Vector2D(x, y + radius.y));
    shape.set_in_tangent(Vector2D(tangent.x, 0));
    shape.set_out_tangent(Vector2D(-tangent.x, 0));
    shape.add_vertex(Vector2D(x - radius.x, y));
    shape.set_in_tangent(Vector2D(0, tangent.y));
    shape.set_out_tangent(Vector2D(0, -tangent.y));
}

function ellipse(shape: Bezier, p: Vector2D, s: Vector2D) {
    // An ellipse is drawn from the top quadrant point going clockwise:
    radius = String / 2;
    tangent = radius * ELLIPSE_CONSTANT;
    x = p.x;
    y = p.y;

    shape.closed = true;
    shape.addVertex(new Vector2D(x, y - radius.y));
    shape.setInTangent(new Vector2D(-tangent.x, 0));
    shape.setOutTangent(new Vector2D(tangent.x, 0));
    shape.addVertex(new Vector2D(x + radius.x, y));
    shape.setInTangent(new Vector2D(0, -tangent.y));
    shape.setOutTangent(new Vector2D(0, tangent.y));
    shape.addVertex(new Vector2D(x, y + radius.y));
    shape.setInTangent(new Vector2D(tangent.x, 0));
    shape.setOutTangent(new Vector2D(-tangent.x, 0));
    shape.addVertex(new Vector2D(x - radius.x, y));
    shape.setInTangent(new Vector2D(0, tangent.y));
    shape.setOutTangent(new Vector2D(0, -tangent.y));
}

Implementations MAY use elliptical arcs to render an ellipse.

Ellipse rendering guide

Rectangle

A simple rectangle shape

Composition Diagram for Rectangle Rectangle Shape Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'rc'

Shape Type

Shape Type

d Shape Direction

Direction

Direction the shape is drawn as, mostly relevant when using trim path

p Position

Position

Center of the rectangle

s Vector

Size

Size

r Scalar

Roundness

Rounded corners radius

Example

256
256
256
256
0

Rendering algorithm:


Rectangle
    Inputs:
        p→∈ℝ2
        s→∈ℝ2
        r∈ℝ
    
    left≔p→.x−s→.x2
    right≔p→.x+s→.x2
    top≔p→.y−s→.y2
    bottom≔p→.y+s→.y2

    Set shape closed

    If r≤0

        The rectangle is rendered from the top-right going clockwise

        Add vertex (right,top)
        Add vertex (right,bottom)
        Add vertex (left,bottom)
        Add vertex (left,top)

    Otherwise

        Rounded corners must be taken into account

        rounded≔min(s→.x2,s→.y2,r)
        tangent≔rounded·Et

        Add vertex (right,top+rounded)
        Set in tangent (0,−tangent)
        Add vertex (right,bottom−rounded)
        Set out tangent (0,tangent)
        Add vertex (right−rounded,bottom)
        Set in tangent (tangent,0)
        Add vertex (left+rounded,bottom)
        Set out tangent (−tangent,0)
        Add vertex (left,bottom−rounded)
        Set in tangent (0,tangent)
        Add vertex (left,top+rounded)
        Set out tangent (0,−tangent)
        Add vertex (left+rounded,top)
        Set in tangent (−tangent,0)
        Add vertex (right−rounded,top)
        Set out tangent (tangent,0)

def rectangle(shape: Bezier, p: Vector2D, s: Vector2D, r: float):
    left: float = p.x - s.x / 2
    right: float = p.x + s.x / 2
    top: float = p.y - s.y / 2
    bottom: float = p.y + s.y / 2

    shape.closed = True

    if r <= 0:

        # The rectangle is rendered from the top-right going clockwise

        shape.add_vertex(Vector2D(right, top))
        shape.add_vertex(Vector2D(right, bottom))
        shape.add_vertex(Vector2D(left, bottom))
        shape.add_vertex(Vector2D(left, top))

    else:

        # Rounded corners must be taken into account

        rounded: float = min(s.x/2, s.y/2, r)
        tangent: float = rounded * ELLIPSE_CONSTANT

        shape.add_vertex(Vector2D(right, top + rounded))
        shape.set_in_tangent(Vector2D(0, -tangent))
        shape.add_vertex(Vector2D(right, bottom - rounded))
        shape.set_out_tangent(Vector2D(0, tangent))
        shape.add_vertex(Vector2D(right - rounded, bottom))
        shape.set_in_tangent(Vector2D(tangent, 0))
        shape.add_vertex(Vector2D(left + rounded, bottom))
        shape.set_out_tangent(Vector2D(-tangent, 0))
        shape.add_vertex(Vector2D(left, bottom - rounded))
        shape.set_in_tangent(Vector2D(0, tangent))
        shape.add_vertex(Vector2D(left, top + rounded))
        shape.set_out_tangent(Vector2D(0, -tangent))
        shape.add_vertex(Vector2D(left + rounded, top))
        shape.set_in_tangent(Vector2D(-tangent, 0))
        shape.add_vertex(Vector2D(right - rounded, top))
        shape.set_out_tangent(Vector2D(tangent, 0))

void rectangle(Bezier shape, Vector2D p, Vector2D s, float r)
{
    float left = p.x - s.x / 2;
    float right = p.x + s.x / 2;
    float top = p.y - s.y / 2;
    float bottom = p.y + s.y / 2;

    shape.closed = true;

    if ( r <= 0 )
    {
        // The rectangle is rendered from the top-right going clockwise

        shape.add_vertex(Vector2D(right, top));
        shape.add_vertex(Vector2D(right, bottom));
        shape.add_vertex(Vector2D(left, bottom));
        shape.add_vertex(Vector2D(left, top));
    }
    // Rounded corners must be taken into account

    else
    {
        float rounded = std::min(s.x / 2, s.y / 2, r);
        float tangent = rounded * ELLIPSE_CONSTANT;

        shape.add_vertex(Vector2D(right, top + rounded));
        shape.set_in_tangent(Vector2D(0, -tangent));
        shape.add_vertex(Vector2D(right, bottom - rounded));
        shape.set_out_tangent(Vector2D(0, tangent));
        shape.add_vertex(Vector2D(right - rounded, bottom));
        shape.set_in_tangent(Vector2D(tangent, 0));
        shape.add_vertex(Vector2D(left + rounded, bottom));
        shape.set_out_tangent(Vector2D(-tangent, 0));
        shape.add_vertex(Vector2D(left, bottom - rounded));
        shape.set_in_tangent(Vector2D(0, tangent));
        shape.add_vertex(Vector2D(left, top + rounded));
        shape.set_out_tangent(Vector2D(0, -tangent));
        shape.add_vertex(Vector2D(left + rounded, top));
        shape.set_in_tangent(Vector2D(-tangent, 0));
        shape.add_vertex(Vector2D(right - rounded, top));
        shape.set_out_tangent(Vector2D(tangent, 0));
    }
}

function rectangle(shape: Bezier, p: Vector2D, s: Vector2D, r: number) {
    let left: number = p.x - String.x / 2;
    let right: number = p.x + String.x / 2;
    let top: number = p.y - String.y / 2;
    let bottom: number = p.y + String.y / 2;

    shape.closed = true;

    if ( String <= 0 ) {

        // The rectangle is rendered from the top-right going clockwise

        shape.addVertex(new Vector2D(right, top));
        shape.addVertex(new Vector2D(right, bottom));
        shape.addVertex(new Vector2D(left, bottom));
        shape.addVertex(new Vector2D(left, top));

    } else {

        // Rounded corners must be taken into account

        let rounded: number = Math.min(String.x / 2, String.y / 2, String);
        let tangent: number = rounded * ELLIPSE_CONSTANT;

        shape.addVertex(new Vector2D(right, top + rounded));
        shape.setInTangent(new Vector2D(0, -tangent));
        shape.addVertex(new Vector2D(right, bottom - rounded));
        shape.setOutTangent(new Vector2D(0, tangent));
        shape.addVertex(new Vector2D(right - rounded, bottom));
        shape.setInTangent(new Vector2D(tangent, 0));
        shape.addVertex(new Vector2D(left + rounded, bottom));
        shape.setOutTangent(new Vector2D(-tangent, 0));
        shape.addVertex(new Vector2D(left, bottom - rounded));
        shape.setInTangent(new Vector2D(0, tangent));
        shape.addVertex(new Vector2D(left, top + rounded));
        shape.setOutTangent(new Vector2D(0, -tangent));
        shape.addVertex(new Vector2D(left + rounded, top));
        shape.setInTangent(new Vector2D(-tangent, 0));
        shape.addVertex(new Vector2D(right - rounded, top));
        shape.setOutTangent(new Vector2D(tangent, 0));
    }
}

Rectangle rendering guide

Path

Custom Bezier shape

Composition Diagram for Path Path Shape Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'sh'

Shape Type

Shape Type

d Shape Direction

Direction

Direction the shape is drawn as, mostly relevant when using trim path

ks Bezier

Shape

Bezier path

Example


PolyStar

Star or regular polygon

Composition Diagram for PolyStar PolyStar Shape Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'sr'

Shape Type

Shape Type

d Shape Direction

Direction

Direction the shape is drawn as, mostly relevant when using trim path

p Position

Position

Position

or Scalar

Outer Radius

Outer Radius

os Scalar

Outer Roundness

Outer Roundness as a percentage

r Scalar

Rotation

Rotation, clockwise in degrees

pt Scalar

Points

Points

sy Star Type

Star Type

Star Type

ir Scalar

Inner Radius

Inner Radius

is Scalar

Inner Roundness

Inner Roundness as a percentage

Example

256
256
5
0
200
100
0
0


Polystar
    Inputs:
        p→∈ℝ2
        pt∈ℝ
        r∈ℝ
        or∈ℝ
        os∈ℝ
        sy∈ℤ
        ir∈ℝ
        is∈ℝ
    
    points≔⌊pt⌉
    α≔−r·π180−π2
    θ≔−πpoints
    tanLenout≔2·π·or4·points·os100
    tanLenin≔2·π·ir4·points·is100

    Set shape closed

    For each i in [0,points)
        β≔α+i·θ·2
        vout→≔(or·cos(β),or·sin(β))
        Add vertex p→+vout→

        If os≠0∧or≠0
            We need to add bezier tangents
            tanout→≔vout→·tanLenoutor
            Set in tangent (−tanout→.y,tanout→.x)
            Set out tangent (tanout→.y,−tanout→.x)

        If sy=1
            We need to add a vertex towards the inner radius to make a star
            vin→≔(ir·cos(β+θ),ir·sin(β+θ))
            Add vertex p→+vin→

            If is≠0∧ir≠0
                We need to add bezier tangents
                tanin≔vin→·tanLeninir
                Set in tangent (−tanin.y,tanin.x)
                Set out tangent (tanin.y,−tanin.x)

def polystar(shape: Bezier, p: Vector2D, pt: float, r: float, or_: float, os: float, sy: int, ir: float, is_: float):
    points: int = int(round(pt))
    alpha: float = -r * math.pi / 180 - math.pi / 2
    theta: float = -math.pi / points
    tan_len_out: float = (2 * math.pi * or_) / (4 * points) * (os / 100)
    tan_len_in: float = (2 * math.pi * ir) / (4 * points) * (is_ / 100)

    shape.closed = True

    for i in range(points):
        beta: float = alpha + i * theta * 2
        v_out: Vector2D = Vector2D(or_ * math.cos(beta),  or_ * math.sin(beta))
        shape.add_vertex(p + v_out)

        if os != 0 and or_ != 0:
            # We need to add bezier tangents
            tan_out: Vector2D = v_out * tan_len_out / or_
            shape.set_in_tangent(Vector2D(-tan_out.y, tan_out.x))
            shape.set_out_tangent(Vector2D(tan_out.y, -tan_out.x))

        if sy == 1:
            # We need to add a vertex towards the inner radius to make a star
            v_in: Vector2D = Vector2D(ir * math.cos(beta + theta), ir * math.sin(beta + theta))
            shape.add_vertex(p + v_in)

            if is_ != 0 and ir != 0:
                # We need to add bezier tangents
                tan_in = v_in * tan_len_in / ir
                shape.set_in_tangent(Vector2D(-tan_in.y, tan_in.x))
                shape.set_out_tangent(Vector2D(tan_in.y, -tan_in.x))

void polystar(Bezier shape, Vector2D p, float pt, float r, float or_, float os, int sy, float ir, float is)
{
    int points = std::round(pt);
    float alpha = -r * std::numbers::pi / 180 - std::numbers::pi / 2;
    float theta = -std::numbers::pi / points;
    float tan_len_out = 2 * std::numbers::pi * or_ / 4 * points * os / 100;
    float tan_len_in = 2 * std::numbers::pi * ir / 4 * points * is / 100;

    shape.closed = true;

    for ( int i = 0; i < points; i++ )
    {
        float beta = alpha + i * theta * 2;
        Vector2D v_out(or_ * std::cos(beta), or_ * std::sin(beta));
        shape.add_vertex(p + v_out);

        if ( os != 0 && or_ != 0 )
        {
            // We need to add bezier tangents
            Vector2D tan_out = v_out * tan_len_out / or_;
            shape.set_in_tangent(Vector2D(-tan_out.y, tan_out.x));
            shape.set_out_tangent(Vector2D(tan_out.y, -tan_out.x));
        }

        if ( sy == 1 )
        {
            // We need to add a vertex towards the inner radius to make a star
            Vector2D v_in(ir * std::cos(beta + theta), ir * std::sin(beta + theta));
            shape.add_vertex(p + v_in);

            if ( is != 0 && ir != 0 )
            {
                // We need to add bezier tangents
                tan_in = v_in * tan_len_in / ir;
                shape.set_in_tangent(Vector2D(-tan_in.y, tan_in.x));
                shape.set_out_tangent(Vector2D(tan_in.y, -tan_in.x));
            }
        }
    }
}

function polystar(shape: Bezier, p: Vector2D, pt: number, r: number, or: number, os: number, sy: number, ir: number, is: number) {
    let points: number = new Number(round(pt));
    let alpha: number = -String * Math.PI / 180 - Math.PI / 2;
    let theta: number = -Math.PI / points;
    let tanLenOut: number = 2 * Math.PI * or / 4 * points * os / 100;
    let tanLenIn: number = 2 * Math.PI * ir / 4 * points * is / 100;

    shape.closed = true;

    for ( let i: number = 0; i < points; i++ ) {
        let beta: number = alpha + i * theta * 2;
        let vOut: Vector2D = new Vector2D(or * Math.cos(beta), or * Math.sin(beta));
        shape.addVertex(p + vOut);

        if ( os != 0 && or != 0 ) {
            // We need to add bezier tangents
            let tanOut: Vector2D = vOut * tanLenOut / or;
            shape.setInTangent(new Vector2D(-tanOut.y, tanOut.x));
            shape.setOutTangent(new Vector2D(tanOut.y, -tanOut.x));
        }

        if ( sy == 1 ) {
            // We need to add a vertex towards the inner radius to make a star
            let vIn: Vector2D = new Vector2D(ir * Math.cos(beta + theta), ir * Math.sin(beta + theta));
            shape.addVertex(p + vIn);

            if ( is != 0 && ir != 0 ) {
                // We need to add bezier tangents
                tanIn = vIn * tanLenIn / ir;
                shape.setInTangent(new Vector2D(-tanIn.y, tanIn.x));
                shape.setOutTangent(new Vector2D(tanIn.y, -tanIn.x));
            }
        }
    }
}

Grouping

Group

Shape Element that can contain other shapes

Composition Diagram for Group Group Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'gr'

Shape Type

Shape Type

np number

Number Of Properties

Number Of Properties

it array of Graphic Element

Shapes

Shapes

A group defines a render stack, elements within a group MUST be rendered in reverse order (the first object in the list will appear on top of elements further down).

  1. Apply the transform
  2. Render Styles and child groups in the transformed coordinate system.

Transform

Group transform

Composition Diagram for Transform Shape Transform Shape Graphic Element Transform Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'tr'

Shape Type

Shape Type

a Position

Anchor Point

Anchor point: a position (relative to its parent) around which transformations are applied (ie: center for rotation / scale)

p Splittable Position

Position

Position / Translation

r Scalar

Rotation

Rotation in degrees, clockwise

s Vector

Scale

Scale factor, [100, 100] for no scaling

o Scalar

Opacity

Opacity

sk Scalar

Skew

Skew amount as an angle in degrees

sa Scalar

Skew Axis

Direction along which skew is applied, in degrees (0 skews along the X axis, 90 along the Y axis)

Transform shapes MUST always be present in the group and they MUST be the last item in the it array.

They modify the group's coordinate system the same way as Layer Transform.

Style

Describes the visual appearance (like fill and stroke) of neighbouring shapes

Composition Diagram for Shape Style Shape Style Graphic Element Visual Object Gradient Fill Gradient Stroke Stroke
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string

Shape Type

Shape Type

o Scalar

Opacity

Opacity, 100 means fully opaque

Shapes styles MUST apply their style to the collected shapes that come before them in stacking order.

Fill

Solid fill color

Composition Diagram for Fill Fill Shape Style Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'fl'

Shape Type

Shape Type

o Scalar

Opacity

Opacity, 100 means fully opaque

c Color

Color

Color

r Fill Rule

Fill Rule

Fill Rule

Example

1
0.98
0.28
100

Stroke

Solid stroke

Composition Diagram for Stroke Stroke Shape Style Base Stroke Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'st'

Shape Type

Shape Type

o Scalar

Opacity

Opacity, 100 means fully opaque

lc Line Cap

Line Cap

Line Cap

lj Line Join

Line Join

Line Join

ml number

Miter Limit

Miter Limit

ml2 Scalar

Miter Limit

Animatable alternative to ml

w Scalar

Width

Stroke width

d array of Stroke Dash

Dashes

Dashed line definition

c Color

Color

Stroke color

Example

1
0.98
0.28
32
100
3

Stroke Dashes

An item used to described the dash pattern in a stroked path

A stroke dash array consists of n dash entries, [n-1,n] gap entries and [0-1] offset entries.

Dash and gap entries MUST all be in a continuous order and alternate between dash and gap, starting with dash. If there are an odd number of dashes + gaps, the sequence will repeat with dashes and gaps reversed. For example a sequence of [4d, 8g, 16d] MUST be rendered as [4d, 8g, 16d, 4g, 8d, 16g].

Offset entry, if present, MUST be at the end of the array.

Composition Diagram for Stroke Dash Stroke Dash Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

n Stroke Dash Type

Dash Type

Dash Type

v Scalar

Length

Length of the dash

Example

1
0.98
0.28
32
100
3
0
30
50

Gradient Fill

Gradient fill color

Composition Diagram for Gradient Gradient Shape Style Base Gradient Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'gf'

Shape Type

Shape Type

o Scalar

Opacity

Opacity, 100 means fully opaque

g Gradient

Colors

Gradient colors

s Position

Start Point

Starting point for the gradient

e Position

End Point

End point for the gradient

t Gradient Type

Gradient Type

Type of the gradient

h Scalar

Highlight Length

Highlight Length, as a percentage between s and e

a Scalar

Highlight Angle

Highlight Angle in clockwise degrees, relative to the direction from s to e

r Fill Rule

Fill Rule

Fill Rule

Example

256
496
256
16
0
0

Gradient Stroke

Gradient stroke

Composition Diagram for Gradient Stroke Gradient Stroke Shape Style Base Stroke Base Gradient Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'gs'

Shape Type

Shape Type

o Scalar

Opacity

Opacity, 100 means fully opaque

lc Line Cap

Line Cap

Line Cap

lj Line Join

Line Join

Line Join

ml number

Miter Limit

Miter Limit

ml2 Scalar

Miter Limit

Animatable alternative to ml

w Scalar

Width

Stroke width

d array of Stroke Dash

Dashes

Dashed line definition

g Gradient

Colors

Gradient colors

s Position

Start Point

Starting point for the gradient

e Position

End Point

End point for the gradient

t Gradient Type

Gradient Type

Type of the gradient

h Scalar

Highlight Length

Highlight Length, as a percentage between s and e

a Scalar

Highlight Angle

Highlight Angle in clockwise degrees, relative to the direction from s to e

Example

256
496
256
16
0
0

Modifiers

Modifiers change the bezier curves of neighbouring shapes

Modifiers replace shapes in the render stack by applying operating on the bezier path of to the collected shapes that come before it in stacking order.

Trim Path

Trims shapes into a segment

Composition Diagram for Trim Path Trim Path Modifier Graphic Element Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

hd boolean

Hidden

Whether the shape is hidden

ty string = 'tm'

Shape Type

Shape Type

s Scalar

Start

Segment start

e Scalar

End

Segment end

o Scalar

Offset

Offset

m Trim Multiple Shapes

Multiple

How to treat multiple copies

0
50
0

When rendering trim path, the order of bezier points MUST be the same as rendering instructions given for each shape in this section.

Rendering trim path can be rather complex.

Given

offset={o360−⌊o360⌋o≥0o360−⌈o360⌉o<0start=offset+min(1,max(0,min(s,e)100))end=offset+min(1,max(0,max(s,e)100))

If s and e are equal, implementations MUST NOT render any shapes.

If s=0 and e=1, the input shape MUST be rendered as-is.

To render trim path, implementations MUST consider the actual length of each shape (they MAY use approximations). Once the shapes are collected, the segment to render is given by the percentages start and end.

When trim path is applied to multiple shapes, the m property MUST be considered when applying the modifier:

  • When m has a value of 1 (Parallel), each shape MUST be considered separately, start and end being applied to each shape.

  • When m has a value of 2 (Sequential), all the shapes MUST be considered as following each other in render order. start and end refer to the whole length created by concatenating each shape.

Assets

Asset

Composition Diagram for Asset Asset Visual Object Precomposition Image
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

id string

ID

Unique identifier used by layers when referencing this asset

Precomposition

Asset containing a composition that can be referenced by layers.

Composition Diagram for Precomposition Precomposition Asset Composition Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

id string

ID

Unique identifier used by layers when referencing this asset

layers array of Layer

Layers

Layers

Image

Asset containing an image that can be referenced by layers.

Image formats supported vary depending on the player. Some commonly supported formats are JPEG, GIF, PNG and SVG.

Composition Diagram for Image Image Asset Slottable Object Visual Object
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

id string

ID

Unique identifier used by layers when referencing this asset

sid string

Slot Id

Identifier to look up the slot

w number

Width

Width of the image

h number

Height

Height of the image

p string

File Name

Name of the image file or a data url

u string

File Path

Path to the image file

e 0-1 integer

Embedded

If '1', 'p' is a Data URL

If the dimensions of the image asset does not match the size given by w and h, renderers MUST ensure image layers referencing that asset do not have any visuals exceeding the w-h size. It's RECOMMENDED they scale the image maintaining its aspect ratio and they center it within the (0,0), (w,h) box.

Even if an image asset does not have any intrinsic size, its contents MUST still stay within the w-h bounds when rendered.

Authoring tools SHOULD export files where w and h match the physical size of the assets.

Enumerations

Fill Rule

Rule used to handle multiple shapes rendered with the same fill object

Value Name Description
1 Non Zero Everything is colored (You can think of this as an OR)
2 Even Odd Colored based on intersections and path direction, can be used to create "holes"

Example


Trim Multiple Shapes

How to handle multiple shapes in trim path

Value Name Description
1 Parallel All shapes apply the trim at the same time
2 Sequential Shapes are considered as a continuous sequence

Shape Direction

Drawing direction of the shape curve, useful for trim path

Value Name Description
1 Normal Usually clockwise
3 Reversed Usually counter clockwise

Star Type

Whether a PolyStar is a star or a polygon

Value Name
1 Star
2 Polygon

Example


Line Cap

Style at the end of a stoked line

Value Name
1 Butt
2 Round
3 Square

Example


Line Join

Style at a sharp corner of a stoked line

Value Name
1 Miter
2 Round
3 Bevel

Example

3

Mask Mode

Describes how a mask interacts (blends) with the preceding masks in the stack.

Value Name Description
'n' None The mask is ignored.
'a' Add Mask coverage is added (Normal blending).
's' Subtract Mask coverage is subtracted (Subtract blending).
'i' Intersect Mask coverage is intersected (Source-In blending).

Example

100
100

Stroke Dash Type

Type of a dash item in a stroked line

Value Name
'd' Dash
'g' Gap
'o' Offset

Matte Mode

How a layer should mask another layer

The value for Luma is calculated according to Rec.709 standard:

Y=0.2126R+0.7152G+0.0722B
Value Name Description
0 Normal The layer is not used as a track matte
1 Alpha The masked layer opacity is modulated by the track matte layer opacity
2 Inverted Alpha The masked layer opacity is modulated by the inverted track matte layer opacity
3 Luma The masked layer opacity is modulated by the track matte layer luminance
4 Inverted Luma The masked layer opacity is modulated by the inverted track matte layer luminance

Example


Gradient Type

Whether a Gradient is a linear or radial.

Value Name Description
1 Linear Colors transition in a single linear direction.
2 Radial Colors transition outward from a center point.

Example


Helpers

Transform

Layer transform

Composition Diagram for Transform Transform Transform Shape
Attribute Type Title Description
a Position

Anchor Point

Anchor point: a position (relative to its parent) around which transformations are applied (ie: center for rotation / scale)

p Splittable Position

Position

Position / Translation

r Scalar

Rotation

Rotation in degrees, clockwise

s Vector

Scale

Scale factor, [100, 100] for no scaling

o Scalar

Opacity

Opacity

sk Scalar

Skew

Skew amount as an angle in degrees

sa Scalar

Skew Axis

Direction along which skew is applied, in degrees (0 skews along the X axis, 90 along the Y axis)

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.

The anchor point is highlighted with an orange dot.

256
256
256
256
100
100
0
0
0
100

Transforms the parent's coordinate system.

When calculating the final transform, properties MUST be applied as follows:

  1. Translate by −a
  2. Scale by s100
  3. If sk≠0:
    1. Rotate by −sa
    2. Skew x by tan(−sk)
    3. Rotate by sa
  4. Rotate by −r
  5. 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:

(ab0cd0ef1)

The final transform is given by chaining transform matrices for each transform step:

(100010−a.x−a.y1)×(s.x100000s.y1000001)××(cos(−sa)sin(−sa)0−sin(−sa)cos(−sa)0001)×(1tan(−sk)0010001)×(cos(sa)sin(sa)0−sin(sa)cos(sa)0001)××(cos(−r)sin(−r)0−sin(−r)cos(−r)0001)×(100010p.xp.y1)

Note that if the transform matrix is transposed compared to the above:

(acebdf001)

The operations need to be chained using right multiplication instead of left multiplication.

Visual Object

Composition Diagram for Visual Object Visual Object Asset Precomposition Image Animation Layer Visual Layer Solid Layer Image Layer Precomposition Layer Null Layer Shape Layer Stroke Dash Graphic Element Shape Style Gradient Fill Gradient Stroke Stroke Shape PolyStar Rectangle Ellipse Path Group Modifier Trim Path Transform Shape
Attribute Type Title Description
nm string

Name

Human readable name, as seen from editors and the like

Marker

Defines named portions of the composition.

Attribute Type Title Description
cm string

Comment

Comment

tm number

Time

Time

dr number

Duration

Duration

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

Defines a property value that will be set to all matched properties

Attribute Type Title Description
p

Property Value

Property Value

Slotabble Object

Object that may have its value replaced with a slot value

Composition Diagram for Slottable Object Slottable Object Image Slottable Property Scalar Property Color Property Vector Property Position Property
Attribute Type Title Description
sid string

Slot Id

Identifier to look up the slot

Slotabble Property

Property that may have its value replaced with a slot value

Composition Diagram for Slottable Property Slottable Property Slottable Object Scalar Property Color Property Vector Property Position Property
Attribute Type Title Description
sid string

Slot Id

Identifier to look up the slot

100
100
0
100

Mask

Mask for layer content.

Attribute Type Title Description
mode Mask Mode

Mode

Mode

o Scalar

Opacity

Mask opacity, as a percentage [0..100].

pt Bezier

Shape

Mask shape

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

Masks are specified in terms of a Path plus additional properties. For a given mask path, the coverage Cpath 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={Cpath·opacity,when inv=falseCpath−1·opacity,when inv=true

and the cumulative coverage for all masks is

Ccumulative=∏k=1nCk

where the product operator is determined by mode. Then the final layer coverage (alpha channel) is

Clayer′=Clayer·Ccumulative

Example

100

Glossary

local coordinates
The local coordinate system is the coordinate system of the current group or layer, with the X coordinate increasing towards the right and the Y coordinate increasing towards the bottom. Without any transforms, the point (0,0) corresponds with the top-left corner of the viewport.
render stack
A render stack is a list if rendering primitive to be drawn in inverse stack order. A render stack can contain child stacks.
stacking order
The order in which objects appear in the render stack.
collected shapes
When collecting shapes for a rendering operation, implementations MUST traverse the render stack in reverse order. All Shapes encountered in the stack traversal MUST be included, until the beginning of the stack is reached or a Modifier is encountered. If a Modifier is found, it MUST be applied to its own collected shapes and the output added to the shape collection.

JSON Schema

This page shows a formatted version of the JSON schema, you can click on highlighted objects to get a link to that section of the schema. You can also click on $ref values to jump to the relevant section.

If you want you can also view the raw schema file.

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://lottie.github.io/lottie-spec/1.0.1/specs/schema/",
    "$ref": "#/$defs/composition/animation",
    "$version": 10001,
    "$defs": {
        "assets": {
            "precomposition"  : {
                "type": "object",
                "title": "Precomposition",
                "description": "Asset containing a composition that can be referenced by layers.",
                "allOf": [
                    {
                        "$ref": "#/$defs/assets/asset"
                    },
                    {
                        "$ref": "#/$defs/composition/composition"
                    }
                ]
            },
            "all-assets"  : {
                "oneOf": [
                    {
                        "$ref": "#/$defs/assets/precomposition"
                    },
                    {
                        "$ref": "#/$defs/assets/image"
                    }
                ]
            },
            "asset"  : {
                "type": "object",
                "title": "Asset",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/visual-object"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "id": {
                                "title": "ID",
                                "description": "Unique identifier used by layers when referencing this asset",
                                "type": "string"
                            }
                        },
                        "required": [
                            "id"
                        ]
                    }
                ]
            },
            "image"  : {
                "type": "object",
                "title": "Image",
                "description": "Asset containing an image that can be referenced by layers.",
                "allOf": [
                    {
                        "$ref": "#/$defs/assets/asset"
                    },
                    {
                        "$ref": "#/$defs/helpers/slottable-object"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "w": {
                                "title": "Width",
                                "description": "Width of the image",
                                "type": "number"
                            },
                            "h": {
                                "title": "Height",
                                "description": "Height of the image",
                                "type": "number"
                            },
                            "p": {
                                "title": "File Name",
                                "description": "Name of the image file or a data url",
                                "type": "string"
                            },
                            "u": {
                                "title": "File Path",
                                "description": "Path to the image file",
                                "type": "string"
                            },
                            "e": {
                                "title": "Embedded",
                                "description": "If '1', 'p' is a Data URL",
                                "$ref": "#/$defs/values/int-boolean"
                            }
                        },
                        "allOf": [
                            {
                                "if": {
                                    "properties": {
                                        "e": {
                                            "const": 1
                                        }
                                    },
                                    "required": [
                                        "e"
                                    ]
                                },
                                "then": {
                                    "properties": {
                                        "p": {
                                            "$ref": "#/$defs/values/data-url"
                                        }
                                    }
                                }
                            }
                        ],
                        "if": {
                            "required": [
                                "sid"
                            ]
                        },
                        "else": {
                            "required": [
                                "w",
                                "h",
                                "p"
                            ]
                        }
                    }
                ]
            }
        },
        "composition": {
            "animation"  : {
                "type": "object",
                "title": "Animation",
                "description": "Top level object, describing the animation",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/visual-object"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ver": {
                                "title": "Specification Version",
                                "description": "Specification version this Lottie is targeting. This is a 6 digit number with version components encoded as MMmmpp, with MM being major version, mm being minor and pp being patch.",
                                "type": "integer",
                                "minimum": 10000
                            },
                            "fr": {
                                "title": "Framerate",
                                "description": "Framerate in frames per second",
                                "type": "number",
                                "exclusiveMinimum": 0
                            },
                            "ip": {
                                "title": "In Point",
                                "description": "Frame the animation starts at (usually 0)",
                                "type": "number"
                            },
                            "op": {
                                "title": "Out Point",
                                "description": "Frame the animation stops/loops at, which makes this the duration in frames when ip is 0",
                                "type": "number"
                            },
                            "w": {
                                "title": "Width",
                                "description": "Width of the animation",
                                "type": "integer",
                                "minimum": 0
                            },
                            "h": {
                                "title": "Height",
                                "description": "Height of the animation",
                                "type": "integer",
                                "minimum": 0
                            },
                            "assets": {
                                "title": "Assets",
                                "type": "array",
                                "description": "List of assets that can be referenced by layers",
                                "items": {
                                    "$ref": "#/$defs/assets/all-assets"
                                }
                            },
                            "markers": {
                                "title": "Markers",
                                "description": "Markers defining named sections of the composition.",
                                "type": "array",
                                "items": {
                                    "$ref": "#/$defs/helpers/marker"
                                }
                            },
                            "slots": {
                                "title": "Slots",
                                "description": "Dictionary of slot ids that will replace matching properties.",
                                "type": "object",
                                "additionalProperties": {
                                    "$ref": "#/$defs/helpers/slot"
                                }
                            }
                        },
                        "required": [
                            "w",
                            "h",
                            "fr",
                            "op",
                            "ip"
                        ]
                    },
                    {
                        "$ref": "#/$defs/composition/composition"
                    }
                ]
            },
            "composition"  : {
                "type": "object",
                "title": "Composition",
                "description": "An object that contains a list of layers",
                "properties": {
                    "layers": {
                        "title": "Layers",
                        "type": "array",
                        "items": {
                            "$ref": "#/$defs/layers/all-layers"
                        }
                    }
                },
                "required": [
                    "layers"
                ]
            }
        },
        "constants": {
            "fill-rule"  : {
                "type": "integer",
                "title": "Fill Rule",
                "description": "Rule used to handle multiple shapes rendered with the same fill object",
                "oneOf": [
                    {
                        "title": "Non Zero",
                        "description": "Everything is colored (You can think of this as an OR)",
                        "const": 1
                    },
                    {
                        "title": "Even Odd",
                        "description": "Colored based on intersections and path direction, can be used to create \"holes\"",
                        "const": 2
                    }
                ]
            },
            "trim-multiple-shapes"  : {
                "type": "integer",
                "title": "Trim Multiple Shapes",
                "description": "How to handle multiple shapes in trim path",
                "oneOf": [
                    {
                        "title": "Parallel",
                        "description": "All shapes apply the trim at the same time",
                        "const": 1
                    },
                    {
                        "title": "Sequential",
                        "description": "Shapes are considered as a continuous sequence",
                        "const": 2
                    }
                ]
            },
            "line-join"  : {
                "type": "integer",
                "title": "Line Join",
                "description": "Style at a sharp corner of a stoked line",
                "oneOf": [
                    {
                        "title": "Miter",
                        "const": 1
                    },
                    {
                        "title": "Round",
                        "const": 2
                    },
                    {
                        "title": "Bevel",
                        "const": 3
                    }
                ]
            },
            "gradient-type"  : {
                "type": "integer",
                "title": "Gradient Type",
                "description": "Whether a Gradient is a linear or radial.",
                "oneOf": [
                    {
                        "title": "Linear",
                        "description": "Colors transition in a single linear direction.",
                        "const": 1
                    },
                    {
                        "title": "Radial",
                        "description": "Colors transition outward from a center point.",
                        "const": 2
                    }
                ]
            },
            "shape-direction"  : {
                "type": "integer",
                "title": "Shape Direction",
                "description": "Drawing direction of the shape curve, useful for trim path",
                "oneOf": [
                    {
                        "title": "Normal",
                        "description": "Usually clockwise",
                        "const": 1
                    },
                    {
                        "title": "Reversed",
                        "description": "Usually counter clockwise",
                        "const": 3
                    }
                ]
            },
            "mask-mode"  : {
                "type": "string",
                "title": "Mask Mode",
                "description": "Describes how a mask interacts (blends) with the preceding masks in the stack.",
                "oneOf": [
                    {
                        "title": "None",
                        "const": "n",
                        "description": "The mask is ignored."
                    },
                    {
                        "title": "Add",
                        "const": "a",
                        "description": "Mask coverage is added (Normal blending)."
                    },
                    {
                        "title": "Subtract",
                        "const": "s",
                        "description": "Mask coverage is subtracted (Subtract blending)."
                    },
                    {
                        "title": "Intersect",
                        "const": "i",
                        "description": "Mask coverage is intersected (Source-In blending)."
                    }
                ]
            },
            "star-type"  : {
                "type": "integer",
                "title": "Star Type",
                "description": "Whether a PolyStar is a star or a polygon",
                "oneOf": [
                    {
                        "title": "Star",
                        "const": 1
                    },
                    {
                        "title": "Polygon",
                        "const": 2
                    }
                ]
            },
            "line-cap"  : {
                "type": "integer",
                "title": "Line Cap",
                "description": "Style at the end of a stoked line",
                "oneOf": [
                    {
                        "title": "Butt",
                        "const": 1
                    },
                    {
                        "title": "Round",
                        "const": 2
                    },
                    {
                        "title": "Square",
                        "const": 3
                    }
                ]
            },
            "stroke-dash-type"  : {
                "type": "string",
                "title": "Stroke Dash Type",
                "description": "Type of a dash item in a stroked line",
                "oneOf": [
                    {
                        "title": "Dash",
                        "const": "d"
                    },
                    {
                        "title": "Gap",
                        "const": "g"
                    },
                    {
                        "title": "Offset",
                        "const": "o"
                    }
                ]
            },
            "matte-mode"  : {
                "type": "integer",
                "title": "Matte Mode",
                "description": "How a layer should mask another layer",
                "oneOf": [
                    {
                        "title": "Normal",
                        "description": "The layer is not used as a track matte",
                        "const": 0
                    },
                    {
                        "title": "Alpha",
                        "description": "The masked layer opacity is modulated by the track matte layer opacity",
                        "const": 1
                    },
                    {
                        "title": "Inverted Alpha",
                        "description": "The masked layer opacity is modulated by the inverted track matte layer opacity",
                        "const": 2
                    },
                    {
                        "title": "Luma",
                        "description": "The masked layer opacity is modulated by the track matte layer luminance",
                        "const": 3
                    },
                    {
                        "title": "Inverted Luma",
                        "description": "The masked layer opacity is modulated by the inverted track matte layer luminance",
                        "const": 4
                    }
                ]
            }
        },
        "helpers": {
            "slottable-object"  : {
                "type": "object",
                "title": "Slottable Object",
                "description": "Object that may have its value replaced with a slot value",
                "properties": {
                    "sid": {
                        "title": "Slot Id",
                        "description": "Identifier to look up the slot",
                        "type": "string"
                    }
                }
            },
            "marker"  : {
                "type": "object",
                "title": "Marker",
                "description": "Defines named portions of the composition.",
                "properties": {
                    "cm": {
                        "title": "Comment",
                        "type": "string"
                    },
                    "tm": {
                        "title": "Time",
                        "type": "number"
                    },
                    "dr": {
                        "title": "Duration",
                        "type": "number"
                    }
                }
            },
            "slottable-property"  : {
                "type": "object",
                "title": "Slottable Property",
                "description": "Property that may have its value replaced with a slot value",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/slottable-object"
                    }
                ],
                "if": {
                    "required": [
                        "sid"
                    ]
                },
                "else": {
                    "required": [
                        "a",
                        "k"
                    ]
                }
            },
            "mask"  : {
                "type": "object",
                "title": "Mask",
                "description": "Mask for layer content.",
                "allOf": [
                    {
                        "properties": {
                            "mode": {
                                "title": "Mode",
                                "$ref": "#/$defs/constants/mask-mode",
                                "default": "i"
                            },
                            "o": {
                                "title": "Opacity",
                                "description": "Mask opacity, as a percentage [0..100].",
                                "$ref": "#/$defs/properties/scalar-property",
                                "default": 100
                            },
                            "pt": {
                                "title": "Shape",
                                "description": "Mask shape",
                                "$ref": "#/$defs/properties/bezier-property"
                            }
                        },
                        "required": [
                            "pt"
                        ]
                    }
                ]
            },
            "slot"  : {
                "type": "object",
                "title": "Slot",
                "description": "Defines a property value that will be set to all matched properties",
                "properties": {
                    "p": {
                        "title": "Property Value",
                        "description": "Property Value"
                    }
                },
                "required": [
                    "p"
                ]
            },
            "transform"  : {
                "type": "object",
                "title": "Transform",
                "description": "Layer transform",
                "allOf": [
                    {
                        "properties": {
                            "a": {
                                "title": "Anchor Point",
                                "description": "Anchor point: a position (relative to its parent) around which transformations are applied (ie: center for rotation / scale)",
                                "$ref": "#/$defs/properties/position-property"
                            },
                            "p": {
                                "title": "Position",
                                "description": "Position / Translation",
                                "$ref": "#/$defs/properties/splittable-position-property"
                            },
                            "r": {
                                "title": "Rotation",
                                "description": "Rotation in degrees, clockwise",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "s": {
                                "title": "Scale",
                                "description": "Scale factor, [100, 100] for no scaling",
                                "$ref": "#/$defs/properties/vector-property"
                            },
                            "o": {
                                "title": "Opacity",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "sk": {
                                "title": "Skew",
                                "description": "Skew amount as an angle in degrees",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "sa": {
                                "title": "Skew Axis",
                                "description": "Direction along which skew is applied, in degrees (0 skews along the X axis, 90 along the Y axis)",
                                "$ref": "#/$defs/properties/scalar-property"
                            }
                        }
                    }
                ]
            },
            "visual-object"  : {
                "type": "object",
                "title": "Visual Object",
                "description": "",
                "allOf": [
                    {
                        "type": "object",
                        "properties": {
                            "nm": {
                                "title": "Name",
                                "description": "Human readable name, as seen from editors and the like",
                                "type": "string"
                            }
                        },
                        "required": []
                    }
                ]
            }
        },
        "layers": {
            "solid-layer"  : {
                "type": "object",
                "title": "Solid Layer",
                "description": "Solid color, rectangle-shaped layer",
                "allOf": [
                    {
                        "$ref": "#/$defs/layers/visual-layer"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Type",
                                "description": "Layer type",
                                "type": "integer",
                                "const": 1
                            },
                            "sw": {
                                "title": "Width",
                                "description": "Solid rectangle width",
                                "type": "integer"
                            },
                            "sh": {
                                "title": "Height",
                                "description": "Solid rectangle height",
                                "type": "integer"
                            },
                            "sc": {
                                "title": "Color",
                                "description": "Solid fill color",
                                "$ref": "#/$defs/values/hexcolor"
                            }
                        },
                        "required": [
                            "ty",
                            "sw",
                            "sh",
                            "sc"
                        ]
                    }
                ]
            },
            "layer"  : {
                "type": "object",
                "title": "Layer",
                "description": "Common properties for all layers",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/visual-object"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "hd": {
                                "title": "Hidden",
                                "description": "Whether the layer is hidden",
                                "type": "boolean"
                            },
                            "ty": {
                                "title": "Type",
                                "description": "Layer Type",
                                "type": "integer"
                            },
                            "ind": {
                                "title": "Index",
                                "type": "integer",
                                "description": "Index that can be used for parenting and referenced in expressions"
                            },
                            "parent": {
                                "title": "Parent Index",
                                "description": "Must be the ind property of another layer",
                                "type": "integer"
                            },
                            "ip": {
                                "title": "In Point",
                                "description": "Frame when the layer becomes visible",
                                "type": "number"
                            },
                            "op": {
                                "title": "Out Point",
                                "description": "Frame when the layer becomes invisible",
                                "type": "number"
                            }
                        },
                        "required": [
                            "ty",
                            "ip",
                            "op"
                        ]
                    }
                ]
            },
            "image-layer"  : {
                "type": "object",
                "title": "Image Layer",
                "description": "Layer containing an image",
                "allOf": [
                    {
                        "$ref": "#/$defs/layers/visual-layer"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Type",
                                "description": "Layer type",
                                "type": "integer",
                                "const": 2
                            },
                            "refId": {
                                "title": "Reference Id",
                                "description": "ID of the image as specified in the assets",
                                "type": "string"
                            }
                        },
                        "required": [
                            "ty",
                            "refId"
                        ]
                    }
                ]
            },
            "unknown-layer"  : {
                "type": "object",
                "title": "Unknown layer types",
                "description": "Unknown layer types. Types not defined by the specification are still allowed.",
                "properties": {
                    "ty": {
                        "not": {
                            "$comment": "enum list is dynamically generated",
                            "enum": [
                                0,
                                2,
                                3,
                                1,
                                4
                            ]
                        }
                    }
                }
            },
            "visual-layer"  : {
                "type": "object",
                "title": "Visual Layer",
                "description": "Layer used to affect visual elements",
                "allOf": [
                    {
                        "$ref": "#/$defs/layers/layer"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ks": {
                                "title": "Transform",
                                "description": "Layer transform",
                                "$ref": "#/$defs/helpers/transform"
                            },
                            "ao": {
                                "title": "Auto Orient",
                                "$ref": "#/$defs/values/int-boolean",
                                "default": 0,
                                "description": "If 1, the layer will rotate itself to match its animated position path"
                            },
                            "tt": {
                                "title": "Matte Mode",
                                "$ref": "#/$defs/constants/matte-mode",
                                "description": "Defines the track matte mode for the layer"
                            },
                            "tp": {
                                "title": "Matte Parent",
                                "type": "integer",
                                "description": "Index of the layer used as matte, if omitted assume the layer above the current one"
                            },
                            "masksProperties": {
                                "title": "Masks",
                                "description": "Optional array of masks for the layer.",
                                "type": "array",
                                "items": {
                                    "$ref": "#/$defs/helpers/mask"
                                }
                            }
                        },
                        "required": [
                            "ks"
                        ]
                    }
                ]
            },
            "precomposition-layer"  : {
                "type": "object",
                "title": "Precomposition Layer",
                "description": "Layer that renders a Precomposition asset",
                "allOf": [
                    {
                        "$ref": "#/$defs/layers/visual-layer"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Type",
                                "description": "Layer type",
                                "type": "integer",
                                "const": 0
                            },
                            "refId": {
                                "title": "Reference Id",
                                "description": "ID of the precomp as specified in the assets",
                                "type": "string"
                            },
                            "w": {
                                "title": "Width",
                                "description": "Width of the clipping rect",
                                "type": "integer"
                            },
                            "h": {
                                "title": "Height",
                                "description": "Height of the clipping rect",
                                "type": "integer"
                            },
                            "sr": {
                                "title": "Time Stretch",
                                "type": "number",
                                "default": 1
                            },
                            "st": {
                                "title": "Start Time",
                                "type": "number",
                                "default": 0
                            },
                            "tm": {
                                "title": "Time Remap",
                                "description": "Timeline remap function (frame index -> time in seconds)",
                                "$ref": "#/$defs/properties/scalar-property"
                            }
                        },
                        "required": [
                            "ty",
                            "refId"
                        ]
                    }
                ]
            },
            "all-layers"  : {
                "oneOf": [
                    {
                        "$ref": "#/$defs/layers/precomposition-layer"
                    },
                    {
                        "$ref": "#/$defs/layers/image-layer"
                    },
                    {
                        "$ref": "#/$defs/layers/null-layer"
                    },
                    {
                        "$ref": "#/$defs/layers/solid-layer"
                    },
                    {
                        "$ref": "#/$defs/layers/shape-layer"
                    },
                    {
                        "$ref": "#/$defs/layers/unknown-layer"
                    }
                ]
            },
            "null-layer"  : {
                "type": "object",
                "title": "Null Layer",
                "description": "Layer with no data, useful to group layers together",
                "allOf": [
                    {
                        "$ref": "#/$defs/layers/visual-layer"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Type",
                                "description": "Layer type",
                                "type": "integer",
                                "const": 3
                            }
                        },
                        "required": [
                            "ty"
                        ]
                    }
                ]
            },
            "shape-layer"  : {
                "type": "object",
                "title": "Shape Layer",
                "description": "Layer containing Shapes",
                "allOf": [
                    {
                        "$ref": "#/$defs/layers/visual-layer"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Type",
                                "description": "Layer type",
                                "type": "integer",
                                "const": 4
                            },
                            "shapes": {
                                "title": "Shapes",
                                "type": "array",
                                "items": {
                                    "$ref": "#/$defs/shapes/all-graphic-elements"
                                }
                            }
                        },
                        "required": [
                            "ty",
                            "shapes"
                        ]
                    }
                ]
            }
        },
        "properties": {
            "vector-keyframe"  : {
                "type": "object",
                "title": "Vector Keyframe",
                "allOf": [
                    {
                        "$ref": "#/$defs/properties/base-keyframe"
                    },
                    {
                        "properties": {
                            "s": {
                                "title": "Value",
                                "description": "Value at this keyframe.",
                                "$ref": "#/$defs/values/vector"
                            }
                        }
                    }
                ],
                "required": [
                    "s"
                ]
            },
            "base-keyframe"  : {
                "type": "object",
                "title": "Base Keyframe",
                "description": "A Keyframes specifies the value at a specific time and the interpolation function to reach the next keyframe.",
                "allOf": [
                    {
                        "properties": {
                            "t": {
                                "title": "Time",
                                "description": "Frame number",
                                "type": "number",
                                "default": 0
                            },
                            "h": {
                                "title": "Hold",
                                "$ref": "#/$defs/values/int-boolean",
                                "default": 0
                            },
                            "i": {
                                "title": "In Tangent",
                                "description": "Easing tangent going into the next keyframe",
                                "$ref": "#/$defs/properties/easing-handle"
                            },
                            "o": {
                                "title": "Out Tangent",
                                "description": "Easing tangent leaving the current keyframe",
                                "$ref": "#/$defs/properties/easing-handle"
                            }
                        }
                    }
                ],
                "required": [
                    "t"
                ]
            },
            "splittable-position-property"  : {
                "type": "object",
                "title": "Splittable Position Property",
                "description": "An animatable position where position values may be defined and animated separately.",
                "oneOf": [
                    {
                        "$comment": "Grouped XY position coordinates",
                        "$ref": "#/$defs/properties/position-property",
                        "properties": {
                            "s": {
                                "title": "Split",
                                "description": "Whether the position has split values",
                                "type": "boolean",
                                "const": false
                            }
                        }
                    },
                    {
                        "$comment": "Split XY position coordinates",
                        "$ref": "#/$defs/properties/split-position"
                    }
                ]
            },
            "scalar-property"  : {
                "type": "object",
                "title": "Scalar Property",
                "description": "An animatable property that holds a float",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/slottable-property"
                    }
                ],
                "oneOf": [
                    {
                        "$comment": "Not animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 0
                            },
                            "k": {
                                "title": "Value",
                                "description": "Static Value",
                                "type": "number"
                            }
                        }
                    },
                    {
                        "$comment": "Animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 1
                            },
                            "k": {
                                "type": "array",
                                "title": "Keyframes",
                                "description": "Array of keyframes",
                                "items": {
                                    "$ref": "#/$defs/properties/vector-keyframe"
                                }
                            }
                        }
                    }
                ]
            },
            "split-position"  : {
                "type": "object",
                "title": "Split Position",
                "description": "An animatable position where x and y are definied and animated separately.",
                "properties": {
                    "s": {
                        "title": "Split",
                        "description": "Whether the position has split values",
                        "type": "boolean",
                        "const": true
                    },
                    "x": {
                        "title": "X Position",
                        "description": "X Position",
                        "$ref": "#/$defs/properties/scalar-property"
                    },
                    "y": {
                        "title": "Y Position",
                        "description": "Y Position",
                        "$ref": "#/$defs/properties/scalar-property"
                    }
                },
                "required": [
                    "s",
                    "x",
                    "y"
                ]
            },
            "easing-handle"  : {
                "type": "object",
                "title": "Keyframe Easing",
                "description": "Bezier handle for keyframe interpolation",
                "properties": {
                    "x": {
                        "title": "X",
                        "description": "Time component:\n0 means start time of the keyframe,\n1 means time of the next keyframe.",
                        "oneOf": [
                            {
                                "type": "array",
                                "$ref": "#/$defs/values/vector",
                                "items": {
                                    "type": "number",
                                    "default": 0,
                                    "minimum": 0,
                                    "maximum": 1
                                },
                                "minItems": 1
                            },
                            {
                                "type": "number",
                                "default": 0,
                                "minimum": 0,
                                "maximum": 1
                            }
                        ]
                    },
                    "y": {
                        "title": "Y",
                        "description": "Value interpolation component:\n0 means start value of the keyframe,\n1 means value at the next keyframe.",
                        "oneOf": [
                            {
                                "type": "array",
                                "$ref": "#/$defs/values/vector",
                                "items": {
                                    "type": "number",
                                    "default": 0
                                },
                                "minItems": 1
                            },
                            {
                                "type": "number",
                                "default": 0
                            }
                        ]
                    }
                },
                "required": [
                    "x",
                    "y"
                ]
            },
            "gradient-keyframe"  : {
                "type": "object",
                "title": "Gradient Keyframe",
                "allOf": [
                    {
                        "$ref": "#/$defs/properties/base-keyframe"
                    },
                    {
                        "properties": {
                            "s": {
                                "title": "Value",
                                "description": "Value at this keyframe.",
                                "$ref": "#/$defs/values/gradient"
                            }
                        }
                    }
                ],
                "required": [
                    "s"
                ]
            },
            "gradient-stops"  : {
                "type": "object",
                "title": "Gradient Stops",
                "description": "Animatable vector representing the gradient stops",
                "oneOf": [
                    {
                        "$comment": "Not animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 0
                            },
                            "k": {
                                "title": "Value",
                                "description": "Static Value",
                                "$ref": "#/$defs/values/gradient"
                            }
                        }
                    },
                    {
                        "$comment": "Animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 1
                            },
                            "k": {
                                "type": "array",
                                "title": "Keyframes",
                                "description": "Array of keyframes",
                                "items": {
                                    "$ref": "#/$defs/properties/gradient-keyframe"
                                }
                            }
                        }
                    }
                ],
                "required": [
                    "a",
                    "k"
                ]
            },
            "gradient-property"  : {
                "type": "object",
                "title": "Gradient Property",
                "description": "An animatable property that holds a Gradient",
                "properties": {
                    "p": {
                        "title": "Color stop count",
                        "type": "number"
                    },
                    "k": {
                        "title": "Gradient stops",
                        "description": "Animatable vector representing the gradient stops",
                        "$ref": "#/$defs/properties/gradient-stops"
                    }
                },
                "required": [
                    "p",
                    "k"
                ]
            },
            "bezier-keyframe"  : {
                "type": "object",
                "title": "Shape Keyframe",
                "allOf": [
                    {
                        "$ref": "#/$defs/properties/base-keyframe"
                    },
                    {
                        "properties": {
                            "s": {
                                "title": "Value",
                                "description": "Value at this keyframe.",
                                "type": "array",
                                "items": {
                                    "$ref": "#/$defs/values/bezier"
                                },
                                "minItems": 1,
                                "maxItems": 1
                            }
                        }
                    }
                ],
                "required": [
                    "s"
                ]
            },
            "color-keyframe"  : {
                "type": "object",
                "title": "Color Keyframe",
                "allOf": [
                    {
                        "$ref": "#/$defs/properties/base-keyframe"
                    },
                    {
                        "properties": {
                            "s": {
                                "title": "Value",
                                "description": "Value at this keyframe.",
                                "$ref": "#/$defs/values/color"
                            }
                        }
                    }
                ],
                "required": [
                    "s"
                ]
            },
            "position-keyframe"  : {
                "type": "object",
                "title": "Position Keyframe",
                "allOf": [
                    {
                        "$ref": "#/$defs/properties/vector-keyframe"
                    },
                    {
                        "properties": {
                            "ti": {
                                "title": "Value In Tangent",
                                "description": "Tangent for values (eg: moving position around a curved path)",
                                "$ref": "#/$defs/values/vector"
                            },
                            "to": {
                                "title": "Value Out Tangent",
                                "description": "Tangent for values (eg: moving position around a curved path)",
                                "$ref": "#/$defs/values/vector"
                            }
                        }
                    }
                ]
            },
            "color-property"  : {
                "type": "object",
                "title": "Color Property",
                "description": "An animatable property that holds a Color",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/slottable-property"
                    }
                ],
                "oneOf": [
                    {
                        "$comment": "Not animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 0
                            },
                            "k": {
                                "title": "Value",
                                "description": "Static Value",
                                "$ref": "#/$defs/values/color"
                            }
                        }
                    },
                    {
                        "$comment": "Animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 1
                            },
                            "k": {
                                "type": "array",
                                "title": "Keyframes",
                                "description": "Array of keyframes",
                                "items": {
                                    "$ref": "#/$defs/properties/color-keyframe"
                                }
                            }
                        }
                    }
                ]
            },
            "vector-property"  : {
                "type": "object",
                "title": "Vector Property",
                "description": "An animatable property that holds an array of numbers",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/slottable-property"
                    }
                ],
                "oneOf": [
                    {
                        "$comment": "Not animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 0
                            },
                            "k": {
                                "title": "Value",
                                "description": "Static Value",
                                "$ref": "#/$defs/values/vector"
                            }
                        }
                    },
                    {
                        "$comment": "Animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 1
                            },
                            "k": {
                                "type": "array",
                                "title": "Keyframes",
                                "description": "Array of keyframes",
                                "items": {
                                    "$ref": "#/$defs/properties/vector-keyframe"
                                }
                            }
                        }
                    }
                ]
            },
            "position-property"  : {
                "type": "object",
                "title": "Position Property",
                "description": "An animatable property to represent a position in space",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/slottable-property"
                    }
                ],
                "oneOf": [
                    {
                        "$comment": "Not animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 0
                            },
                            "k": {
                                "title": "Value",
                                "description": "Static Value",
                                "$ref": "#/$defs/values/vector"
                            }
                        }
                    },
                    {
                        "$comment": "Animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 1
                            },
                            "k": {
                                "type": "array",
                                "title": "Keyframes",
                                "description": "Array of keyframes",
                                "items": {
                                    "$ref": "#/$defs/properties/position-keyframe"
                                }
                            }
                        }
                    }
                ],
                "required": [
                    "a",
                    "k"
                ]
            },
            "bezier-property"  : {
                "type": "object",
                "title": "Bezier Property",
                "description": "An animatable property that holds a Bezier shape",
                "oneOf": [
                    {
                        "$comment": "Not animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 0
                            },
                            "k": {
                                "title": "Value",
                                "description": "Static Value",
                                "$ref": "#/$defs/values/bezier"
                            }
                        }
                    },
                    {
                        "$comment": "Animated",
                        "properties": {
                            "a": {
                                "title": "Animated",
                                "description": "Whether the property is animated",
                                "$ref": "#/$defs/values/int-boolean",
                                "const": 1
                            },
                            "k": {
                                "type": "array",
                                "title": "Keyframes",
                                "description": "Array of keyframes",
                                "items": {
                                    "$ref": "#/$defs/properties/bezier-keyframe"
                                }
                            }
                        }
                    }
                ],
                "required": [
                    "a",
                    "k"
                ]
            }
        },
        "shapes": {
            "shape-style"  : {
                "type": "object",
                "title": "Shape Style",
                "description": "Describes the visual appearance (like fill and stroke) of neighbouring shapes",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/graphic-element"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "o": {
                                "title": "Opacity",
                                "description": "Opacity, 100 means fully opaque",
                                "$ref": "#/$defs/properties/scalar-property"
                            }
                        },
                        "required": [
                            "o"
                        ]
                    }
                ]
            },
            "shape"  : {
                "type": "object",
                "title": "Shape",
                "description": "Drawable shape, defines the actual shape but not the style",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/graphic-element"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "d": {
                                "title": "Direction",
                                "description": "Direction the shape is drawn as, mostly relevant when using trim path",
                                "$ref": "#/$defs/constants/shape-direction"
                            }
                        }
                    }
                ]
            },
            "polystar"  : {
                "type": "object",
                "title": "PolyStar",
                "description": "Star or regular polygon",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/shape"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "sr"
                            },
                            "p": {
                                "title": "Position",
                                "$ref": "#/$defs/properties/position-property"
                            },
                            "or": {
                                "title": "Outer Radius",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "os": {
                                "title": "Outer Roundness",
                                "description": "Outer Roundness as a percentage",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "r": {
                                "title": "Rotation",
                                "description": "Rotation, clockwise in degrees",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "pt": {
                                "title": "Points",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "sy": {
                                "title": "Star Type",
                                "$ref": "#/$defs/constants/star-type",
                                "default": 1
                            },
                            "ir": {
                                "title": "Inner Radius",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "is": {
                                "title": "Inner Roundness",
                                "description": "Inner Roundness as a percentage",
                                "$ref": "#/$defs/properties/scalar-property"
                            }
                        },
                        "required": [
                            "ty",
                            "or",
                            "os",
                            "pt",
                            "p",
                            "r"
                        ]
                    },
                    {
                        "if": {
                            "properties": {
                                "sy": {
                                    "const": 1
                                }
                            }
                        },
                        "then": {
                            "required": [
                                "ir",
                                "is"
                            ]
                        }
                    }
                ]
            },
            "rectangle"  : {
                "type": "object",
                "title": "Rectangle",
                "description": "A simple rectangle shape",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/shape"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "rc"
                            },
                            "p": {
                                "title": "Position",
                                "description": "Center of the rectangle",
                                "$ref": "#/$defs/properties/position-property"
                            },
                            "s": {
                                "title": "Size",
                                "$ref": "#/$defs/properties/vector-property"
                            },
                            "r": {
                                "title": "Roundness",
                                "description": "Rounded corners radius",
                                "$ref": "#/$defs/properties/scalar-property"
                            }
                        },
                        "required": [
                            "ty",
                            "s",
                            "p"
                        ]
                    }
                ]
            },
            "group"  : {
                "type": "object",
                "title": "Group",
                "description": "Shape Element that can contain other shapes",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/graphic-element"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "gr"
                            },
                            "np": {
                                "title": "Number Of Properties",
                                "type": "number"
                            },
                            "it": {
                                "title": "Shapes",
                                "type": "array",
                                "items": {
                                    "$ref": "#/$defs/shapes/all-graphic-elements"
                                }
                            }
                        },
                        "required": [
                            "ty"
                        ]
                    }
                ]
            },
            "ellipse"  : {
                "type": "object",
                "title": "Ellipse",
                "description": "Ellipse shape",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/shape"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "el"
                            },
                            "p": {
                                "title": "Position",
                                "$ref": "#/$defs/properties/position-property"
                            },
                            "s": {
                                "title": "Size",
                                "$ref": "#/$defs/properties/vector-property"
                            }
                        },
                        "required": [
                            "ty",
                            "s",
                            "p"
                        ]
                    }
                ]
            },
            "path"  : {
                "type": "object",
                "title": "Path",
                "description": "Custom Bezier shape",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/shape"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "sh"
                            },
                            "ks": {
                                "title": "Shape",
                                "description": "Bezier path",
                                "$ref": "#/$defs/properties/bezier-property"
                            }
                        },
                        "required": [
                            "ty",
                            "ks"
                        ]
                    }
                ]
            },
            "base-gradient"  : {
                "type": "object",
                "title": "Base Gradient",
                "description": "Common properties for gradients",
                "allOf": [
                    {
                        "type": "object",
                        "properties": {
                            "g": {
                                "title": "Colors",
                                "description": "Gradient colors",
                                "$ref": "#/$defs/properties/gradient-property"
                            },
                            "s": {
                                "title": "Start Point",
                                "description": "Starting point for the gradient",
                                "$ref": "#/$defs/properties/position-property"
                            },
                            "e": {
                                "title": "End Point",
                                "description": "End point for the gradient",
                                "$ref": "#/$defs/properties/position-property"
                            },
                            "t": {
                                "title": "Gradient Type",
                                "description": "Type of the gradient",
                                "$ref": "#/$defs/constants/gradient-type"
                            },
                            "h": {
                                "title": "Highlight Length",
                                "description": "Highlight Length, as a percentage between s and e",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "a": {
                                "title": "Highlight Angle",
                                "description": "Highlight Angle in clockwise degrees, relative to the direction from s to e",
                                "$ref": "#/$defs/properties/scalar-property"
                            }
                        },
                        "required": [
                            "s",
                            "e",
                            "g",
                            "t"
                        ]
                    }
                ]
            },
            "gradient-fill"  : {
                "type": "object",
                "title": "Gradient",
                "description": "Gradient fill color",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/shape-style"
                    },
                    {
                        "$ref": "#/$defs/shapes/base-gradient"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "gf"
                            },
                            "r": {
                                "title": "Fill Rule",
                                "$ref": "#/$defs/constants/fill-rule"
                            }
                        },
                        "required": [
                            "ty"
                        ]
                    }
                ]
            },
            "base-stroke"  : {
                "type": "object",
                "title": "Base Stroke",
                "description": "Common properties for stroke styles",
                "allOf": [
                    {
                        "type": "object",
                        "properties": {
                            "lc": {
                                "title": "Line Cap",
                                "$ref": "#/$defs/constants/line-cap",
                                "default": 2
                            },
                            "lj": {
                                "title": "Line Join",
                                "$ref": "#/$defs/constants/line-join",
                                "default": 2
                            },
                            "ml": {
                                "title": "Miter Limit",
                                "type": "number",
                                "default": 0
                            },
                            "ml2": {
                                "title": "Miter Limit",
                                "description": "Animatable alternative to ml",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "w": {
                                "title": "Width",
                                "description": "Stroke width",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "d": {
                                "title": "Dashes",
                                "description": "Dashed line definition",
                                "type": "array",
                                "items": {
                                    "$ref": "#/$defs/shapes/stroke-dash"
                                }
                            }
                        },
                        "required": [
                            "w"
                        ]
                    }
                ]
            },
            "modifier"  : {
                "type": "object",
                "title": "Modifier",
                "description": "Modifiers change the bezier curves of neighbouring shapes",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/graphic-element"
                    }
                ]
            },
            "trim-path"  : {
                "type": "object",
                "title": "Trim Path",
                "description": "Trims shapes into a segment",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/modifier"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "tm"
                            },
                            "s": {
                                "title": "Start",
                                "description": "Segment start",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "e": {
                                "title": "End",
                                "description": "Segment end",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "o": {
                                "title": "Offset",
                                "$ref": "#/$defs/properties/scalar-property"
                            },
                            "m": {
                                "title": "Multiple",
                                "description": "How to treat multiple copies",
                                "$ref": "#/$defs/constants/trim-multiple-shapes"
                            }
                        },
                        "required": [
                            "ty",
                            "o",
                            "s",
                            "e"
                        ]
                    }
                ]
            },
            "unknown-shape"  : {
                "type": "object",
                "title": "Unknown shape types",
                "description": "Unknown shape types. Types not defined by the specification are still allowed.",
                "properties": {
                    "ty": {
                        "not": {
                            "$comment": "enum list is dynamically generated",
                            "enum": [
                                "el",
                                "fl",
                                "gf",
                                "gs",
                                "gr",
                                "sh",
                                "sr",
                                "rc",
                                "st",
                                "tr",
                                "tm"
                            ]
                        }
                    }
                }
            },
            "fill"  : {
                "type": "object",
                "title": "Fill",
                "description": "Solid fill color",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/shape-style"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "fl"
                            },
                            "c": {
                                "title": "Color",
                                "$ref": "#/$defs/properties/color-property"
                            },
                            "r": {
                                "title": "Fill Rule",
                                "$ref": "#/$defs/constants/fill-rule"
                            }
                        },
                        "required": [
                            "ty",
                            "c"
                        ]
                    }
                ]
            },
            "stroke-dash"  : {
                "type": "object",
                "title": "Stroke Dash",
                "description": "An item used to described the dash pattern in a stroked path",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/visual-object"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "n": {
                                "title": "Dash Type",
                                "$ref": "#/$defs/constants/stroke-dash-type",
                                "default": "d"
                            },
                            "v": {
                                "title": "Length",
                                "description": "Length of the dash",
                                "$ref": "#/$defs/properties/scalar-property"
                            }
                        },
                        "required": []
                    }
                ]
            },
            "gradient-stroke"  : {
                "type": "object",
                "title": "Gradient Stroke",
                "description": "Gradient stroke",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/shape-style"
                    },
                    {
                        "$ref": "#/$defs/shapes/base-stroke"
                    },
                    {
                        "$ref": "#/$defs/shapes/base-gradient"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "gs"
                            }
                        },
                        "required": [
                            "ty"
                        ]
                    }
                ]
            },
            "transform"  : {
                "type": "object",
                "title": "Transform Shape",
                "description": "Group transform",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/graphic-element"
                    },
                    {
                        "$ref": "#/$defs/helpers/transform"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "tr"
                            }
                        },
                        "required": [
                            "ty"
                        ]
                    }
                ]
            },
            "stroke"  : {
                "type": "object",
                "title": "Stroke",
                "description": "Solid stroke",
                "allOf": [
                    {
                        "$ref": "#/$defs/shapes/shape-style"
                    },
                    {
                        "$ref": "#/$defs/shapes/base-stroke"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ty": {
                                "title": "Shape Type",
                                "type": "string",
                                "const": "st"
                            },
                            "c": {
                                "title": "Color",
                                "description": "Stroke color",
                                "$ref": "#/$defs/properties/color-property"
                            }
                        },
                        "required": [
                            "ty",
                            "c"
                        ]
                    }
                ]
            },
            "graphic-element"  : {
                "type": "object",
                "title": "Graphic Element",
                "description": "Element used to display vector data in a shape layer",
                "allOf": [
                    {
                        "$ref": "#/$defs/helpers/visual-object"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "hd": {
                                "title": "Hidden",
                                "description": "Whether the shape is hidden",
                                "type": "boolean"
                            },
                            "ty": {
                                "title": "Shape Type",
                                "type": "string"
                            }
                        },
                        "required": [
                            "ty"
                        ]
                    }
                ]
            },
            "all-graphic-elements"  : {
                "$comment": "List of valid shapes",
                "oneOf": [
                    {
                        "$ref": "#/$defs/shapes/ellipse"
                    },
                    {
                        "$ref": "#/$defs/shapes/fill"
                    },
                    {
                        "$ref": "#/$defs/shapes/gradient-fill"
                    },
                    {
                        "$ref": "#/$defs/shapes/gradient-stroke"
                    },
                    {
                        "$ref": "#/$defs/shapes/group"
                    },
                    {
                        "$ref": "#/$defs/shapes/path"
                    },
                    {
                        "$ref": "#/$defs/shapes/polystar"
                    },
                    {
                        "$ref": "#/$defs/shapes/rectangle"
                    },
                    {
                        "$ref": "#/$defs/shapes/stroke"
                    },
                    {
                        "$ref": "#/$defs/shapes/transform"
                    },
                    {
                        "$ref": "#/$defs/shapes/trim-path"
                    },
                    {
                        "$ref": "#/$defs/shapes/unknown-shape"
                    }
                ]
            }
        },
        "values": {
            "gradient"  : {
                "type": "array",
                "title": "Gradient",
                "description": "A flat list of color stops followed by optional transparency stops. A color stop is [offset, red, green, blue]. A transparency stop is [offset, transparency]. All values are between 0 and 1",
                "items": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                }
            },
            "data-url"  : {
                "type": "string",
                "title": "Data URL",
                "description": "An embedded data object",
                "pattern": "^data:([\w/]+)(;base64)?,(.+)$"
            },
            "bezier"  : {
                "type": "object",
                "title": "Bezier",
                "description": "Cubic polybezier",
                "properties": {
                    "c": {
                        "title": "Closed",
                        "type": "boolean",
                        "default": false
                    },
                    "i": {
                        "title": "In Tangents",
                        "type": "array",
                        "description": "Array of points, each point is an array of coordinates.\nThese points are along the in tangents relative to the corresponding v.",
                        "items": {
                            "$ref": "#/$defs/values/vector",
                            "default": []
                        }
                    },
                    "o": {
                        "title": "Out Tangents",
                        "type": "array",
                        "description": "Array of points, each point is an array of coordinates.\nThese points are along the out tangents relative to the corresponding v.",
                        "items": {
                            "$ref": "#/$defs/values/vector",
                            "default": []
                        }
                    },
                    "v": {
                        "title": "Vertices",
                        "description": "Array of points, each point is an array of coordinates.\nThese points are along the bezier path",
                        "type": "array",
                        "items": {
                            "$ref": "#/$defs/values/vector",
                            "default": []
                        }
                    }
                },
                "required": [
                    "i",
                    "v",
                    "o"
                ]
            },
            "vector"  : {
                "type": "array",
                "title": "Vector",
                "description": "An array of numbers",
                "items": {
                    "type": "number"
                }
            },
            "int-boolean"  : {
                "type": "integer",
                "title": "Integer Boolean",
                "description": "Represents boolean values as an integer. 0 is false, 1 is true.",
                "default": 0,
                "examples": [
                    0
                ],
                "enum": [
                    0,
                    1
                ],
                "oneOf": [
                    {
                        "title": "True",
                        "const": 1
                    },
                    {
                        "title": "False",
                        "const": 0
                    }
                ]
            },
            "hexcolor"  : {
                "type": "string",
                "title": "Hex Color",
                "description": "Color value in hexadecimal format, with two digits per component ('#RRGGBB')",
                "pattern": "^#([a-fA-F0-9]{6})$",
                "examples": [
                    "#FF00AA"
                ]
            },
            "color"  : {
                "type": "array",
                "title": "Color",
                "description": "Color as a [r, g, b] array with values in [0, 1]",
                "items": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                },
                "minItems": 3,
                "maxItems": 4
            }
        }
    }
}

Ended: Format

Community ↵

Contributing ↵

Ended: Contributing

Ended: Community


Search

From here you can search these documents. Enter your search terms below.

Keyboard Shortcuts

Keys Action
? Open this help
n Next page
p Previous page
s Search