From f8677531c9a0e6a7f8b386a32a1a0f1fc4253f0f Mon Sep 17 00:00:00 2001 From: Orr Shalom Dvory Date: Fri, 18 Dec 2020 14:29:31 +0200 Subject: [PATCH 1/2] Added function to test hit on nodes in the animation. Very useful feature, that should help with making animatable buttons etc.. When extending FlareControls and overriding setViewTransform, one should add call to "super.setViewTransform(viewTransform);" in order to make it work. Example: wrap your FlareActor with GestureDetector. add onTapDown Event, and ask the flare controller which nodes were clicked. GestureDetector(child: FlareActor( "assets/Teddy.flr", shouldClip: false, alignment: Alignment.bottomCenter, fit: BoxFit.contain, controller: _teddyController, ), onTapDown : (details){ print (_teddyController.deepHitTest(details.globalPosition)); } ) --- flare_dart/lib/math/aabb.dart | 5 +++++ flare_flutter/lib/flare.dart | 25 +++++++++++++++++++++++++ flare_flutter/lib/flare_controls.dart | 15 ++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/flare_dart/lib/math/aabb.dart b/flare_dart/lib/math/aabb.dart index f0212f4..3f359ff 100644 --- a/flare_dart/lib/math/aabb.dart +++ b/flare_dart/lib/math/aabb.dart @@ -81,6 +81,11 @@ class AABB { return a[0] <= b[0] && a[1] <= b[1] && b[2] <= a[2] && b[3] <= a[3]; } + static bool pointInside(AABB a, Vec2D point) { + return a[0] <= point[0] && a[2] >= point[0] + && a[1] <= point[1] && a[3] >= point[1]; + } + static bool isValid(AABB a) { double dx = a[2] - a[0]; double dy = a[3] - a[1]; diff --git a/flare_flutter/lib/flare.dart b/flare_flutter/lib/flare.dart index 7e430b8..2daa0f2 100644 --- a/flare_flutter/lib/flare.dart +++ b/flare_flutter/lib/flare.dart @@ -67,6 +67,7 @@ abstract class FlutterActorDrawable { void onAntialiasChanged(bool useAA); void onBlendModeChanged(ui.BlendMode blendMode); + List hitTest(ui.Offset point) => []; void draw(ui.Canvas canvas); List> get clipShapes; @@ -292,6 +293,14 @@ class FlutterActorShape extends ActorShape with FlutterActorDrawable { return path; } + @override + List hitTest(ui.Offset point) { + if (path.contains(point) && (fills != null)) { + return [name]; + } + return []; + } + @override void draw(ui.Canvas canvas) { if (!doesDraw) { @@ -862,6 +871,22 @@ class FlutterActorArtboard extends ActorArtboard { } } + List deepHitTest(ui.Offset point) { + List nodeNameList = []; + if (drawableNodes != null) { + for (final ActorDrawable drawable in drawableNodes) { + if (drawable is FlutterActorDrawable) { + List nodeNames = + (drawable as FlutterActorDrawable).hitTest(point); + if (nodeNames.isNotEmpty) { + nodeNameList.addAll(nodeNames); + } + } + } + } + return nodeNameList; + } + void draw(ui.Canvas canvas) { if (clipContents) { canvas.save(); diff --git a/flare_flutter/lib/flare_controls.dart b/flare_flutter/lib/flare_controls.dart index ed89a16..ca06c22 100644 --- a/flare_flutter/lib/flare_controls.dart +++ b/flare_flutter/lib/flare_controls.dart @@ -1,8 +1,10 @@ import 'dart:math'; import 'package:flare_dart/math/mat2d.dart'; +import 'package:flare_dart/math/vec2d.dart'; import 'flare.dart'; import 'flare_actor.dart'; import 'flare_controller.dart'; +import 'dart:ui'; /// [FlareControls] is a concrete implementation of the [FlareController]. /// @@ -47,8 +49,19 @@ class FlareControls extends FlareController { } } + // Storage for our matrix to get global Flutter coordinates into Flare world coordinates. + Mat2D globalToFlareWorld = Mat2D(); + List deepHitTest(Offset point) { + Vec2D pointGlobal = Vec2D.fromValues(point.dx, point.dy); + Vec2D pointFlare = Vec2D(); + Vec2D.transformMat2D(pointFlare, pointGlobal, globalToFlareWorld); + return _artboard.deepHitTest(Offset(pointFlare[0], pointFlare[1])); + } + @override - void setViewTransform(Mat2D viewTransform) {} + void setViewTransform(Mat2D viewTransform) { + Mat2D.invert(globalToFlareWorld, viewTransform); + } /// Advance all the [FlareAnimationLayer]s that are currently controlled /// by this object, and mixes them accordingly. From 5b81d812c4f886e6abc296d736d541217d298948 Mon Sep 17 00:00:00 2001 From: Orr Shalom Dvory Date: Mon, 21 Dec 2020 23:10:57 +0200 Subject: [PATCH 2/2] Added mechanism to stop animations --- flare_flutter/lib/flare_controls.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/flare_flutter/lib/flare_controls.dart b/flare_flutter/lib/flare_controls.dart index ca06c22..aacf44f 100644 --- a/flare_flutter/lib/flare_controls.dart +++ b/flare_flutter/lib/flare_controls.dart @@ -17,6 +17,7 @@ class FlareControls extends FlareController { /// The current [ActorAnimation]. String _animationName; + List _toBeRemoved = []; final double _mixSeconds = 0.1; /// The [FlareAnimationLayer]s currently active. @@ -49,6 +50,10 @@ class FlareControls extends FlareController { } } + void stop(String name) { + _toBeRemoved.add(name); + } + // Storage for our matrix to get global Flutter coordinates into Flare world coordinates. Mat2D globalToFlareWorld = Mat2D(); List deepHitTest(Offset point) { @@ -72,6 +77,13 @@ class FlareControls extends FlareController { bool advance(FlutterActorArtboard artboard, double elapsed) { /// List of completed animations during this frame. List completed = []; + //remove all stopped animations + for (final String animationName in _toBeRemoved) { + _animationLayers.removeWhere((animation) => + animation.name == animationName); + onCompleted(animationName); + } + _toBeRemoved.clear(); /// This loop will mix all the currently active animation layers so that, /// if an animation is played on top of the current one, it'll smoothly mix