[formatters] Dart formatting pass

This commit is contained in:
Mario Zechner 2025-07-16 03:20:14 +02:00
parent 440125252a
commit 81b445302a
15 changed files with 4391 additions and 7260 deletions

View File

@ -36,24 +36,28 @@ class AnimatedLogin extends StatelessWidget {
@override
Widget build(BuildContext context) {
reportLeaks();
final controller = SpineWidgetController(onInitialized: (controller) {
controller.skeleton.setSkinByName("nate");
controller.skeleton.setToSetupPose();
controller.animationState.setAnimationByName(0, "login/look-left-down", true);
});
final controller = SpineWidgetController(
onInitialized: (controller) {
controller.skeleton.setSkinByName("nate");
controller.skeleton.setToSetupPose();
controller.animationState.setAnimationByName(0, "login/look-left-down", true);
},
);
return Scaffold(
appBar: AppBar(title: const Text('Animated login')),
body: Container(
margin: const EdgeInsets.all(15.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: SpineWidget.fromAsset(
"assets/chibi/chibi-stickers.atlas",
"assets/chibi/chibi-stickers.skel",
controller,
boundsProvider: SkinAndAnimationBounds(skins: ["nate"], animation: "login/look-left-down"),
sizedByBounds: true,
)));
appBar: AppBar(title: const Text('Animated login')),
body: Container(
margin: const EdgeInsets.all(15.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: SpineWidget.fromAsset(
"assets/chibi/chibi-stickers.atlas",
"assets/chibi/chibi-stickers.skel",
controller,
boundsProvider: SkinAndAnimationBounds(skins: ["nate"], animation: "login/look-left-down"),
sizedByBounds: true,
),
),
);
}
}

View File

@ -8,32 +8,38 @@ class AnimationStateEvents extends StatelessWidget {
@override
Widget build(BuildContext context) {
reportLeaks();
final controller = SpineWidgetController(onInitialized: (controller) {
controller.skeleton.setScaleX(0.5);
controller.skeleton.setScaleY(0.5);
controller.skeleton.findSlot("gun")?.setColor(Color(1, 0, 0, 1));
controller.animationStateData.setDefaultMix(0.2);
controller.animationState.setAnimationByName(0, "walk", true).setListener((type, trackEntry, event) {
print("Walk animation event $type");
});
controller.animationState.addAnimationByName(0, "jump", false, 2);
controller.animationState.addAnimationByName(0, "run", true, 0).setListener((type, trackEntry, event) {
print("Run animation event $type");
});
controller.animationState.setListener((type, trackEntry, event) {
if (type == EventType.event) {
print(
"User event: { name: ${event?.getData().getName()}, intValue: ${event?.getIntValue()}, floatValue: ${event?.getFloatValue()}, stringValue: ${event?.getStringValue()} }");
}
});
print("Current: ${controller.animationState.getCurrent(0)?.getAnimation().getName()}");
});
final controller = SpineWidgetController(
onInitialized: (controller) {
controller.skeleton.setScaleX(0.5);
controller.skeleton.setScaleY(0.5);
controller.skeleton.findSlot("gun")?.setColor(Color(1, 0, 0, 1));
controller.animationStateData.setDefaultMix(0.2);
controller.animationState.setAnimationByName(0, "walk", true).setListener((type, trackEntry, event) {
print("Walk animation event $type");
});
controller.animationState.addAnimationByName(0, "jump", false, 2);
controller.animationState.addAnimationByName(0, "run", true, 0).setListener((type, trackEntry, event) {
print("Run animation event $type");
});
controller.animationState.setListener((type, trackEntry, event) {
if (type == EventType.event) {
print(
"User event: { name: ${event?.getData().getName()}, intValue: ${event?.getIntValue()}, floatValue: ${event?.getFloatValue()}, stringValue: ${event?.getStringValue()} }",
);
}
});
print("Current: ${controller.animationState.getCurrent(0)?.getAnimation().getName()}");
},
);
return Scaffold(
appBar: AppBar(title: const Text('Animation State Listener')),
body: Column(children: [
appBar: AppBar(title: const Text('Animation State Listener')),
body: Column(
children: [
const Text("See output in console!"),
Expanded(child: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller))
]));
Expanded(child: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller)),
],
),
);
}
}

View File

