Appearance
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 construct | Native Anim representation |
|---|---|
| cubic shape and morph | retained BezierPath plus Signal<Path> |
| solid fill/stroke | retained path paint with fill rule, cap, join, and miter |
| arbitrary rotation | sampled Q16 affine transform |
| multi-keyframe properties | typed keyframes signals |
spatial to/ti tangents | cubic Signal<Point2> consumed by place |
| alpha track matte | retained mask scene |
| precomp start offset | exact 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:
| Construct | Required Anim extension |
|---|---|
| linear/radial gradients | retained brush/shader values and deterministic CPU/SVG paint |
| trim paths, dash offset, taper | retained path-measure and stroke-effect semantics |
| merge paths and repeaters | bounded retained path boolean/instance operators |
| subtract/intersect/inverted/feathered masks | mask modes plus deterministic blur coverage |
| non-normal blend modes | explicit linear-light compositing operators |
| text layers | pinned font assets, shaping, glyph fallback, and text-on-path rules |
| image layers | bounded asset references, decoding, color management, and sampling |
| expressions | a specified deterministic expression language or translation boundary |
| 3D layers, cameras, and lights | projective transforms, depth ordering, and 3D rendering |
| effects | a typed, bounded image-effect graph with backend parity |
| negative start offsets and non-unit time stretch | a 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:
| Frame | SSIM | PSNR |
|---|---|---|
| 0 | 0.999987 | 60.765 dB |
| 90 | 0.994310 | 30.530 dB |
| 180 | 0.999938 | 54.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 --forceThe regression test imports the complete compatibility file and proves that frames 100, 200, and 300 produce distinct native SVG scenes.