mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[formatters] Dart formatting pass
This commit is contained in:
parent
440125252a
commit
81b445302a
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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')),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user