@ -38,36 +38,40 @@ class DebugRendering extends StatelessWidget {
reportLeaks();
const debugRenderer = DebugRenderer();
final controller = SpineWidgetController(onInitialized: (controller) {
controller.animationState.setAnimationByName(0, "walk", true);
}, onBeforePaint: (controller, canvas) {
// Save the current transform and other canvas state
canvas.save();
final controller = SpineWidgetController(
onInitialized: (controller) {
controller.animationState.setAnimationByName(0, "walk", true);
},
onBeforePaint: (controller, canvas) {
// Save the current transform and other canvas state
canvas.save();
// Get the current canvas transform an invert it, so we can work in the
// canvas coordinate system.
final currentMatrix = canvas.getTransform();
final invertedMatrix = Matrix4.tryInvert(Matrix4.fromFloat64List(currentMatrix));
if (invertedMatrix != null) {
canvas.transform(invertedMatrix.storage);
}
// Get the current canvas transform an invert it, so we can work in the
// canvas coordinate system.
final currentMatrix = canvas.getTransform();
final invertedMatrix = Matrix4.tryInvert(Matrix4.fromFloat64List(currentMatrix));
if (invertedMatrix != null) {
canvas.transform(invertedMatrix.storage);
}
// Draw something.
final Paint paint = Paint()
..color = Colors.black
..strokeWidth = 2.0;
// Draw something.
final Paint paint = Paint()
..color = Colors.black
..strokeWidth = 2.0;
canvas.drawLine(
Offset(0, 0),
Offset(canvas.getLocalClipBounds().width, canvas.getLocalClipBounds().height),
paint,
);
canvas.drawLine(
Offset(0, 0),
Offset(canvas.getLocalClipBounds().width, canvas.getLocalClipBounds().height),
paint,
);
// Restore the old transform and canvas state
canvas.restore();
}, onAfterPaint: (controller, canvas, commands) {
debugRenderer.render(controller.drawable, canvas, commands);
});
// Restore the old transform and canvas state
canvas.restore();
},
onAfterPaint: (controller, canvas, commands) {
debugRenderer.render(controller.drawable, canvas, commands);
},
);
return Scaffold(
appBar: AppBar(title: const Text('Debug Renderer')),

View File

@ -84,23 +84,26 @@ class DressUpState extends State<DressUp> {
@override
Widget build(BuildContext context) {
final controller = SpineWidgetController(onInitialized: (controller) {
controller.animationState.setAnimationByName(0, "dance", true);
});
final controller = SpineWidgetController(
onInitialized: (controller) {
controller.animationState.setAnimationByName(0, "dance", true);
},
);
return Scaffold(
appBar: AppBar(title: const Text('Dress Up')),
body: _skinImages.isEmpty
? const SizedBox()
: Row(children: [
appBar: AppBar(title: const Text('Dress Up')),
body: _skinImages.isEmpty
? const SizedBox()
: Row(
children: [
SizedBox(
width: thumbnailSize,
child: ListView(
children: _skinImages.keys.map((skinName) {
var rawImageData = _skinImages[skinName]!;
var image = Image(image: RawImageProvider(rawImageData));
var box = SizedBox(width: 200, height: 200, child: image);
return GestureDetector(
children: _skinImages.keys.map((skinName) {
var rawImageData = _skinImages[skinName]!;
var image = Image(image: RawImageProvider(rawImageData));
var box = SizedBox(width: 200, height: 200, child: image);
return GestureDetector(
onTap: () {
_toggleSkin(skinName);
setState(() {});
@ -114,16 +117,22 @@ class DressUpState extends State<DressUp> {
color: Colors.grey,
backgroundBlendMode: painting.BlendMode.saturation,
),
child: box));
}).toList()),
child: box,
),
);
}).toList(),
),
),
Expanded(
child: SpineWidget.fromDrawable(
_drawable,
controller,
boundsProvider: SkinAndAnimationBounds(skins: ["full-skins/girl"]),
))
]));
child: SpineWidget.fromDrawable(
_drawable,
controller,
boundsProvider: SkinAndAnimationBounds(skins: ["full-skins/girl"]),
),
),
],
),
);
}
@override

View File

@ -50,8 +50,8 @@ class SpineComponent extends PositionComponent {
Anchor super.anchor = Anchor.topLeft,
super.children,
super.priority,
}) : _ownsDrawable = ownsDrawable,
_boundsProvider = boundsProvider {
}) : _ownsDrawable = ownsDrawable,
_boundsProvider = boundsProvider {
_drawable.update(0);
_bounds = _boundsProvider.computeBounds(_drawable);
size = Vector2(_bounds.width, _bounds.height);
@ -69,15 +69,17 @@ class SpineComponent extends PositionComponent {
Iterable<Component>? children,
int? priority,
}) async {
return SpineComponent(await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle),
ownsDrawable: true,
boundsProvider: boundsProvider,
position: position,
scale: scale,
angle: angle,
anchor: anchor,
children: children,
priority: priority);
return SpineComponent(
await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle),
ownsDrawable: true,
boundsProvider: boundsProvider,
position: position,
scale: scale,
angle: angle,
anchor: anchor,
children: children,
priority: priority,
);
}
void dispose() {
@ -114,8 +116,13 @@ class SimpleFlameExample extends FlameGame {
// Load the Spineboy atlas and skeleton data from asset files
// and create a SpineComponent from them, scaled down and
// centered on the screen
spineboy = await SpineComponent.fromAssets("assets/spineboy.atlas", "assets/spineboy-pro.json",
scale: Vector2(0.4, 0.4), anchor: Anchor.center, position: Vector2(size.x / 2, size.y / 2));
spineboy = await SpineComponent.fromAssets(
"assets/spineboy.atlas",
"assets/spineboy-pro.json",
scale: Vector2(0.4, 0.4),
anchor: Anchor.center,
position: Vector2(size.x / 2, size.y / 2),
);
// Set the "walk" animation on track 0 in looping mode
spineboy.animationState.setAnimationByName(0, "walk", true);
@ -205,6 +212,9 @@ class SpineFlameGameWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: const Text('Flame Integration')), body: GameWidget(game: game));
return Scaffold(
appBar: AppBar(title: const Text('Flame Integration')),
body: GameWidget(game: game),
);
}
}

View File

