mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[flutter] Rename SpineWidget factory methods, complete doc comments.
This commit is contained in:
parent
b424cb811d
commit
147439fe95
@ -33,7 +33,7 @@ class AnimationStateEvents extends StatelessWidget {
|
|||||||
appBar: AppBar(title: const Text('Spineboy')),
|
appBar: AppBar(title: const Text('Spineboy')),
|
||||||
body: Column(children: [
|
body: Column(children: [
|
||||||
const Text("See output in console!"),
|
const Text("See output in console!"),
|
||||||
Expanded(child: SpineWidget.asset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller))
|
Expanded(child: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller))
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class DebugRendering extends StatelessWidget {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text('Debug Renderer')),
|
appBar: AppBar(title: const Text('Debug Renderer')),
|
||||||
body: SpineWidget.asset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
|
body: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ class DressUpState extends State<DressUp> {
|
|||||||
skeleton.setSkin(skin);
|
skeleton.setSkin(skin);
|
||||||
skeleton.setToSetupPose();
|
skeleton.setToSetupPose();
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform();
|
||||||
_skinImages[skin.getName()] = await drawable.renderToRawImageData(thumbnailSize, thumbnailSize);
|
_skinImages[skin.getName()] = await drawable.renderToRawImageData(thumbnailSize, thumbnailSize, 0xffffffff);
|
||||||
_selectedSkins[skin.getName()] = false;
|
_selectedSkins[skin.getName()] = false;
|
||||||
}
|
}
|
||||||
_toggleSkin("full-skins/girl");
|
_toggleSkin("full-skins/girl");
|
||||||
@ -87,7 +87,7 @@ class DressUpState extends State<DressUp> {
|
|||||||
}).toList()),
|
}).toList()),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SpineWidget.drawable(
|
child: SpineWidget.fromDrawable(
|
||||||
_drawable,
|
_drawable,
|
||||||
controller,
|
controller,
|
||||||
boundsProvider: SkinAndAnimationBounds(skins: ["full-skins/girl"]),
|
boundsProvider: SkinAndAnimationBounds(skins: ["full-skins/girl"]),
|
||||||
|
|||||||
@ -25,7 +25,9 @@ class IkFollowingState extends State<IkFollowing> {
|
|||||||
if (worldPosition == null) return;
|
if (worldPosition == null) return;
|
||||||
var bone = controller.skeleton.findBone("crosshair");
|
var bone = controller.skeleton.findBone("crosshair");
|
||||||
if (bone == null) return;
|
if (bone == null) return;
|
||||||
var position = bone.getParent()?.worldToLocal(worldPosition.dx, worldPosition.dy) ?? Vec2(0, 0);
|
var parent = bone.getParent();
|
||||||
|
if (parent == null) return;
|
||||||
|
var position = parent.worldToLocal(worldPosition.dx, worldPosition.dy);
|
||||||
bone.setX(position.x);
|
bone.setX(position.x);
|
||||||
bone.setY(position.y);
|
bone.setY(position.y);
|
||||||
});
|
});
|
||||||
@ -44,7 +46,7 @@ class IkFollowingState extends State<IkFollowing> {
|
|||||||
body: GestureDetector(
|
body: GestureDetector(
|
||||||
onPanDown: (drag) => _updateBonePosition(drag.localPosition),
|
onPanDown: (drag) => _updateBonePosition(drag.localPosition),
|
||||||
onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
|
onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
|
||||||
child: SpineWidget.asset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
|
child: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ class PlayPauseAnimationState extends State<PlayPauseAnimation> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text('Play/Pause')),
|
appBar: AppBar(title: const Text('Play/Pause')),
|
||||||
body: SpineWidget.asset(
|
body: SpineWidget.fromAsset(
|
||||||
"assets/dragon.atlas",
|
"assets/dragon.atlas",
|
||||||
"assets/dragon-ess.skel",
|
"assets/dragon-ess.skel",
|
||||||
controller,
|
controller,
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class SimpleAnimation extends StatelessWidget {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text('Simple Animation')),
|
appBar: AppBar(title: const Text('Simple Animation')),
|
||||||
body: SpineWidget.asset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
|
body: SpineWidget.fromAsset("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: 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"),
|
// body: const SpineWidget.http("https://marioslab.io/dump/spineboy/spineboy.atlas", "https://marioslab.io/dump/spineboy/spineboy-pro.json"),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import 'dart:convert' as convert;
|
import 'dart:convert' as convert;
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,27 @@ import 'package:flutter/widgets.dart';
|
|||||||
|
|
||||||
import 'spine_flutter.dart';
|
import 'spine_flutter.dart';
|
||||||
|
|
||||||
|
/// Controls how the skeleton of a [SpineWidget] is animated and rendered.
|
||||||
|
///
|
||||||
|
/// Upon initialization of a [SpineWidget] the provided [onInitialized] callback method is called once. This method can be used
|
||||||
|
/// to setup the initial animation(s) of the skeleton, among other things.
|
||||||
|
///
|
||||||
|
/// After initialization is complete, the [SpineWidget] is rendered at the screen refresh rate. In each frame,
|
||||||
|
/// the [AnimationState] is updated and applied to the [Skeleton].
|
||||||
|
///
|
||||||
|
/// Next the optionally provided method [onBeforeUpdateWorldTransforms] is called, which can modify the
|
||||||
|
/// skeleton before its current pose is calculated using [Skeleton.updateWorldTransforms]. After
|
||||||
|
/// [Skeleton.updateWorldTransforms] has completed, the optional [onAfterUpdateWorldTransforms] method is
|
||||||
|
/// called, which can modify the current pose before rendering the skeleton.
|
||||||
|
///
|
||||||
|
/// Before the skeleton's current pose is rendered by the [SpineWidget] the optional [onBeforePaint] is called,
|
||||||
|
/// which allows rendering backgrounds or other objects that should go behind the skeleton on the [Canvas]. The
|
||||||
|
/// [SpineWidget] then renderes the skeleton's current pose, and finally calls the optional [onAfterPaint], which
|
||||||
|
/// can render additional objects on top of the skeleton.
|
||||||
|
///
|
||||||
|
/// The underlying [Atlas], [SkeletonData], [Skeleton], [AnimationStateData], [AnimationState], and [SkeletonDrawable]
|
||||||
|
/// can be accessed through their respective getters to inspect and/or modify the skeleton and its associated data. Accessing
|
||||||
|
/// this data is only allowed if the [SpineWidget] and its data have been initialized and have not been disposed yet.
|
||||||
class SpineWidgetController {
|
class SpineWidgetController {
|
||||||
SkeletonDrawable? _drawable;
|
SkeletonDrawable? _drawable;
|
||||||
double _offsetX = 0, _offsetY = 0, _scaleX = 1, _scaleY = 1;
|
double _offsetX = 0, _offsetY = 0, _scaleX = 1, _scaleY = 1;
|
||||||
@ -16,6 +37,8 @@ class SpineWidgetController {
|
|||||||
final void Function(SpineWidgetController controller, Canvas canvas)? onBeforePaint;
|
final void Function(SpineWidgetController controller, Canvas canvas)? onBeforePaint;
|
||||||
final void Function(SpineWidgetController controller, Canvas canvas, List<RenderCommand> commands)? onAfterPaint;
|
final void Function(SpineWidgetController controller, Canvas canvas, List<RenderCommand> commands)? onAfterPaint;
|
||||||
|
|
||||||
|
/// Constructs a new [SpineWidget] controller. See the class documentation of [SpineWidgetController] for information on
|
||||||
|
/// the optional arguments.
|
||||||
SpineWidgetController(
|
SpineWidgetController(
|
||||||
{this.onInitialized, this.onBeforeUpdateWorldTransforms, this.onAfterUpdateWorldTransforms, this.onBeforePaint, this.onAfterPaint});
|
{this.onInitialized, this.onBeforeUpdateWorldTransforms, this.onAfterUpdateWorldTransforms, this.onBeforePaint, this.onAfterPaint});
|
||||||
|
|
||||||
@ -25,31 +48,38 @@ class SpineWidgetController {
|
|||||||
onInitialized?.call(this);
|
onInitialized?.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The [Atlas] from which images to render the skeleton are sourced.
|
||||||
Atlas get atlas {
|
Atlas get atlas {
|
||||||
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
||||||
return _drawable!.atlas;
|
return _drawable!.atlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The setup-pose data used by the skeleton.
|
||||||
SkeletonData get skeletonData {
|
SkeletonData get skeletonData {
|
||||||
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
||||||
return _drawable!.skeletonData;
|
return _drawable!.skeletonData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The mixing information used by the [AnimationState]
|
||||||
AnimationStateData get animationStateData {
|
AnimationStateData get animationStateData {
|
||||||
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
||||||
return _drawable!.animationStateData;
|
return _drawable!.animationStateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The [AnimationState] used to manage animations that are being applied to the
|
||||||
|
/// skeleton.
|
||||||
AnimationState get animationState {
|
AnimationState get animationState {
|
||||||
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
||||||
return _drawable!.animationState;
|
return _drawable!.animationState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The [Skeleton]
|
||||||
Skeleton get skeleton {
|
Skeleton get skeleton {
|
||||||
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
||||||
return _drawable!.skeleton;
|
return _drawable!.skeleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The [SkeletonDrawable]
|
||||||
SkeletonDrawable get drawable {
|
SkeletonDrawable get drawable {
|
||||||
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
if (_drawable == null) throw Exception("Controller is not initialized yet.");
|
||||||
return _drawable!;
|
return _drawable!;
|
||||||
@ -62,6 +92,9 @@ class SpineWidgetController {
|
|||||||
_scaleY = scaleY;
|
_scaleY = scaleY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transforms the coordinates given in the [SpineWidget] coordinate system in [position] to
|
||||||
|
/// the skeleton coordinate system. See the `ik_following.dart` example how to use this
|
||||||
|
/// to move a bone based on user touch input.
|
||||||
Offset toSkeletonCoordinates(Offset position) {
|
Offset toSkeletonCoordinates(Offset position) {
|
||||||
var x = position.dx;
|
var x = position.dx;
|
||||||
var y = position.dy;
|
var y = position.dy;
|
||||||
@ -69,14 +102,18 @@ class SpineWidgetController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AssetType { asset, file, http, drawable }
|
enum _AssetType { asset, file, http, drawable }
|
||||||
|
|
||||||
|
/// Base class for bounds providers. A bounds provider calculates the axis aligned bounding box
|
||||||
|
/// used to scale and fit a skeleton inside the bounds of a [SpineWidget].
|
||||||
abstract class BoundsProvider {
|
abstract class BoundsProvider {
|
||||||
const BoundsProvider();
|
const BoundsProvider();
|
||||||
|
|
||||||
Bounds computeBounds(SkeletonDrawable drawable);
|
Bounds computeBounds(SkeletonDrawable drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [BoundsProvider] that calculates the bounding box of the skeleton based on the visible
|
||||||
|
/// attachments in the setup pose.
|
||||||
class SetupPoseBounds extends BoundsProvider {
|
class SetupPoseBounds extends BoundsProvider {
|
||||||
const SetupPoseBounds();
|
const SetupPoseBounds();
|
||||||
|
|
||||||
@ -86,6 +123,7 @@ class SetupPoseBounds extends BoundsProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [BoundsProvider] that returns fixed bounds.
|
||||||
class RawBounds extends BoundsProvider {
|
class RawBounds extends BoundsProvider {
|
||||||
final double x, y, width, height;
|
final double x, y, width, height;
|
||||||
|
|
||||||
@ -97,11 +135,17 @@ class RawBounds extends BoundsProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [BoundsProvider] that calculates the bounding box needed for a combination of skins
|
||||||
|
/// and an animation.
|
||||||
class SkinAndAnimationBounds extends BoundsProvider {
|
class SkinAndAnimationBounds extends BoundsProvider {
|
||||||
final List<String> skins;
|
final List<String> skins;
|
||||||
final String? animation;
|
final String? animation;
|
||||||
final double stepTime;
|
final double stepTime;
|
||||||
|
|
||||||
|
/// Constructs a new provider that will use the given [skins] and [animation] to calculate
|
||||||
|
/// the bounding box of the skeleton. If no skins are given, the default skin is used.
|
||||||
|
/// 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})
|
SkinAndAnimationBounds({List<String>? skins, this.animation, this.stepTime = 0.1})
|
||||||
: skins = skins == null || skins.isEmpty ? ["default"] : skins;
|
: skins = skins == null || skins.isEmpty ? ["default"] : skins;
|
||||||
|
|
||||||
@ -151,15 +195,15 @@ class SkinAndAnimationBounds extends BoundsProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComputedBounds extends BoundsProvider {
|
/// A [StatefulWidget] to display a Spine skeleton. The skeleton can be loaded from an asset bundle ([SpineWidget.fromAsset],
|
||||||
@override
|
/// local files [SpineWidget.fromFile], URLs [SpineWidget.fromHttp], or a pre-loaded [SkeletonDrawable] ([SpineWidget.fromDrawable]).
|
||||||
Bounds computeBounds(SkeletonDrawable drawable) {
|
///
|
||||||
return Bounds(0, 0, 0, 0);
|
/// The skeleton displayed by a `SpineWidget` can be controlled via a [SpineWidgetController].
|
||||||
}
|
///
|
||||||
}
|
/// The size of the widget can be derived from the bounds provided by a [BoundsProvider]. If the widget is not sized by the bounds
|
||||||
|
/// computed by the [BoundsProvider], the widget will use the computed bounds to fit the skeleton inside the widget's dimensions.
|
||||||
class SpineWidget extends StatefulWidget {
|
class SpineWidget extends StatefulWidget {
|
||||||
final AssetType _assetType;
|
final _AssetType _assetType;
|
||||||
final AssetBundle? _bundle;
|
final AssetBundle? _bundle;
|
||||||
final String? _skeletonFile;
|
final String? _skeletonFile;
|
||||||
final String? _atlasFile;
|
final String? _atlasFile;
|
||||||
@ -170,9 +214,21 @@ class SpineWidget extends StatefulWidget {
|
|||||||
final BoundsProvider _boundsProvider;
|
final BoundsProvider _boundsProvider;
|
||||||
final bool _sizedByBounds;
|
final bool _sizedByBounds;
|
||||||
|
|
||||||
SpineWidget.asset(this._atlasFile, this._skeletonFile, this._controller,
|
/// Constructs a new [SpineWidget] from files in the root bundle or the optionally specified [bundle]. 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.
|
||||||
|
///
|
||||||
|
/// After initialization is complete, the provided [_controller] is invoked as per the [SpineWidgetController] semantics, to allow
|
||||||
|
/// modifying how the skeleton inside the widget is animated and rendered.
|
||||||
|
///
|
||||||
|
/// The skeleton is fitted and aligned inside the widget as per the [fit] and [alignment] arguments. For this purpose, the skeleton
|
||||||
|
/// bounds must be computed via a [BoundsProvider]. By default, [BoxFit.contain], [Alignment.center], and a [SetupPoseBounds] provider
|
||||||
|
/// 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})
|
{AssetBundle? bundle, BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
|
||||||
: _assetType = AssetType.asset,
|
: _assetType = _AssetType.asset,
|
||||||
_fit = fit ?? BoxFit.contain,
|
_fit = fit ?? BoxFit.contain,
|
||||||
_alignment = alignment ?? Alignment.center,
|
_alignment = alignment ?? Alignment.center,
|
||||||
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
|
_boundsProvider = boundsProvider ?? const SetupPoseBounds(),
|
||||||
@ -180,9 +236,20 @@ class SpineWidget extends StatefulWidget {
|
|||||||
_drawable = null,
|
_drawable = null,
|
||||||
_bundle = bundle ?? rootBundle;
|
_bundle = bundle ?? rootBundle;
|
||||||
|
|
||||||
const SpineWidget.file(this._atlasFile, this._skeletonFile, this._controller,
|
/// 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.
|
||||||
|
///
|
||||||
|
/// After initialization is complete, the provided [_controller] is invoked as per the [SpineWidgetController] semantics, to allow
|
||||||
|
/// modifying how the skeleton inside the widget is animated and rendered.
|
||||||
|
///
|
||||||
|
/// The skeleton is fitted and aligned inside the widget as per the [fit] and [alignment] arguments. For this purpose, the skeleton
|
||||||
|
/// bounds must be computed via a [BoundsProvider]. By default, [BoxFit.contain], [Alignment.center], and a [SetupPoseBounds] provider
|
||||||
|
/// 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})
|
{BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
|
||||||
: _assetType = AssetType.file,
|
: _assetType = _AssetType.file,
|
||||||
_bundle = null,
|
_bundle = null,
|
||||||
_fit = fit ?? BoxFit.contain,
|
_fit = fit ?? BoxFit.contain,
|
||||||
_alignment = alignment ?? Alignment.center,
|
_alignment = alignment ?? Alignment.center,
|
||||||
@ -190,9 +257,20 @@ class SpineWidget extends StatefulWidget {
|
|||||||
_sizedByBounds = sizedByBounds ?? false,
|
_sizedByBounds = sizedByBounds ?? false,
|
||||||
_drawable = null;
|
_drawable = null;
|
||||||
|
|
||||||
const SpineWidget.http(this._atlasFile, this._skeletonFile, this._controller,
|
/// 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.
|
||||||
|
///
|
||||||
|
/// After initialization is complete, the provided [_controller] is invoked as per the [SpineWidgetController] semantics, to allow
|
||||||
|
/// modifying how the skeleton inside the widget is animated and rendered.
|
||||||
|
///
|
||||||
|
/// The skeleton is fitted and aligned inside the widget as per the [fit] and [alignment] arguments. For this purpose, the skeleton
|
||||||
|
/// bounds must be computed via a [BoundsProvider]. By default, [BoxFit.contain], [Alignment.center], and a [SetupPoseBounds] provider
|
||||||
|
/// 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})
|
{BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
|
||||||
: _assetType = AssetType.http,
|
: _assetType = _AssetType.http,
|
||||||
_bundle = null,
|
_bundle = null,
|
||||||
_fit = fit ?? BoxFit.contain,
|
_fit = fit ?? BoxFit.contain,
|
||||||
_alignment = alignment ?? Alignment.center,
|
_alignment = alignment ?? Alignment.center,
|
||||||
@ -200,9 +278,19 @@ class SpineWidget extends StatefulWidget {
|
|||||||
_sizedByBounds = sizedByBounds ?? false,
|
_sizedByBounds = sizedByBounds ?? false,
|
||||||
_drawable = null;
|
_drawable = null;
|
||||||
|
|
||||||
const SpineWidget.drawable(this._drawable, this._controller,
|
/// Constructs a new [SpineWidget] from a [SkeletonDrawable].
|
||||||
|
///
|
||||||
|
/// After initialization is complete, the provided [_controller] is invoked as per the [SpineWidgetController] semantics, to allow
|
||||||
|
/// modifying how the skeleton inside the widget is animated and rendered.
|
||||||
|
///
|
||||||
|
/// The skeleton is fitted and aligned inside the widget as per the [fit] and [alignment] arguments. For this purpose, the skeleton
|
||||||
|
/// bounds must be computed via a [BoundsProvider]. By default, [BoxFit.contain], [Alignment.center], and a [SetupPoseBounds] provider
|
||||||
|
/// 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})
|
{BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key})
|
||||||
: _assetType = AssetType.drawable,
|
: _assetType = _AssetType.drawable,
|
||||||
_bundle = null,
|
_bundle = null,
|
||||||
_fit = fit ?? BoxFit.contain,
|
_fit = fit ?? BoxFit.contain,
|
||||||
_alignment = alignment ?? Alignment.center,
|
_alignment = alignment ?? Alignment.center,
|
||||||
@ -222,7 +310,7 @@ class _SpineWidgetState extends State<SpineWidget> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
if (widget._assetType == AssetType.drawable) {
|
if (widget._assetType == _AssetType.drawable) {
|
||||||
loadDrawable(widget._drawable!);
|
loadDrawable(widget._drawable!);
|
||||||
} else {
|
} else {
|
||||||
loadFromAsset(widget._bundle, widget._atlasFile!, widget._skeletonFile!, widget._assetType);
|
loadFromAsset(widget._bundle, widget._atlasFile!, widget._skeletonFile!, widget._assetType);
|
||||||
@ -236,18 +324,18 @@ class _SpineWidgetState extends State<SpineWidget> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadFromAsset(AssetBundle? bundle, String atlasFile, String skeletonFile, AssetType assetType) async {
|
void loadFromAsset(AssetBundle? bundle, String atlasFile, String skeletonFile, _AssetType assetType) async {
|
||||||
switch (assetType) {
|
switch (assetType) {
|
||||||
case AssetType.asset:
|
case _AssetType.asset:
|
||||||
loadDrawable(await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle));
|
loadDrawable(await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle));
|
||||||
break;
|
break;
|
||||||
case AssetType.file:
|
case _AssetType.file:
|
||||||
loadDrawable(await SkeletonDrawable.fromFile(atlasFile, skeletonFile));
|
loadDrawable(await SkeletonDrawable.fromFile(atlasFile, skeletonFile));
|
||||||
break;
|
break;
|
||||||
case AssetType.http:
|
case _AssetType.http:
|
||||||
loadDrawable(await SkeletonDrawable.fromHttp(atlasFile, skeletonFile));
|
loadDrawable(await SkeletonDrawable.fromHttp(atlasFile, skeletonFile));
|
||||||
break;
|
break;
|
||||||
case AssetType.drawable:
|
case _AssetType.drawable:
|
||||||
throw Exception("Drawable can not be loaded via loadFromAsset().");
|
throw Exception("Drawable can not be loaded via loadFromAsset().");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user