Skip to main content

dragonbones 0.4.0 copy "dragonbones: ^0.4.0" to clipboard
dragonbones: ^0.4.0 copied to clipboard

Pure-Dart runtime for the DragonBones 5.x skeletal animation format: parses DragonBones Pro exports and evaluates armature, bone, mesh and IK timelines. Zero dependencies.

dragonbones #

A pure-Dart runtime for DragonBones skeletal animation (text/JSON format 5.x).

The defining property of this package is that it has zero dependencies — no Flutter, no platform channels, no third-party packages. That is not minimalism for its own sake:

  • it can be verified with a bare Dart SDK, with no GPU and no device, which is how the maths is proven correct (see Correctness);
  • it runs anywhere Dart runs, including the web and headless on a server;
  • it can back a Flutter renderer, a game engine's component, or your own Canvas code, without dragging a gameplay engine along.
import 'dart:convert';
import 'package:dragonbones/dragonbones.dart';

final factory = HeadlessFactory();
factory.parseDragonBonesData(jsonDecode(skeJson), 'Dragon');
factory.parseTextureAtlasData(jsonDecode(texJson), null, 'Dragon');

final armature = factory.buildArmature('Dragon', 'Dragon')!;
armature.animation.play('stand');
armature.advanceTime(1 / 24);

// Read back the frame as a framework-agnostic draw list.
for (final slot in armature.buildDrawList()) {
  print('${slot.name}: ${slot.matrix}');
}

HeadlessFactory is a concrete BaseFactory that binds no renderer at all. A real binding subclasses BaseFactory and Slot instead, and draws the displays — that is exactly what dragonbones_flutter does.

Correctness #

This is a faithful transcription of the upstream TypeScript runtime (DragonBonesJS) — but a transcription is a claim, not a proof, so it is diffed against the official runtime:

tool/parse_check.dart            structural: 1527 assertions over the parsed model
tool/check_against_oracle.dart   replays every fixture frame by frame and compares
                                 bone matrices, slot draw data, posed mesh vertices
                                 and nested-armature slots against dumps produced
                                 by the official runtime

Result on the current commit:

1353695 numeric comparisons over 56 assets (56 clean, 0 failing)
205259 mesh values, 1228 nested-armature slots
RESULT: PASS

~5e-7 is the rounding precision of the reference dumps themselves, so the port is effectively exact. Both scripts run in CI on every push.

The 56 assets are the hand-picked ladder (Dragon, 龙, mecha_1004d), the entire DragonBones Unity SDK demo set, and the feature fixtures — animated IK, Surface bones and animation blending. One of them (you_xin/body) is 71 frames, 70 bones, 6,816 slot draw data and 47,357 mesh values in a single asset; another (shizuku) has 117 Surface bones.

What is implemented #

  • geom: Matrix, Transform, Point, Rectangle, ColorTransform
  • model: the full 5.x data model — armature, bone, slot, skin, display, animation, timeline, texture atlas, user data, including mesh/geometry/weight data and constraints
  • parser: ObjectDataParser for the text/JSON format, including the packed binary frame arrays that format 5.5 embeds in the JSON
  • armature: Armature, Bone, Slot (render hooks left abstract), TransformObject, IKConstraint, Surface
  • animation: WorldClock, Animation, AnimationState and the timeline states — bone all/translate/rotate/scale, slot display/colour, action, z-order, deform (FFD), animated IK, Surface deformation, animation blending (AnimationProgress/Weight/Parameter), and alpha/z-index
  • events: EventObject and IEventDispatcher — frame events and sound events placed on the timeline, the start / loopComplete / complete / fadeIn / fadeOut lifecycle events, and gotoAndPlay actions, all dispatched (buffered) after the frame is posed
  • render: Armature.buildDrawList(), which flattens nested child armatures and emits the complete per-slot geometry a renderer needs

What is NOT implemented #

Each of these is parsed but not evaluated, so a file using it will load and mostly animate, then be subtly wrong rather than fail loudly.

  • Path constraints (PathConstraint) — data parsed, never built.
  • Binary .dragonbones input (BinaryDataParser) — JSON export only.

That is the whole list. Animated IK, Surface bones and animation blending were implemented in 0.4.0 and are verified against the official runtime.

Deviations from upstream (deliberate) #

  • No object pooling. Upstream implements a per-class pool (BaseObject.borrowObject). Dart's GC handles this, so objects are constructed directly. This is the single biggest structural difference from the reference implementation, and it has not been benchmarked.
  • JS array growth. Upstream grows arrays with list.length = n, which in JS creates holes. Dart cannot do that for non-nullable element types, so those sites were rewritten to append.
  • An upstream bug was NOT transcribed. Slot.set displayFrameCount, removal branch, reads for (let i = prevCount - 1; i < value; --i) — the condition is never true, so the upstream loop body never runs. The port uses i >= value so the removal actually happens.
  • Unused-member and redundant-cast lints are silenced in analysis_options.yaml, because a transcription keeps members a given milestone does not exercise yet.

See also #

Licence #

MIT. The DragonBones runtime and format are MIT (© DragonBones team and contributors).

0
likes
160
points
493
downloads

Documentation

Documentation
API reference

Publisher

verified publisherrafaelbarbosatec.com

Weekly Downloads

Pure-Dart runtime for the DragonBones 5.x skeletal animation format: parses DragonBones Pro exports and evaluates armature, bone, mesh and IK timelines. Zero dependencies.

Repository (GitHub)
View/report issues

Topics

#dragonbones #skeletal-animation #animation #gamedev

License

MIT (license)

More

Packages that depend on dragonbones