@ -45,19 +45,22 @@ class IkFollowingState extends State<IkFollowing> {
void initState() {
super.initState();
controller = SpineWidgetController(onInitialized: (controller) {
// Set the walk animation on track 0, let it loop
controller.animationState.setAnimationByName(0, "walk", true);
controller.animationState.setAnimationByName(1, "aim", true);
}, onAfterUpdateWorldTransforms: (controller) {
final worldPosition = crossHairPosition;
if (worldPosition == null) return;
final bone = controller.skeleton.findBone("crosshair")!;
final parent = bone.getParent()!;
final position = parent.worldToLocal(worldPosition.dx, worldPosition.dy);
bone.setX(position.x);
bone.setY(position.y);
});
controller = SpineWidgetController(
onInitialized: (controller) {
// Set the walk animation on track 0, let it loop
controller.animationState.setAnimationByName(0, "walk", true);
controller.animationState.setAnimationByName(1, "aim", true);
},
onAfterUpdateWorldTransforms: (controller) {
final worldPosition = crossHairPosition;
if (worldPosition == null) return;
final bone = controller.skeleton.findBone("crosshair")!;
final parent = bone.getParent()!;
final position = parent.worldToLocal(worldPosition.dx, worldPosition.dy);
bone.setX(position.x);
bone.setY(position.y);
},
);
}
void _updateBonePosition(Offset position) {
@ -69,16 +72,17 @@ class IkFollowingState extends State<IkFollowing> {
reportLeaks();
return Scaffold(
appBar: AppBar(title: const Text('IK Following')),
body: GestureDetector(
onPanDown: (drag) => _updateBonePosition(drag.localPosition),
onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
child: SpineWidget.fromAsset(
"assets/spineboy.atlas",
"assets/spineboy-pro.skel",
controller,
alignment: Alignment.centerLeft,
),
));
appBar: AppBar(title: const Text('IK Following')),
body: GestureDetector(
onPanDown: (drag) => _updateBonePosition(drag.localPosition),
onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
child: SpineWidget.fromAsset(
"assets/spineboy.atlas",
"assets/spineboy-pro.skel",
controller,
alignment: Alignment.centerLeft,
),
),
);
}
}

View File

@ -46,130 +46,96 @@ class ExampleSelector extends StatelessWidget {
Widget build(BuildContext context) {
const spacer = SizedBox(height: 10);
return Scaffold(
appBar: AppBar(title: const Text('Spine Examples')),
body: Center(
child: Column(mainAxisSize: MainAxisSize.min, children: [
ElevatedButton(
child: const Text('Simple Animation'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const SimpleAnimation(),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Pause/Play animation'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const PlayPauseAnimation(),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Animation State Listener'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const AnimationStateEvents(),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Debug Rendering'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const DebugRendering(),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Dress Up'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const DressUp(),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('IK Following'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const IkFollowing(),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Physics'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const PhysicsTest(),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Flame: Simple Example'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => SpineFlameGameWidget(SimpleFlameExample()),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Flame: Pre-load and share Spine data'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => SpineFlameGameWidget(PreloadAndShareSpineDataExample()),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Flame: Dragon Example'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => SpineFlameGameWidget(DragonExample()),
),
);
},
),
spacer,
])));
appBar: AppBar(title: const Text('Spine Examples')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
child: const Text('Simple Animation'),
onPressed: () {
Navigator.push(context, MaterialPageRoute<void>(builder: (context) => const SimpleAnimation()));
},
),
spacer,
ElevatedButton(
child: const Text('Pause/Play animation'),
onPressed: () {
Navigator.push(context, MaterialPageRoute<void>(builder: (context) => const PlayPauseAnimation()));
},
),
spacer,
ElevatedButton(
child: const Text('Animation State Listener'),
onPressed: () {
Navigator.push(context, MaterialPageRoute<void>(builder: (context) => const AnimationStateEvents()));
},
),
spacer,
ElevatedButton(
child: const Text('Debug Rendering'),
onPressed: () {
Navigator.push(context, MaterialPageRoute<void>(builder: (context) => const DebugRendering()));
},
),
spacer,
ElevatedButton(
child: const Text('Dress Up'),
onPressed: () {
Navigator.push(context, MaterialPageRoute<void>(builder: (context) => const DressUp()));
},
),
spacer,
ElevatedButton(
child: const Text('IK Following'),
onPressed: () {
Navigator.push(context, MaterialPageRoute<void>(builder: (context) => const IkFollowing()));
},
),
spacer,
ElevatedButton(
child: const Text('Physics'),
onPressed: () {
Navigator.push(context, MaterialPageRoute<void>(builder: (context) => const PhysicsTest()));
},
),
spacer,
ElevatedButton(
child: const Text('Flame: Simple Example'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(builder: (context) => SpineFlameGameWidget(SimpleFlameExample())),
);
},
),
spacer,
ElevatedButton(
child: const Text('Flame: Pre-load and share Spine data'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => SpineFlameGameWidget(PreloadAndShareSpineDataExample()),
),
);
},
),
spacer,
ElevatedButton(
child: const Text('Flame: Dragon Example'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<void>(builder: (context) => SpineFlameGameWidget(DragonExample())),
);
},
),
spacer,
],
),
),
);
}
}

View File

