Anima

GitHub 769stars on GitHub

Anima is an add-on for the Godot Engine that makes it easier to author, compose and play UI motion. Anima 2.0 provides a concise API for individual nodes, groups and grids, plus a catalog of 99 reusable animation presets.

Problem

I wanted a more expressive, composable way to program animation in Godot. Complex animations should be easy to describe from small motions, applied to a node, a group of nodes or a grid. The same motion should be reusable across targets, and its playback should remain controllable after it starts.

Limits of existing approaches

Godot’s own animation tools work well for single animations. For this kind of orchestration they can become verbose:

  • Reusing an animation across a collection usually means managing targets, order and timing by hand.
  • Coordinating sequential and concurrent motion becomes harder as delays, reversing and interruptions accumulate.
  • Relationships between animations can end up hidden in callbacks and manual timing rather than expressed in the motion itself.
  • A running animation needs explicit lifecycle and conflict behaviour, not only a way to start a Tween.

Solution

Anima 2.0 is organised around the Anima façade rather than requiring callers to assemble runtime objects themselves. Anima.on(node) creates a motion for one target; Anima.item() describes the motion applied to each member of a collection; Anima.group(...) and Anima.grid(...) build and play those collection motions. The returned motions can be chained with then() for the next step or with() for a concurrent step, then played directly.

var motion = Anima.on($Card).fade_in(0.25) \
	.then(Anima.on($Card).move_by(Vector2(0, -24), 0.35))

motion.play()

Anima.group($CardRow) \
	.with_item_motion(Anima.item().opacity(1.0, 0.2)) \
	.play()

For a ready-made effect, Anima.animation("fade_in") returns a reusable preset that can be played on a target.

Key decisions

  • Convenience without a second model. The Anima.on, Anima.group and Anima.grid helpers produce the same motion types that can be composed and played through the runtime.
  • Groups and grids are first-class. A collection can resolve a container’s children or an explicit node array; grids add dimensions, start points and distance formulas for distribution.
  • Composition is fluent. then() expresses an ordered step, while with() adds a motion to the concurrent step.
  • Playback is an object. play() returns an AnimaPlayback, which can be paused, resumed, reversed, completed or cancelled.
  • Conflicts are deliberate. Per-property interruption policies make replacement, retargeting, reversal, queuing and other overlapping-motion outcomes explicit.
  • The catalog is ordinary motion. Each of the 99 presets is an AnimaMotion, so a preset follows the same playback and composition rules as a hand-authored motion.

Animation work for Godot

Anima is my work on animation for Godot. Its runnable Godot playgrounds demonstrate composition, convenience motions, groups, grids, layout transitions, motion interruption and the preset catalog. Playback controls expose behaviour such as pause, resume, reverse, speed, reduced motion and reset before the API is used in a project.

Available results

  • Anima 2.0 has a working runtime, node/group/grid convenience APIs, composition, playback control, interruption policies and runnable Godot examples.
  • The animation catalog currently contains 99 reusable presets.
  • The project includes playgrounds that make the runtime behaviour observable rather than relying solely on reference snippets.
  • There are no formal benchmarks against Godot’s native animation tools or other libraries, and no significant adoption figures yet.

Lessons learned

  • A good animation API is about composition and target selection, not only individual effects.
  • An API such as Anima.on, Anima.group and Anima.grid can make common authoring paths concise without introducing a separate runtime model.
  • Treating collections and grids as first-class concepts avoids manual orchestration of targets and distribution.
  • Playback control, reversal, interruption and reduced-motion handling belong in the architecture from the start.
  • Interactive playgrounds matter for an animation library because visible runtime behaviour communicates more than a reference page alone.