Skip to content

Lottie import

anim import-lottie INPUT.json -o OUTPUT.anim converts a deliberately bounded Lottie profile into ordinary, editable Anim source. The output has no runtime dependency on Lottie and is deterministic: importing the same bytes produces the same source bytes.

The implemented profile covers the constructs exercised by examples/RRX9U6XiOf.json: two-dimensional shape and precomposition layers, cubic paths and compatible path morphs, solid fills and strokes, group and layer transforms, arbitrary rotation, exact temporal easing, spatial motion tangents, parenting, layer timing, opacity, normal compositing, and alpha track mattes. Unsupported input fails with a JSON path rather than producing a partial approximation.

The byte-exact generated fixture is committed as examples/lets-go.anim.

The bounded profile requires a zero composition in-point, unit layer stretch, nonnegative layer start offsets, visible 2D layers and shape items, and expression-free properties. These constraints are checked rather than silently ignored.

Why core changes were required

The source converter is intentionally thin. It maps Lottie concepts onto general Anim capabilities added in Specs 0039–0041:

Lottie constructNative Anim representation
cubic shape and morphretained BezierPath plus Signal<Path>
solid fill/strokeretained path paint with fill rule, cap, join, and miter
arbitrary rotationsampled Q16 affine transform
multi-keyframe propertiestyped keyframes signals
spatial to/ti tangentscubic Signal<Point2> consumed by place
alpha track matteretained mask scene
precomp start offsetexact sequence local time

These are reusable language and engine features; none contains fixture names, layer indices, or path coordinates.

Common constructs still requiring engine work

The importer rejects the following popular Lottie features because faithful support needs a meaningful retained-engine extension, not a JSON-only rewrite:

ConstructRequired Anim extension
linear/radial gradientsretained brush/shader values and deterministic CPU/SVG paint
trim paths, dash offset, taperretained path-measure and stroke-effect semantics
merge paths and repeatersbounded retained path boolean/instance operators
subtract/intersect/inverted/feathered masksmask modes plus deterministic blur coverage
non-normal blend modesexplicit linear-light compositing operators
text layerspinned font assets, shaping, glyph fallback, and text-on-path rules
image layersbounded asset references, decoding, color management, and sampling
expressionsa specified deterministic expression language or translation boundary
3D layers, cameras, and lightsprojective transforms, depth ordering, and 3D rendering
effectsa typed, bounded image-effect graph with backend parity
negative start offsets and non-unit time stretcha retained local-time transform

The error boundary is part of the compatibility contract. Adding any row should be a separate vertical slice with scene semantics, language exposure, CPU rendering, SVG behavior where applicable, and conformance fixtures.

Conformance evidence

The committed fixture was independently rendered with lottie-web 5.13.0's SVG backend. Both reference SVG and Anim SVG were rasterized by the same FFmpeg SVG decoder at 1000×800 before comparison:

FrameSSIMPSNR
00.99998760.765 dB
900.99431030.530 dB
1800.99993854.851 dB

The comparison permits subpixel and easing-grid differences; the native Anim determinism contract remains byte-exact and is tested separately.

Lossy Soccer compatibility edition

examples/soccer-supported.json is a hand-translated, explicitly lossy version of examples/soccer.json. It demonstrates how a complex export can be reduced to the existing profile without weakening the importer's fail-closed default. The original source remains unchanged.

The compatibility edition retains the main 330-frame shot at 1440×1024 and 60 fps. It preserves ordinary cubic path animation, supported transforms, parenting, solid painting, and layer timing. Ellipses are converted to cubic paths, gradients to deterministic midpoint colors, and the matte-only ball artwork to a classic outlined pentagon-and-seam motif. Its seven-shade skin palette is hand recolored from pink to warm light brown while retaining the original shading. Four unsupported finger fragments are replaced by one overlapping hand silhouette.

The translation deliberately omits alternate shots, effects, blend modes, matte-dependent artwork, boolean/path modifiers, hidden construction layers, and unsupported local-time behavior. It is a showcase of graceful degradation, not a conformance result or a replacement for the missing engine features.

Convert and render a representative SVG frame:

sh
anim import-lottie examples/soccer-supported.json \
  -o /tmp/soccer-supported.anim
anim render \
  /tmp/soccer-supported.anim --frame 200 \
  -o /tmp/soccer-supported-200.svg --force

The regression test imports the complete compatibility file and proves that frames 100, 200, and 300 produce distinct native SVG scenes.

Anim 0.1 preview · Documentation and examples are MIT licensed · Runtime binaries are proprietary