@ -43,9 +43,11 @@ class PlayPauseAnimationState extends State<PlayPauseAnimation> {
@override
void initState() {
super.initState();
controller = SpineWidgetController(onInitialized: (controller) {
controller.animationState.setAnimationByName(0, "flying", true);
});
controller = SpineWidgetController(
onInitialized: (controller) {
controller.animationState.setAnimationByName(0, "flying", true);
},
);
}
void _togglePlay() {

View File

@ -46,26 +46,29 @@ class PhysicsState extends State<PhysicsTest> {
void initState() {
super.initState();
controller = SpineWidgetController(onInitialized: (controller) {
controller.animationState.setAnimationByName(0, "eyeblink-long", true);
controller.animationState.setAnimationByName(1, "wings-and-feet", true);
}, onAfterUpdateWorldTransforms: (controller) {
if (lastMousePosition == null) {
lastMousePosition = mousePosition;
return;
}
if (mousePosition == null) {
return;
}
controller = SpineWidgetController(
onInitialized: (controller) {
controller.animationState.setAnimationByName(0, "eyeblink-long", true);
controller.animationState.setAnimationByName(1, "wings-and-feet", true);
},
onAfterUpdateWorldTransforms: (controller) {
if (lastMousePosition == null) {
lastMousePosition = mousePosition;
return;
}
if (mousePosition == null) {
return;
}
final dx = mousePosition!.dx - lastMousePosition!.dx;
final dy = mousePosition!.dy - lastMousePosition!.dy;
final position = controller.skeleton.getPosition();
position.x += dx;
position.y += dy;
controller.skeleton.setPosition(position.x, position.y);
lastMousePosition = mousePosition;
});
final dx = mousePosition!.dx - lastMousePosition!.dx;
final dy = mousePosition!.dy - lastMousePosition!.dy;
final position = controller.skeleton.getPosition();
position.x += dx;
position.y += dy;
controller.skeleton.setPosition(position.x, position.y);
lastMousePosition = mousePosition;
},
);
}
void _updateBonePosition(Offset position) {
@ -77,11 +80,12 @@ class PhysicsState extends State<PhysicsTest> {
reportLeaks();
return Scaffold(
appBar: AppBar(title: const Text('Physics (drag anywhere)')),
body: GestureDetector(
onPanDown: (drag) => _updateBonePosition(drag.localPosition),
onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
child: SpineWidget.fromAsset("assets/celestial-circus.atlas", "assets/celestial-circus-pro.skel", controller),
));
appBar: AppBar(title: const Text('Physics (drag anywhere)')),
body: GestureDetector(
onPanDown: (drag) => _updateBonePosition(drag.localPosition),
onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
child: SpineWidget.fromAsset("assets/celestial-circus.atlas", "assets/celestial-circus-pro.skel", controller),
),
);
}
}

View File

@ -36,17 +36,20 @@ class SimpleAnimation extends StatelessWidget {
@override
Widget build(BuildContext context) {
reportLeaks();
final controller = SpineWidgetController(onInitialized: (controller) {
// Set the default mixing time between animations
controller.animationState.getData().setDefaultMix(0.2);
// Set the portal animation on track 0
controller.animationState.setAnimationByName(0, "portal", true);
// Queue the run animation after the portal animation
controller.animationState.addAnimationByName(0, "run", true, 0);
});
final controller = SpineWidgetController(
onInitialized: (controller) {
// Set the default mixing time between animations
controller.animationState.getData().setDefaultMix(0.2);
// Set the portal animation on track 0
controller.animationState.setAnimationByName(0, "portal", true);
// Queue the run animation after the portal animation
controller.animationState.addAnimationByName(0, "run", true, 0);
},
);
return Scaffold(
appBar: AppBar(title: const Text('Simple Animation')),
body: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller));
appBar: AppBar(title: const Text('Simple Animation')),
body: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
);
}
}

View File

@ -91,8 +91,9 @@ Future<SpineFlutterFFI> initSpineFlutterFFI(bool useStaticLinkage) async {
registerOpaqueType<spine_skin_entries_wrapper>();
await js.importLibrary('assets/packages/spine_flutter/lib/assets/libspine_flutter.js');
Uint8List wasmBinaries =
(await rootBundle.load('packages/spine_flutter/lib/assets/libspine_flutter.wasm')).buffer.asUint8List();
Uint8List wasmBinaries = (await rootBundle.load(
'packages/spine_flutter/lib/assets/libspine_flutter.wasm',
)).buffer.asUint8List();
_module = await EmscriptenModule.compile(wasmBinaries, 'libspine_flutter');
}
Module? m = _module;

View File

