Skip to main content

fusion2lottie

CI

Convert motion design made in DaVinci Resolve's Fusion page to Lottie, so it plays on the web and in apps (lottie-web, lottie-react, iOS, Android) the way After Effects animations do through Bodymovin.

uvx fusion2lottie intro.comp --fps 30      # writes intro.json

The conversion is exact, not approximate. Fusion's shape tools and Lottie's shape layers share the same model: shapes, groups and transforms, animated by cubic-bezier keyframes. A composition outside the supported subset is refused with a list of what to change, never silently approximated.

Alpha. The core shape tools convert; more are on the way. See What converts.

Use it

From DaVinci Resolve

uvx fusion2lottie install-resolve

Restart Resolve, put the playhead over a clip with a Fusion composition, and choose Workspace → Scripts → Export to Lottie. It asks where to save, offers the timeline's frame rate, and reports what it wrote or what stopped it. Inputs driven by expressions or modifiers (such as Shake) are sampled at every frame through Fusion, so they export too. It exports the composition's render range, which is the whole clip unless you set one in the Fusion page. uvx fusion2lottie uninstall-resolve removes it.

The installer copies fusion2lottie into its own folder for Resolve's built-in Python, which has no pip, and adds a small script to Resolve's per-user Scripts folder.

From the command line

  1. In Resolve's Fusion page, build the animation with the shape tools and keyframes.

  2. Export the composition: right-click the clip in the Edit page, then Fusion → Export Composition…. From a script, use TimelineItem.ExportFusionComp(path, 1).

  3. Convert it:

    uvx fusion2lottie intro.comp --fps 30 -o intro.json
    uvx fusion2lottie intro.comp --check          # list what would stop the conversion
    

    Resolve does not save the frame rate in the comp, so pass your timeline's with --fps. Inputs driven by expressions or modifiers need Fusion to evaluate them: use the Resolve menu, or pass their values per frame with --samples values.json ({"Tool.Input": [one value per frame], ...}).

Play it

For example with lottie-react:

import { Lottie } from 'lottie-react';
import intro from './intro.json';

<Lottie src={intro} autoplay loop={false} style={{ width: 512, height: 512 }} />

From Python

from fusion2lottie import parse, convert

lottie, notes = convert(parse(open("intro.comp").read()), fps=30)

What converts

Fusion Lottie
sPolygon: polyline (straight or curved, open or closed), Center, Size, ZRotation shape group: path and transform (Size scales the path, not an outline's width, as in Fusion)
sRectangle (with CornerRadius), sEllipse, sNGon, sStar: Width, Height, Depth, Translate, Angle path drawn where Fusion draws it, keyframed as it resizes
colour, Alpha, Opacity fill or stroke colour and opacity, group opacity
outlines (Solid off): BorderWidth, JoinStyle, CapStyle, MiterLimit stroke with the same width, joins and caps
write-on: WritePosition, WriteLength trim path, starting and running where Fusion's does
sMerge group (Fusion's highest input drawn on top)
sTransform: offset, size (including mirroring with a negative size), rotation, pivot group transform
sRender shape layer
Background (solid) solid layer
Merge (untransformed, Normal) layer order
BezierSpline keyframes keyframes with the same easing, converted exactly
expressions, and modifiers such as Shake a keyframe per frame, from Fusion's own values (Resolve menu or --samples)

One tool's output feeding several tools is fine: Lottie has no instancing, so the shared part is written once per use. A shape animated in a way one easing curve cannot reproduce exactly, such as width and height on different keyframes, is sampled once per frame instead, and the conversion says so.

Not yet: keyframed polylines and paths for points, Sides and Points changing over time, Text+, transformed or blended Merges, the other shape tools (sBoolean, sDuplicate, sGrid, sOutline, sExpand, sJitter).

Never: blur, glow, particles, 3D and other pixel effects. Lottie is vector, so render those as video with alpha instead.

How it is checked

Conversions are compared with Resolve's own render, frame by frame. fidelity/ holds small compositions that each exercise one family of tools, and a script that renders them in Resolve and keeps the comp and frames Resolve produces as test fixtures. The test suite converts each fixture, plays it with lottie-web in headless Chrome, and requires every frame to match Resolve's within one-pixel anti-aliasing: under 3% of the drawn area, and in practice 0.3–1.4%. The tests also check keyframes against the values Fusion itself reports.

Develop

(cd fidelity && npm install)   # lottie-web for the fidelity tests; also needs Google Chrome (or set CHROME)
uv run pytest

To add a fidelity case: describe it in fidelity/make_comps.py, run uv run fidelity/make_comps.py, then render it with Resolve Studio open (python3 fidelity/render_in_resolve.py <name>).

License

MIT

Metadata

Release files for fusion2lottie 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fusion2lottie 0.1.0
File Size Uploaded Provenance
fusion2lottie-0.1.0.tar.gz 17.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for fusion2lottie 0.1.0
File Interpreter ABI Platform
fusion2lottie-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 37.6 kB

Release files / fusion2lottie-0.1.0.tar.gz

Download URL fusion2lottie-0.1.0.tar.gz
Size 17.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f4653217857a2fbb9f948825a7c72d5e039b28311b9061b4cdd81be900a56374
BLAKE2b-256 checksum
How to use checksums
fc1b1bf6c0c22cb7fafb8cdedcfffa5feef84da342d52f97f691513cec5f5da4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.3 {"installer":{"name":"uv","version":"0.13.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fusion2lottie-0.1.0-py3-none-any.whl

Download URL fusion2lottie-0.1.0-py3-none-any.whl
Size 20.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
71f669a85769ea0883f623216bd34cedfcbc6b422a2acd9275bc874b0a81e46c
BLAKE2b-256 checksum
How to use checksums
0c0bf640856ecc055925ee42e99adae9d4d5d8219f1b4217860f0bb5a6c91749
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.3 {"installer":{"name":"uv","version":"0.13.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for fusion2lottie 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page