mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-11 17:48:45 +08:00
[flutter] Clean-up asset bundle constructors, add Flame integration examples.
This commit is contained in:
parent
6efb197776
commit
1c0a860139
@ -1,5 +1,10 @@
|
||||
# 0.0.4
|
||||
* Clean-up `fromAsset()` factory methods so the atlas comes before skeleton data file name.
|
||||
* Rename `Vector2` to `Vec2`.
|
||||
* Make the bundle configurable in `SpineWidget.asset()`.
|
||||
|
||||
# 0.0.3
|
||||
* Lower macOS deployment target to 10.11
|
||||
* Lower macOS deployment target to 10.11.
|
||||
|
||||
# 0.0.2
|
||||
* Fix package name in build system `spine_flutter` > `esotericsoftware_spine_flutter`.
|
||||
|
||||
@ -36,7 +36,7 @@ class AnimationStateEvents extends StatelessWidget {
|
||||
children: [
|
||||
const Text("See output in console!"),
|
||||
Expanded(
|
||||
child: SpineWidget.asset("assets/spineboy-pro.skel", "assets/spineboy.atlas", controller)
|
||||
child: SpineWidget.asset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller)
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
@ -4,6 +4,7 @@ import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/painting.dart' as painting;
|
||||
import 'package:esotericsoftware_spine_flutter/spine_flutter.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:raw_image_provider/raw_image_provider.dart';
|
||||
|
||||
class DressUp extends StatefulWidget {
|
||||
@ -25,7 +26,7 @@ class DressUpState extends State<DressUp> {
|
||||
void initState() {
|
||||
reportLeaks();
|
||||
super.initState();
|
||||
SkeletonDrawable.fromAsset("assets/mix-and-match-pro.skel", "assets/mix-and-match.atlas").then((drawable) async {
|
||||
SkeletonDrawable.fromAsset("assets/mix-and-match.atlas", "assets/mix-and-match-pro.skel").then((drawable) async {
|
||||
for (var skin in drawable.skeletonData.getSkins()) {
|
||||
if (skin.getName() == "default") continue;
|
||||
|
||||
|
||||
145
spine-flutter/example/lib/flame_example.dart
Normal file
145
spine-flutter/example/lib/flame_example.dart
Normal file
@ -0,0 +1,145 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:esotericsoftware_spine_flutter/spine_flutter.dart';
|
||||
|
||||
class SpineComponent extends PositionComponent {
|
||||
final BoundsProvider _boundsProvider;
|
||||
final SkeletonDrawable _drawable;
|
||||
late final Bounds _bounds;
|
||||
final bool _ownsDrawable;
|
||||
|
||||
SpineComponent(this._drawable, {
|
||||
bool ownsDrawable = false,
|
||||
BoundsProvider boundsProvider = const SetupPoseBounds(),
|
||||
super.position,
|
||||
super.scale,
|
||||
double super.angle = 0.0,
|
||||
Anchor super.anchor = Anchor.topLeft,
|
||||
super.children,
|
||||
super.priority,
|
||||
}) :
|
||||
_ownsDrawable = ownsDrawable,
|
||||
_boundsProvider = boundsProvider {
|
||||
_drawable.update(0);
|
||||
_bounds = _boundsProvider.computeBounds(_drawable);
|
||||
size = Vector2(_bounds.width, _bounds.height);
|
||||
}
|
||||
|
||||
static Future<SpineComponent> fromAssets(String atlasFile, String skeletonFile, {
|
||||
AssetBundle? bundle, BoundsProvider boundsProvider = const SetupPoseBounds(),
|
||||
Vector2? position,
|
||||
Vector2? scale,
|
||||
double angle = 0.0,
|
||||
Anchor anchor = Anchor.topLeft,
|
||||
Iterable<Component>? children,
|
||||
int? priority,
|
||||
}) async {
|
||||
final drawable = await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle);
|
||||
return SpineComponent(
|
||||
drawable,
|
||||
ownsDrawable: true,
|
||||
boundsProvider: boundsProvider,
|
||||
position: position,
|
||||
scale: scale,
|
||||
angle: angle,
|
||||
anchor: anchor,
|
||||
children: children,
|
||||
priority: priority);
|
||||
}
|
||||
|
||||
@override
|
||||
void onRemove() {
|
||||
if (_ownsDrawable) _drawable.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void update(double dt) {
|
||||
_drawable.update(dt);
|
||||
}
|
||||
|
||||
@override
|
||||
void render(Canvas canvas) {
|
||||
canvas.save();
|
||||
canvas.translate(-_bounds.x, -_bounds.y);
|
||||
_drawable.renderToCanvas(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
get animationState => _drawable.animationState;
|
||||
get animationStateData => _drawable.animationStateData;
|
||||
get skeleton => _drawable.skeleton;
|
||||
}
|
||||
|
||||
class SimpleFlameExample extends FlameGame {
|
||||
late final SpineComponent spineboy;
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
// 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.skel",
|
||||
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);
|
||||
await add(spineboy);
|
||||
}
|
||||
}
|
||||
|
||||
class PreloadAndShareSpineDataExample extends FlameGame {
|
||||
late final SkeletonData cachedSkeletonData;
|
||||
late final Atlas cachedAtlas;
|
||||
late final List<SpineComponent> spineboys;
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
// Pre-load the atlas and skeleton data once.
|
||||
cachedAtlas = await Atlas.fromAsset("assets/spineboy.atlas");
|
||||
cachedSkeletonData = await SkeletonData.fromAsset(cachedAtlas, "assets/spineboy-pro.skel");
|
||||
|
||||
// Instantiate many spineboys from the pre-loaded data. Each SpineComponent
|
||||
// gets their own SkeletonDrawable copy derived from the cached data. The
|
||||
// SkeletonDrawable copies do not own the underlying skeleton data and atlas.
|
||||
final rng = Random();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
final drawable = SkeletonDrawable(cachedAtlas, cachedSkeletonData, false);
|
||||
final scale = 0.1 + rng.nextDouble() * 0.2;
|
||||
final position = Vector2(rng.nextDouble() * size.x, rng.nextDouble() * size.y);
|
||||
final spineboy = SpineComponent(
|
||||
drawable,
|
||||
scale: Vector2(scale, scale),
|
||||
position: position
|
||||
);
|
||||
spineboy.animationState.setAnimationByName(0, "walk", true);
|
||||
await add(spineboy);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onRemove() {
|
||||
// Dispose the pre-loaded atlas and skeleton data when the game/scene is removed
|
||||
cachedAtlas.dispose();
|
||||
cachedSkeletonData.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class SpineFlameGameWidget extends StatelessWidget {
|
||||
final FlameGame game;
|
||||
const SpineFlameGameWidget(this.game, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Flame Integration')),
|
||||
body: GameWidget(game: game)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,7 @@ class IkFollowingState extends State<IkFollowing> {
|
||||
if (worldPosition == null) return;
|
||||
var bone = controller.skeleton.findBone("crosshair");
|
||||
if (bone == null) return;
|
||||
var position = bone.getParent()?.worldToLocal(worldPosition.dx, worldPosition.dy) ?? Vector2(0, 0);
|
||||
var position = bone.getParent()?.worldToLocal(worldPosition.dx, worldPosition.dy) ?? Vec2(0, 0);
|
||||
bone.setX(position.x);
|
||||
bone.setY(position.y);
|
||||
});
|
||||
@ -44,7 +44,7 @@ class IkFollowingState extends State<IkFollowing> {
|
||||
body: GestureDetector(
|
||||
onPanDown: (drag) => _updateBonePosition(drag.localPosition),
|
||||
onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
|
||||
child: SpineWidget.asset("assets/spineboy-pro.skel", "assets/spineboy.atlas", controller),
|
||||
child: SpineWidget.asset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:esotericsoftware_spine_flutter/spine_flutter.dart';
|
||||
|
||||
import 'flame_example.dart';
|
||||
import 'simple_animation.dart';
|
||||
import 'animation_state_events.dart';
|
||||
import 'pause_play_animation.dart';
|
||||
import 'skins.dart';
|
||||
import 'dress_up.dart';
|
||||
import 'ik_following.dart';
|
||||
import 'package:esotericsoftware_spine_flutter/spine_flutter.dart';
|
||||
|
||||
class ExampleSelector extends StatelessWidget {
|
||||
const ExampleSelector({super.key});
|
||||
@ -91,6 +92,30 @@ class ExampleSelector extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
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
|
||||
]
|
||||
)
|
||||
|
||||
@ -33,7 +33,7 @@ class PlayPauseAnimationState extends State<PlayPauseAnimation> {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Play/Pause')),
|
||||
body: SpineWidget.asset("assets/spineboy-pro.skel", "assets/spineboy.atlas", controller),
|
||||
body: SpineWidget.asset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _togglePlay,
|
||||
child: Icon(isPlaying ? Icons.pause : Icons.play_arrow),
|
||||
|
||||
@ -14,10 +14,9 @@ class SimpleAnimation extends StatelessWidget {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Simple Animation')),
|
||||
body: SpineWidget.asset("assets/spineboy-pro.skel", "assets/spineboy.atlas", controller),
|
||||
// body: SpineWidget.file("/Users/badlogic/workspaces/spine-runtimes/examples/spineboy/export/spineboy-pro.skel", "/Users/badlogic/workspaces/spine-runtimes/examples/spineboy/export/spineboy.atlas", controller),
|
||||
// body: const SpineWidget.http("https://marioslab.io/dump/spineboy/spineboy-pro.json", "https://marioslab.io/dump/spineboy/spineboy.atlas"),
|
||||
// body: SpineWidget.asset("assets/skeleton.json", "assets/skeleton.atlas", controller, alignment: Alignment.topLeft, fit: BoxFit.cover),
|
||||
body: SpineWidget.asset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
|
||||
// body: SpineWidget.file( "/Users/badlogic/workspaces/spine-runtimes/examples/spineboy/export/spineboy.atlas", "/Users/badlogic/workspaces/spine-runtimes/examples/spineboy/export/spineboy-pro.skel", controller),
|
||||
// body: const SpineWidget.http("https://marioslab.io/dump/spineboy/spineboy.atlas", "https://marioslab.io/dump/spineboy/spineboy-pro.json"),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,7 @@ class SkinsState extends State<Skins> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SkeletonDrawable.fromAsset("assets/mix-and-match-pro.skel", "assets/mix-and-match.atlas").then((drawable) {
|
||||
SkeletonDrawable.fromAsset("assets/mix-and-match.atlas", "assets/mix-and-match-pro.skel").then((drawable) {
|
||||
for (var skin in drawable.skeletonData.getSkins()) {
|
||||
_selectedSkins[skin.getName()] = false;
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ packages:
|
||||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.2"
|
||||
version: "0.0.3"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -50,6 +50,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
flame:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flame
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -111,6 +118,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
ordered_set:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ordered_set
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -174,4 +188,4 @@ packages:
|
||||
version: "2.1.2"
|
||||
sdks:
|
||||
dart: ">=2.17.6 <3.0.0"
|
||||
flutter: ">=2.11.0"
|
||||
flutter: ">=3.3.0"
|
||||
|
||||
@ -14,6 +14,7 @@ dependencies:
|
||||
path: ../
|
||||
cupertino_icons: ^1.0.2
|
||||
raw_image_provider: ^0.2.0
|
||||
flame: ^1.4.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.0
|
||||
|
||||
@ -50,11 +50,11 @@ class Bounds {
|
||||
Bounds(this.x, this.y, this.width, this.height);
|
||||
}
|
||||
|
||||
class Vector2 {
|
||||
class Vec2 {
|
||||
double x;
|
||||
double y;
|
||||
|
||||
Vector2(this.x, this.y);
|
||||
Vec2(this.x, this.y);
|
||||
}
|
||||
|
||||
class Atlas {
|
||||
@ -99,8 +99,9 @@ class Atlas {
|
||||
return Atlas._(atlas, atlasPages, atlasPagePaints);
|
||||
}
|
||||
|
||||
static Future<Atlas> fromAsset(AssetBundle assetBundle, String atlasFileName) async {
|
||||
return _load(atlasFileName, (file) async => (await assetBundle.load(file)).buffer.asUint8List());
|
||||
static Future<Atlas> fromAsset(String atlasFileName, {AssetBundle? bundle}) async {
|
||||
bundle ??= rootBundle;
|
||||
return _load(atlasFileName, (file) async => (await bundle!.load(file)).buffer.asUint8List());
|
||||
}
|
||||
|
||||
static Future<Atlas> fromFile(String atlasFileName) async {
|
||||
@ -160,11 +161,12 @@ class SkeletonData {
|
||||
return data;
|
||||
}
|
||||
|
||||
static Future<SkeletonData> fromAsset(AssetBundle assetBundle, Atlas atlas, String skeletonFile) async {
|
||||
static Future<SkeletonData> fromAsset(Atlas atlas, String skeletonFile, {AssetBundle? bundle}) async {
|
||||
bundle ??= rootBundle;
|
||||
if (skeletonFile.endsWith(".json")) {
|
||||
return fromJson(atlas, await assetBundle.loadString(skeletonFile));
|
||||
return fromJson(atlas, await bundle.loadString(skeletonFile));
|
||||
} else {
|
||||
return fromBinary(atlas, (await assetBundle.load(skeletonFile)).buffer.asUint8List());
|
||||
return fromBinary(atlas, (await bundle.load(skeletonFile)).buffer.asUint8List());
|
||||
}
|
||||
}
|
||||
|
||||
@ -652,16 +654,16 @@ class Bone {
|
||||
_bindings.spine_bone_set_to_setup_pose(_bone);
|
||||
}
|
||||
|
||||
Vector2 worldToLocal(double worldX, double worldY) {
|
||||
Vec2 worldToLocal(double worldX, double worldY) {
|
||||
final local = _bindings.spine_bone_world_to_local(_bone, worldX, worldY);
|
||||
final result = Vector2(_bindings.spine_vector_get_x(local), _bindings.spine_vector_get_y(local));
|
||||
final result = Vec2(_bindings.spine_vector_get_x(local), _bindings.spine_vector_get_y(local));
|
||||
_allocator.free(local);
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector2 localToWorld(double localX, double localY) {
|
||||
Vec2 localToWorld(double localX, double localY) {
|
||||
final world = _bindings.spine_bone_local_to_world(_bone, localX, localY);
|
||||
final result = Vector2(_bindings.spine_vector_get_x(world), _bindings.spine_vector_get_y(world));
|
||||
final result = Vec2(_bindings.spine_vector_get_x(world), _bindings.spine_vector_get_y(world));
|
||||
_allocator.free(world);
|
||||
return result;
|
||||
}
|
||||
@ -1593,9 +1595,9 @@ class PathAttachment extends VertexAttachment<spine_path_attachment> {
|
||||
class PointAttachment extends Attachment<spine_point_attachment> {
|
||||
PointAttachment._(spine_point_attachment attachment) : super._(attachment);
|
||||
|
||||
Vector2 computeWorldPosition(Bone bone) {
|
||||
Vec2 computeWorldPosition(Bone bone) {
|
||||
final position = _bindings.spine_point_attachment_compute_world_position(_attachment, bone._bone);
|
||||
final result = Vector2(_bindings.spine_vector_get_x(position), _bindings.spine_vector_get_y(position));
|
||||
final result = Vec2(_bindings.spine_vector_get_x(position), _bindings.spine_vector_get_y(position));
|
||||
_allocator.free(position);
|
||||
return result;
|
||||
}
|
||||
@ -3256,21 +3258,23 @@ class SkeletonDrawable {
|
||||
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));
|
||||
skeleton.updateWorldTransform();
|
||||
}
|
||||
|
||||
static Future<SkeletonDrawable> fromAsset(String skeletonFile, String atlasFile) async {
|
||||
var atlas = await Atlas.fromAsset(rootBundle, atlasFile);
|
||||
var skeletonData = await SkeletonData.fromAsset(rootBundle, atlas, skeletonFile);
|
||||
static Future<SkeletonDrawable> fromAsset(String atlasFile, String skeletonFile, {AssetBundle? bundle}) async {
|
||||
bundle ??= rootBundle;
|
||||
var atlas = await Atlas.fromAsset(atlasFile, bundle: bundle);
|
||||
var skeletonData = await SkeletonData.fromAsset(atlas, skeletonFile, bundle: bundle);
|
||||
return SkeletonDrawable(atlas, skeletonData, true);
|
||||
}
|
||||
|
||||
static Future<SkeletonDrawable> fromFile(String skeletonFile, String atlasFile) async {
|
||||
static Future<SkeletonDrawable> fromFile(String atlasFile, String skeletonFile) async {
|
||||
var atlas = await Atlas.fromFile(atlasFile);
|
||||
var skeletonData = await SkeletonData.fromFile(atlas, skeletonFile);
|
||||
return SkeletonDrawable(atlas, skeletonData, true);
|
||||
}
|
||||
|
||||
static Future<SkeletonDrawable> fromHttp(String skeletonFile, String atlasFile) async {
|
||||
static Future<SkeletonDrawable> fromHttp(String atlasFile, String skeletonFile) async {
|
||||
var atlas = await Atlas.fromUrl(atlasFile);
|
||||
var skeletonData = await SkeletonData.fromHttp(atlas, skeletonFile);
|
||||
return SkeletonDrawable(atlas, skeletonData, true);
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:math';
|
||||
|
||||
import 'package:flutter/rendering.dart' as rendering;
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'spine_flutter.dart';
|
||||
@ -135,6 +136,7 @@ class ComputedBounds extends BoundsProvider {
|
||||
|
||||
class SpineWidget extends StatefulWidget {
|
||||
final AssetType _assetType;
|
||||
AssetBundle? _bundle;
|
||||
final String? _skeletonFile;
|
||||
final String? _atlasFile;
|
||||
final SkeletonDrawable? _drawable;
|
||||
@ -144,32 +146,37 @@ class SpineWidget extends StatefulWidget {
|
||||
final BoundsProvider _boundsProvider;
|
||||
final bool _sizedByBounds;
|
||||
|
||||
const SpineWidget.asset(this._skeletonFile, this._atlasFile, this._controller, {BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
|
||||
SpineWidget.asset(this._skeletonFile, this._atlasFile, 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;
|
||||
_drawable = null {
|
||||
_bundle = bundle ?? rootBundle;
|
||||
}
|
||||
|
||||
const SpineWidget.file(this._skeletonFile, this._atlasFile, this._controller, {BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
|
||||
SpineWidget.file(this._skeletonFile, this._atlasFile, 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.http(this._skeletonFile, this._atlasFile, this._controller, {BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
|
||||
SpineWidget.http(this._skeletonFile, this._atlasFile, 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.drawable(this._drawable, this._controller, {BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
|
||||
SpineWidget.drawable(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(),
|
||||
@ -189,26 +196,25 @@ class _SpineWidgetState extends State<SpineWidget> {
|
||||
if (widget._assetType == AssetType.Drawable) {
|
||||
loadDrawable(widget._drawable!);
|
||||
} else {
|
||||
loadFromAsset(widget._skeletonFile!, widget._atlasFile!, widget._assetType);
|
||||
loadFromAsset(widget._bundle, widget._skeletonFile!, widget._atlasFile!, widget._assetType);
|
||||
}
|
||||
}
|
||||
|
||||
void loadDrawable(SkeletonDrawable drawable) {
|
||||
widget._controller._initialize(drawable);
|
||||
drawable.update(0);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void loadFromAsset(String skeletonFile, String atlasFile, AssetType assetType) async {
|
||||
void loadFromAsset(AssetBundle? bundle, String atlasFile, String skeletonFile, AssetType assetType) async {
|
||||
switch (assetType) {
|
||||
case AssetType.Asset:
|
||||
loadDrawable(await SkeletonDrawable.fromAsset(skeletonFile, atlasFile));
|
||||
loadDrawable(await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle));
|
||||
break;
|
||||
case AssetType.File:
|
||||
loadDrawable(await SkeletonDrawable.fromFile(skeletonFile, atlasFile));
|
||||
loadDrawable(await SkeletonDrawable.fromFile(atlasFile, skeletonFile));
|
||||
break;
|
||||
case AssetType.Http:
|
||||
loadDrawable(await SkeletonDrawable.fromHttp(skeletonFile, atlasFile));
|
||||
loadDrawable(await SkeletonDrawable.fromHttp(atlasFile, skeletonFile));
|
||||
break;
|
||||
case AssetType.Drawable:
|
||||
throw Exception("Drawable can not be loaded via loadFromAsset().");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user