@ -32,12 +32,7 @@ class RawImageProvider extends ImageProvider<_RawImageKey> {
final double? scale;
final int? targetWidth;
final int? targetHeight;
RawImageProvider(
this.image, {
this.scale = 1.0,
this.targetWidth,
this.targetHeight,
});
RawImageProvider(this.image, {this.scale = 1.0, this.targetWidth, this.targetHeight});
@override
ImageStreamCompleter loadImage(_RawImageKey key, ImageDecoderCallback decode) {
@ -104,12 +99,7 @@ class RawImageData {
final int height;
final ui.PixelFormat pixelFormat;
RawImageData(
this.pixels,
this.width,
this.height, {
this.pixelFormat = ui.PixelFormat.rgba8888,
});
RawImageData(this.pixels, this.width, this.height, {this.pixelFormat = ui.PixelFormat.rgba8888});
_RawImageKey? _key;
_RawImageKey _obtainKey() {

View File

@ -136,8 +136,13 @@ class Atlas {
Map<BlendMode, Paint> paints = {};
for (final blendMode in BlendMode.values) {
paints[blendMode] = Paint()
..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage,
filterQuality: Atlas.filterQuality)
..shader = ImageShader(
image,
TileMode.clamp,
TileMode.clamp,
Matrix4.identity().storage,
filterQuality: Atlas.filterQuality,
)
..isAntiAlias = true
..blendMode = blendMode.canvasBlendMode;
}
@ -745,8 +750,12 @@ class BoneData {
/// rendered at runtime.
Color getColor() {
final color = _bindings.spine_bone_data_get_color(_data);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(double r, double g, double b, double a) {
@ -796,7 +805,14 @@ class Bone {
/// See [World transform](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
/// Runtimes Guide.
void updateWorldTransformWith(
double x, double y, double rotation, double scaleX, double scaleY, double shearX, double shearY) {
double x,
double y,
double rotation,
double scaleX,
double scaleY,
double shearX,
double shearY,
) {
_bindings.spine_bone_update_world_transform_with(_bone, x, y, rotation, scaleX, scaleY, shearX, shearY);
}
@ -1122,8 +1138,12 @@ class SlotData {
/// color tinting.
Color getColor() {
final color = _bindings.spine_slot_data_get_color(_data);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(double r, double g, double b, double a) {
@ -1134,8 +1154,12 @@ class SlotData {
/// color's alpha is not used.
Color getDarkColor() {
final color = _bindings.spine_slot_data_get_dark_color(_data);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setDarkColor(double r, double g, double b, double a) {
@ -1210,8 +1234,12 @@ class Slot {
/// color tinting.
Color getColor() {
final color = _bindings.spine_slot_get_color(_slot);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(Color color) {
@ -1222,8 +1250,12 @@ class Slot {
/// color's alpha is not used.
Color getDarkColor() {
final color = _bindings.spine_slot_get_dark_color(_slot);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setDarkColor(Color color) {
@ -1573,8 +1605,12 @@ class RegionAttachment extends Attachment<spine_region_attachment> {
Color getColor() {
final color = _bindings.spine_region_attachment_get_color(_attachment);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(double r, double g, double b, double a) {
@ -1661,7 +1697,9 @@ class VertexAttachment<T extends Pointer> extends Attachment<T> {
void setTimelineAttachment(Attachment? attachment) {
_bindings.spine_vertex_attachment_set_timeline_attachment(
_attachment.cast(), attachment == null ? nullptr : attachment._attachment.cast());
_attachment.cast(),
attachment == null ? nullptr : attachment._attachment.cast(),
);
}
}
@ -1712,8 +1750,12 @@ class MeshAttachment extends VertexAttachment<spine_mesh_attachment> {
Color getColor() {
final color = _bindings.spine_mesh_attachment_get_color(_attachment);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(double r, double g, double b, double a) {
@ -1797,8 +1839,12 @@ class ClippingAttachment extends VertexAttachment<spine_clipping_attachment> {
/// attachments are not usually rendered at runtime.
Color getColor() {
final color = _bindings.spine_clipping_attachment_get_color(_attachment);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(double r, double g, double b, double a) {
@ -1818,8 +1864,12 @@ class BoundingBoxAttachment extends VertexAttachment<spine_bounding_box_attachme
/// are not usually rendered at runtime.
Color getColor() {
final color = _bindings.spine_bounding_box_attachment_get_color(_attachment);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(double r, double g, double b, double a) {
@ -1863,8 +1913,12 @@ class PathAttachment extends VertexAttachment<spine_path_attachment> {
/// rendered at runtime.
Color getColor() {
final color = _bindings.spine_path_attachment_get_color(_attachment);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(double r, double g, double b, double a) {
@ -1918,8 +1972,12 @@ class PointAttachment extends Attachment<spine_point_attachment> {
/// attachments are not usually rendered at runtime.
Color getColor() {
final color = _bindings.spine_point_attachment_get_color(_attachment);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(double r, double g, double b, double a) {
@ -1968,7 +2026,11 @@ class Skin {
void setAttachment(int slotIndex, String name, Attachment? attachment) {
final nativeName = name.toNativeUtf8(allocator: _allocator);
_bindings.spine_skin_set_attachment(
_skin, slotIndex, nativeName.cast(), attachment == null ? nullptr : attachment._attachment.cast());
_skin,
slotIndex,
nativeName.cast(),
attachment == null ? nullptr : attachment._attachment.cast(),
);
_allocator.free(nativeName);
}
@ -2007,12 +2069,15 @@ class Skin {
for (int i = 0; i < numEntries; i++) {
final entry = _bindings.spine_skin_entries_get_entry(entries, i);
Pointer<Utf8> name = _bindings.spine_skin_entry_get_name(entry).cast();
result.add(SkinEntry(
result.add(
SkinEntry(
_bindings.spine_skin_entry_get_slot_index(entry),
name.toDartString(),
_bindings.spine_skin_entry_get_attachment(entry).address == nullptr.address
? null
: Attachment._toSubclass(_bindings.spine_skin_entry_get_attachment(entry))));
: Attachment._toSubclass(_bindings.spine_skin_entry_get_attachment(entry)),
),
);
}
return result;
}
@ -2836,8 +2901,11 @@ class Skeleton {
Attachment? getAttachmentByName(String slotName, String attachmentName) {
final slotNameNative = slotName.toNativeUtf8(allocator: _allocator);
final attachmentNameNative = attachmentName.toNativeUtf8(allocator: _allocator);
final attachment =
_bindings.spine_skeleton_get_attachment_by_name(_skeleton, slotNameNative.cast(), attachmentNameNative.cast());
final attachment = _bindings.spine_skeleton_get_attachment_by_name(
_skeleton,
slotNameNative.cast(),
attachmentNameNative.cast(),
);
_allocator.free(slotNameNative);
_allocator.free(attachmentNameNative);
if (attachment.address == nullptr.address) return null;
@ -2899,8 +2967,12 @@ class Skeleton {
/// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
Bounds getBounds() {
final nativeBounds = _bindings.spine_skeleton_get_bounds(_skeleton);
final bounds = Bounds(_bindings.spine_bounds_get_x(nativeBounds), _bindings.spine_bounds_get_y(nativeBounds),
_bindings.spine_bounds_get_width(nativeBounds), _bindings.spine_bounds_get_height(nativeBounds));
final bounds = Bounds(
_bindings.spine_bounds_get_x(nativeBounds),
_bindings.spine_bounds_get_y(nativeBounds),
_bindings.spine_bounds_get_width(nativeBounds),
_bindings.spine_bounds_get_height(nativeBounds),
);
return bounds;
}
@ -2994,8 +3066,12 @@ class Skeleton {
/// The color to tint all the skeleton's attachments.
Color getColor() {
final color = _bindings.spine_skeleton_get_color(_skeleton);
return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color), _bindings.spine_color_get_a(color));
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color),
);
}
void setColor(Color color) {
@ -3509,7 +3585,7 @@ enum EventType {
///
/// Because this event is triggered at the end of [AnimationState.apply], any animations set in response to
/// the event won't be applied until the next time the [AnimationState] is applied.
event
event,
}
/// Stores the setup pose values for an [Event].
@ -3802,8 +3878,12 @@ class AnimationState {
/// See [setAnimation].
TrackEntry setAnimationByName(int trackIndex, String animationName, bool loop) {
final animation = animationName.toNativeUtf8(allocator: _allocator);
final entry =
_bindings.spine_animation_state_set_animation_by_name(_state, trackIndex, animation.cast(), loop ? -1 : 0);
final entry = _bindings.spine_animation_state_set_animation_by_name(
_state,
trackIndex,
animation.cast(),
loop ? -1 : 0,
);
_allocator.free(animation);
if (entry.address == nullptr.address) throw Exception("Couldn't set animation $animationName");
return TrackEntry._(entry, this);
@ -3818,8 +3898,12 @@ class AnimationState {
/// Returns a track entry to allow further customization of animation playback. References to the track entry must not be kept
/// after the [EventType.dispose] event occurs.
TrackEntry setAnimation(int trackIndex, Animation animation, bool loop) {
final entry =
_bindings.spine_animation_state_set_animation(_state, trackIndex, animation._animation, loop ? -1 : 0);
final entry = _bindings.spine_animation_state_set_animation(
_state,
trackIndex,
animation._animation,
loop ? -1 : 0,
);
if (entry.address == nullptr.address) throw Exception("Couldn't set animation ${animation.getName()}");
return TrackEntry._(entry, this);
}
@ -3830,7 +3914,12 @@ class AnimationState {
TrackEntry addAnimationByName(int trackIndex, String animationName, bool loop, double delay) {
final animation = animationName.toNativeUtf8(allocator: _allocator);
final entry = _bindings.spine_animation_state_add_animation_by_name(
_state, trackIndex, animation.cast(), loop ? -1 : 0, delay);
_state,
trackIndex,
animation.cast(),
loop ? -1 : 0,
delay,
);
_allocator.free(animation);
if (entry.address == nullptr.address) throw Exception("Couldn't add animation $animationName");
return TrackEntry._(entry, this);
@ -3847,8 +3936,13 @@ class AnimationState {
/// Returns a track entry to allow further customization of animation playback. References to the track entry must not be kept
/// after the [EventType.dispose] event occurs.
TrackEntry addAnimation(int trackIndex, Animation animation, bool loop, double delay) {
final entry =
_bindings.spine_animation_state_add_animation(_state, trackIndex, animation._animation, loop ? -1 : 0, delay);
final entry = _bindings.spine_animation_state_add_animation(
_state,
trackIndex,
animation._animation,
loop ? -1 : 0,
delay,
);
if (entry.address == nullptr.address) throw Exception("Couldn't add animation ${animation.getName()}");
return TrackEntry._(entry, this);
}
@ -3971,8 +4065,10 @@ class SkeletonDrawable {
_drawable = _bindings.spine_skeleton_drawable_create(skeletonData._data);
skeleton = Skeleton._(_bindings.spine_skeleton_drawable_get_skeleton(_drawable));
animationStateData = AnimationStateData._(_bindings.spine_skeleton_drawable_get_animation_state_data(_drawable));
animationState = AnimationState._(_bindings.spine_skeleton_drawable_get_animation_state(_drawable),
_bindings.spine_skeleton_drawable_get_animation_state_events(_drawable));
animationState = AnimationState._(
_bindings.spine_skeleton_drawable_get_animation_state(_drawable),
_bindings.spine_skeleton_drawable_get_animation_state_events(_drawable),
);
skeleton.updateWorldTransform(Physics.none);
}
@ -4036,7 +4132,10 @@ class SkeletonDrawable {
var commands = render();
for (final cmd in commands) {
canvas.drawVertices(
cmd.vertices, rendering.BlendMode.modulate, atlas.atlasPagePaints[cmd.atlasPageIndex][cmd.blendMode]!);
cmd.vertices,
rendering.BlendMode.modulate,
atlas.atlasPagePaints[cmd.atlasPageIndex][cmd.blendMode]!,
);
}
return commands;
}
@ -4076,10 +4175,10 @@ class SkeletonDrawable {
/// Scales and centers the skeleton to fit the within the bounds of [width] and [height].
Future<RawImageData> renderToRawImageData(double width, double height, int bgColor) async {
final recorder = renderToPictureRecorder(width, height, bgColor);
var rawImageData = (await (await recorder.endRecording().toImage(width.toInt(), height.toInt()))
.toByteData(format: ImageByteFormat.rawRgba))!
.buffer
.asUint8List();
var rawImageData = (await (await recorder.endRecording().toImage(
width.toInt(),
height.toInt(),
)).toByteData(format: ImageByteFormat.rawRgba))!.buffer.asUint8List();
return RawImageData(rawImageData, width.toInt(), height.toInt());
}
@ -4141,8 +4240,13 @@ class RenderCommand {
if (colors.isNotEmpty && colors[0] == -1) {
vertices = Vertices.raw(VertexMode.triangles, positions, textureCoordinates: uvs, indices: indices);
} else {
vertices =
Vertices.raw(VertexMode.triangles, positions, textureCoordinates: uvs, colors: colors, indices: indices);
vertices = Vertices.raw(
VertexMode.triangles,
positions,
textureCoordinates: uvs,
colors: colors,
indices: indices,
);
}
} else {
// On the web, rendering is done through CanvasKit, which requires copies of the native data.
@ -4150,8 +4254,13 @@ class RenderCommand {
final uvsCopy = Float32List.fromList(uvs);
final colorsCopy = Int32List.fromList(colors);
final indicesCopy = Uint16List.fromList(indices);
vertices = Vertices.raw(VertexMode.triangles, positionsCopy,
textureCoordinates: uvsCopy, colors: colorsCopy, indices: indicesCopy);
vertices = Vertices.raw(
VertexMode.triangles,
positionsCopy,
textureCoordinates: uvsCopy,
colors: colorsCopy,
indices: indicesCopy,
);
}
}
}
@ -4167,7 +4276,9 @@ class DebugRenderer {
..style = PaintingStyle.fill;
for (final bone in drawable.skeleton.getBones()) {
canvas.drawRect(
Rect.fromCenter(center: Offset(bone.getWorldX(), bone.getWorldY()), width: 5, height: 5), bonePaint);
Rect.fromCenter(center: Offset(bone.getWorldX(), bone.getWorldY()), width: 5, height: 5),
bonePaint,
);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -74,12 +74,13 @@ class SpineWidgetController {
/// Constructs a new [SpineWidget] controller. See the class documentation of [SpineWidgetController] for information on
/// the optional arguments.
SpineWidgetController(
{this.onInitialized,
this.onBeforeUpdateWorldTransforms,
this.onAfterUpdateWorldTransforms,
this.onBeforePaint,
this.onAfterPaint});
SpineWidgetController({
this.onInitialized,
this.onBeforeUpdateWorldTransforms,
this.onAfterUpdateWorldTransforms,
this.onBeforePaint,
this.onAfterPaint,
});
void _initialize(SkeletonDrawable drawable) {
var wasInitialized = _drawable != null;
@ -207,7 +208,7 @@ class SkinAndAnimationBounds extends BoundsProvider {
/// The [stepTime], given in seconds, defines at what interval the bounds should be sampled
/// across the entire animation.
SkinAndAnimationBounds({List<String>? skins, this.animation, this.stepTime = 0.1})
: skins = skins == null || skins.isEmpty ? ["default"] : skins;
: skins = skins == null || skins.isEmpty ? ["default"] : skins;
@override
Bounds computeBounds(SkeletonDrawable drawable) {
@ -286,20 +287,23 @@ class SpineWidget extends StatefulWidget {
/// are used.
///
/// The widget can optionally by sized by the bounds provided by the [BoundsProvider] by passing `true` for [sizedByBounds].
SpineWidget.fromAsset(this._atlasFile, this._skeletonFile, this._controller,
{AssetBundle? bundle,
BoxFit? fit,
Alignment? alignment,
BoundsProvider? boundsProvider,
bool? sizedByBounds,
super.key})
: _assetType = _AssetType.asset,
_fit = fit ?? BoxFit.contain,
_alignment = alignment ?? Alignment.center,
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
_sizedByBounds = sizedByBounds ?? false,
_drawable = null,
_bundle = bundle ?? rootBundle;
SpineWidget.fromAsset(
this._atlasFile,
this._skeletonFile,
this._controller, {
AssetBundle? bundle,
BoxFit? fit,
Alignment? alignment,
BoundsProvider? boundsProvider,
bool? sizedByBounds,
super.key,
}) : _assetType = _AssetType.asset,
_fit = fit ?? BoxFit.contain,
_alignment = alignment ?? Alignment.center,
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
_sizedByBounds = sizedByBounds ?? false,
_drawable = null,
_bundle = bundle ?? rootBundle;
/// Constructs a new [SpineWidget] from files. The [_atlasFile] specifies the `.atlas` file to be loaded for the images used to render
/// the skeleton. The [_skeletonFile] specifies either a Skeleton `.json` or `.skel` file containing the skeleton data.
@ -312,15 +316,22 @@ class SpineWidget extends StatefulWidget {
/// are used.
///
/// The widget can optionally by sized by the bounds provided by the [BoundsProvider] by passing `true` for [sizedByBounds].
const SpineWidget.fromFile(this._atlasFile, this._skeletonFile, this._controller,
{BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
: _assetType = _AssetType.file,
_bundle = null,
_fit = fit ?? BoxFit.contain,
_alignment = alignment ?? Alignment.center,
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
_sizedByBounds = sizedByBounds ?? false,
_drawable = null;
const SpineWidget.fromFile(
this._atlasFile,
this._skeletonFile,
this._controller, {
BoxFit? fit,
Alignment? alignment,
BoundsProvider? boundsProvider,
bool? sizedByBounds,
super.key,
}) : _assetType = _AssetType.file,
_bundle = null,
_fit = fit ?? BoxFit.contain,
_alignment = alignment ?? Alignment.center,
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
_sizedByBounds = sizedByBounds ?? false,
_drawable = null;
/// Constructs a new [SpineWidget] from HTTP URLs. The [_atlasFile] specifies the `.atlas` file to be loaded for the images used to render
/// the skeleton. The [_skeletonFile] specifies either a Skeleton `.json` or `.skel` file containing the skeleton data.
@ -333,15 +344,22 @@ class SpineWidget extends StatefulWidget {
/// are used.
///
/// The widget can optionally by sized by the bounds provided by the [BoundsProvider] by passing `true` for [sizedByBounds].
const SpineWidget.fromHttp(this._atlasFile, this._skeletonFile, this._controller,
{BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
: _assetType = _AssetType.http,
_bundle = null,
_fit = fit ?? BoxFit.contain,
_alignment = alignment ?? Alignment.center,
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
_sizedByBounds = sizedByBounds ?? false,
_drawable = null;
const SpineWidget.fromHttp(
this._atlasFile,
this._skeletonFile,
this._controller, {
BoxFit? fit,
Alignment? alignment,
BoundsProvider? boundsProvider,
bool? sizedByBounds,
super.key,
}) : _assetType = _AssetType.http,
_bundle = null,
_fit = fit ?? BoxFit.contain,
_alignment = alignment ?? Alignment.center,
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
_sizedByBounds = sizedByBounds ?? false,
_drawable = null;
/// Constructs a new [SpineWidget] from a [SkeletonDrawable].
///
@ -353,16 +371,22 @@ class SpineWidget extends StatefulWidget {
/// are used.
///
/// The widget can optionally by sized by the bounds provided by the [BoundsProvider] by passing `true` for [sizedByBounds].
const SpineWidget.fromDrawable(this._drawable, this._controller,
{BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
: _assetType = _AssetType.drawable,
_bundle = null,
_fit = fit ?? BoxFit.contain,
_alignment = alignment ?? Alignment.center,
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
_sizedByBounds = sizedByBounds ?? false,
_skeletonFile = null,
_atlasFile = null;
const SpineWidget.fromDrawable(
this._drawable,
this._controller, {
BoxFit? fit,
Alignment? alignment,
BoundsProvider? boundsProvider,
bool? sizedByBounds,
super.key,
}) : _assetType = _AssetType.drawable,
_bundle = null,
_fit = fit ?? BoxFit.contain,
_alignment = alignment ?? Alignment.center,
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
_sizedByBounds = sizedByBounds ?? false,
_skeletonFile = null,
_atlasFile = null;
@override
State<SpineWidget> createState() => _SpineWidgetState();
@ -439,7 +463,13 @@ class _SpineWidgetState extends State<SpineWidget> {
Widget build(BuildContext context) {
if (_drawable != null) {
return _SpineRenderObjectWidget(
_drawable!, widget._controller, widget._fit, widget._alignment, _computedBounds, widget._sizedByBounds);
_drawable!,
widget._controller,
widget._fit,
widget._alignment,
_computedBounds,
widget._sizedByBounds,
);
} else {
return const SizedBox();
}
@ -461,7 +491,13 @@ class _SpineRenderObjectWidget extends LeafRenderObjectWidget {
final bool _sizedByBounds;
const _SpineRenderObjectWidget(
this._skeletonDrawable, this._controller, this._fit, this._alignment, this._bounds, this._sizedByBounds);
this._skeletonDrawable,
this._controller,
this._fit,
this._alignment,
this._bounds,
this._sizedByBounds,
);
@override
RenderObject createRenderObject(BuildContext context) {
@ -491,7 +527,13 @@ class _SpineRenderObject extends RenderBox {
bool _firstUpdated = false;
_SpineRenderObject(
this._skeletonDrawable, this._controller, this._fit, this._alignment, this._bounds, this._sizedByBounds);
this._skeletonDrawable,
this._controller,
this._fit,
this._alignment,
this._bounds,
this._sizedByBounds,
);
set skeletonDrawable(SkeletonDrawable skeletonDrawable) {
if (_skeletonDrawable == skeletonDrawable) return;