From d0a81351d349efdd93d6cbd19ff1e07aec1c0d7c Mon Sep 17 00:00:00 2001 From: Umberto Sonnino Date: Wed, 12 Jun 2019 12:52:27 +0200 Subject: [PATCH 1/4] Missing mixed value for interpolators #100 --- flare_dart/lib/animation/keyframe.dart | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/flare_dart/lib/animation/keyframe.dart b/flare_dart/lib/animation/keyframe.dart index 0acd1c7..1de9763 100644 --- a/flare_dart/lib/animation/keyframe.dart +++ b/flare_dart/lib/animation/keyframe.dart @@ -611,10 +611,12 @@ class KeyFrameFillColor extends KeyFrameWithInterpolation { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { ActorColor ac = component as ActorColor; @@ -623,6 +625,9 @@ class KeyFrameFillColor extends KeyFrameWithInterpolation { int l = _value.length; double f = (time - _time) / (toFrame.time - _time); + if (_interpolator != null) { + f = _interpolator.getEasedMix(f); + } double fi = 1.0 - f; if (mix == 1.0) { for (int i = 0; i < l; i++) { @@ -698,10 +703,12 @@ class KeyFramePathVertices extends KeyFrameWithInterpolation { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { ActorPath path = component as ActorPath; @@ -710,6 +717,9 @@ class KeyFramePathVertices extends KeyFrameWithInterpolation { int l = _vertices.length; double f = (time - _time) / (toFrame.time - _time); + if(_interpolator != null) { + f = _interpolator.getEasedMix(f); + } double fi = 1.0 - f; if (mix == 1.0) { for (int i = 0; i < l; i++) { @@ -778,7 +788,7 @@ class KeyFrameStrokeColor extends KeyFrameWithInterpolation { } @override - applyInterpolation( + void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { ColorStroke cs = component as ColorStroke; Float32List wr = cs.color; @@ -786,6 +796,9 @@ class KeyFrameStrokeColor extends KeyFrameWithInterpolation { int len = _value.length; double f = (time - _time) / (toFrame.time - _time); + if (_interpolator != null) { + f = _interpolator.getEasedMix(f); + } double fi = 1.0 - f; if (mix == 1.0) { for (int i = 0; i < len; i++) { From 54274f58e76e95cc9de6458d1a31c17a5331a49e Mon Sep 17 00:00:00 2001 From: Umberto Sonnino Date: Wed, 12 Jun 2019 12:53:16 +0200 Subject: [PATCH 2/4] Play nice with Dart linter --- .../animation/interpolation/cubic_ease.dart | 3 +- .../lib/animation/interpolation/hold.dart | 3 +- .../lib/animation/interpolation/linear.dart | 3 +- flare_dart/lib/animation/keyframe.dart | 125 +++++++++++------- 4 files changed, 84 insertions(+), 50 deletions(-) diff --git a/flare_dart/lib/animation/interpolation/cubic_ease.dart b/flare_dart/lib/animation/interpolation/cubic_ease.dart index 5b40a7b..975aa41 100644 --- a/flare_dart/lib/animation/interpolation/cubic_ease.dart +++ b/flare_dart/lib/animation/interpolation/cubic_ease.dart @@ -23,7 +23,7 @@ double getSlope(double aT, double aA1, double aA2) { (3.0 * aA1); } -double newtonRaphsonIterate(aX, aGuessT, mX1, mX2) { +double newtonRaphsonIterate(double aX, double aGuessT, double mX1, double mX2) { for (int i = 0; i < NewtonIterations; ++i) { double currentSlope = getSlope(aGuessT, mX1, mX2); if (currentSlope == 0.0) { @@ -113,6 +113,7 @@ class Cubic extends CubicEase { } } + @override double ease(double mix) { return calcBezier(getT(mix), y1, y2); } diff --git a/flare_dart/lib/animation/interpolation/hold.dart b/flare_dart/lib/animation/interpolation/hold.dart index ce67583..13896b8 100644 --- a/flare_dart/lib/animation/interpolation/hold.dart +++ b/flare_dart/lib/animation/interpolation/hold.dart @@ -1,10 +1,11 @@ import "./interpolator.dart"; class HoldInterpolator extends Interpolator { - static get instance { + static Interpolator get instance { return _instance; } + @override double getEasedMix(double mix) { return 0.0; } diff --git a/flare_dart/lib/animation/interpolation/linear.dart b/flare_dart/lib/animation/interpolation/linear.dart index f57e102..81d0cd7 100644 --- a/flare_dart/lib/animation/interpolation/linear.dart +++ b/flare_dart/lib/animation/interpolation/linear.dart @@ -1,10 +1,11 @@ import "./interpolator.dart"; class LinearInterpolator extends Interpolator { - static get instance { + static Interpolator get instance { return _instance; } + @override double getEasedMix(double mix) { return mix; } diff --git a/flare_dart/lib/animation/keyframe.dart b/flare_dart/lib/animation/keyframe.dart index 1de9763..ed7cfd7 100644 --- a/flare_dart/lib/animation/keyframe.dart +++ b/flare_dart/lib/animation/keyframe.dart @@ -1,24 +1,26 @@ -import '../actor_drawable.dart'; -import "../stream_reader.dart"; -import "../actor_component.dart"; -import "../actor_node.dart"; +import "dart:collection"; +import "dart:typed_data"; + +import "../actor_artboard.dart"; import "../actor_bone_base.dart"; +import "../actor_color.dart"; +import "../actor_component.dart"; import "../actor_constraint.dart"; +import '../actor_drawable.dart'; import "../actor_image.dart"; -import "../actor_artboard.dart"; +import "../actor_node.dart"; import "../actor_node_solo.dart"; -import "../actor_star.dart"; +import "../actor_path.dart"; import "../actor_rectangle.dart"; -import "../math/mat2d.dart"; -import "./interpolation/interpolator.dart"; +import "../actor_star.dart"; +import "../path_point.dart"; +import "../stream_reader.dart"; + +import "./interpolation/cubic.dart"; import "./interpolation/hold.dart"; +import "./interpolation/interpolator.dart"; import "./interpolation/linear.dart"; -import "./interpolation/cubic.dart"; -import "dart:collection"; -import "dart:typed_data"; -import "../actor_path.dart"; -import "../path_point.dart"; -import "../actor_color.dart"; + enum InterpolationTypes { Hold, Linear, Cubic } @@ -66,9 +68,7 @@ abstract class KeyFrameWithInterpolation extends KeyFrame { int type = reader.readUint8("interpolatorType"); InterpolationTypes actualType = interpolationTypesLookup[type]; - if (actualType == null) { - actualType = InterpolationTypes.Linear; - } + actualType ??= InterpolationTypes.Linear; switch (actualType) { case InterpolationTypes.Hold: @@ -91,6 +91,7 @@ abstract class KeyFrameWithInterpolation extends KeyFrame { return true; } + @override void setNext(KeyFrame frame) { // Null out the interpolator if the next frame doesn't validate. // if(_interpolator != null && !_interpolator.setNextFrame(this, frame)) @@ -124,6 +125,7 @@ abstract class KeyFrameNumeric extends KeyFrameWithInterpolation { return true; } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { KeyFrameNumeric to = toFrame as KeyFrameNumeric; @@ -134,6 +136,7 @@ abstract class KeyFrameNumeric extends KeyFrameWithInterpolation { setValue(component, _value * (1.0 - f) + to._value * f, mix); } + @override void apply(ActorComponent component, double mix) { setValue(component, _value, mix); } @@ -156,6 +159,7 @@ abstract class KeyFrameInt extends KeyFrameWithInterpolation { return true; } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { KeyFrameNumeric to = toFrame as KeyFrameNumeric; @@ -166,6 +170,7 @@ abstract class KeyFrameInt extends KeyFrameWithInterpolation { setValue(component, _value * (1.0 - f) + to._value * f, mix); } + @override void apply(ActorComponent component, double mix) { setValue(component, _value, mix); } @@ -182,6 +187,7 @@ class KeyFrameIntProperty extends KeyFrameInt { return null; } + @override void setValue(ActorComponent component, double value, double mix) { // TODO //CustomIntProperty node = component as CustomIntProperty; @@ -197,7 +203,7 @@ class KeyFrameFloatProperty extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { // TODO // CustomFloatProperty node = component as CustomFloatProperty; @@ -216,15 +222,18 @@ class KeyFrameStringProperty extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { // CustomStringProperty prop = component as CustomStringProperty; // prop.value = _value; @@ -242,15 +251,18 @@ class KeyFrameBooleanProperty extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { // CustomBooleanProperty prop = component as CustomBooleanProperty; // prop.value = _value; @@ -268,15 +280,18 @@ class KeyFrameCollisionEnabledProperty extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { // ActorCollider collider = component as ActorCollider; // collider.isCollisionEnabled = _value; @@ -291,7 +306,7 @@ class KeyFramePosX extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.x = node.x * (1.0 - mix) + value * mix; @@ -306,7 +321,7 @@ class KeyFramePosY extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.y = node.y * (1.0 - mix) + value * mix; @@ -321,7 +336,7 @@ class KeyFrameScaleX extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.scaleX = node.scaleX * (1.0 - mix) + value * mix; @@ -336,7 +351,7 @@ class KeyFrameScaleY extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.scaleY = node.scaleY * (1.0 - mix) + value * mix; @@ -351,7 +366,7 @@ class KeyFrameRotation extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.rotation = node.rotation * (1.0 - mix) + value * mix; @@ -366,7 +381,7 @@ class KeyFrameOpacity extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.opacity = node.opacity * (1.0 - mix) + value * mix; @@ -381,7 +396,7 @@ class KeyFrameLength extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorBoneBase bone = component as ActorBoneBase; if (bone == null) { @@ -399,7 +414,7 @@ class KeyFrameConstraintStrength extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorConstraint constraint = component as ActorConstraint; constraint.strength = constraint.strength * (1.0 - mix) + value * mix; @@ -434,19 +449,22 @@ class KeyFrameDrawOrder extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { ActorArtboard artboard = component.artboard; - for (DrawOrderIndex doi in _orderedNodes) { + for (final DrawOrderIndex doi in _orderedNodes) { ActorComponent component = artboard[doi.componentIndex]; if (component is ActorDrawable) { component.drawOrder = doi.order; @@ -477,10 +495,12 @@ class KeyFrameImageVertices extends KeyFrameWithInterpolation { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { ActorImage imageNode = component as ActorImage; @@ -510,6 +530,7 @@ class KeyFrameImageVertices extends KeyFrameWithInterpolation { imageNode.invalidateDrawable(); } + @override void apply(ActorComponent component, double mix) { ActorImage imageNode = component as ActorImage; int l = _vertices.length; @@ -538,13 +559,16 @@ class KeyFrameTrigger extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) {} + @override void apply(ActorComponent component, double mix) {} } @@ -560,15 +584,18 @@ class KeyFrameActiveChild extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // No Interpolation } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { ActorNodeSolo soloNode = component as ActorNodeSolo; soloNode.activeChildIndex = _value; @@ -583,7 +610,7 @@ class KeyFrameSequence extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorImage node = component as ActorImage; int frameIndex = value.floor() % node.sequenceFrames.length; @@ -644,6 +671,7 @@ class KeyFrameFillColor extends KeyFrameWithInterpolation { ac.markPaintDirty(); } + @override void apply(ActorComponent component, double mix) { ActorColor ac = component as ActorColor; int l = _value.length; @@ -683,7 +711,7 @@ class KeyFramePathVertices extends KeyFrameWithInterpolation { frame._vertices = Float32List(length); int readIdx = 0; reader.openArray("value"); - for (PathPoint point in pathNode.points) { + for (final PathPoint point in pathNode.points) { frame._vertices[readIdx++] = reader.readFloat32("translationX"); frame._vertices[readIdx++] = reader.readFloat32("translationY"); if (point.pointType == PointType.Straight) { @@ -737,6 +765,7 @@ class KeyFramePathVertices extends KeyFrameWithInterpolation { path.markVertexDeformDirty(); } + @override void apply(ActorComponent component, double mix) { ActorPath path = component as ActorPath; int l = _vertices.length; @@ -764,7 +793,7 @@ class KeyFramePaintOpacity extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorPaint node = component as ActorPaint; node.opacity = node.opacity * (1.0 - mix) + value * mix; @@ -816,7 +845,7 @@ class KeyFrameStrokeColor extends KeyFrameWithInterpolation { } @override - apply(ActorComponent component, double mix) { + void apply(ActorComponent component, double mix) { ColorStroke node = component as ColorStroke; Float32List wr = node.color; int len = wr.length; @@ -842,7 +871,7 @@ class KeyFrameCornerRadius extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { ActorRectangle node = component as ActorRectangle; node.radius = node.radius * (1.0 - mix) + value * mix; @@ -851,7 +880,7 @@ class KeyFrameCornerRadius extends KeyFrameNumeric { class KeyFrameGradient extends KeyFrameWithInterpolation { Float32List _value; - get value => _value; + Float32List get value => _value; static KeyFrame read(StreamReader reader, ActorComponent component) { KeyFrameGradient frame = KeyFrameGradient(); @@ -864,7 +893,7 @@ class KeyFrameGradient extends KeyFrameWithInterpolation { } @override - applyInterpolation( + void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { GradientColor gradient = component as GradientColor; Float32List v = (toFrame as KeyFrameGradient)._value; @@ -890,7 +919,8 @@ class KeyFrameGradient extends KeyFrameWithInterpolation { } else { double imix = 1.0 - mix; - // Mix : first interpolate the KeyFrames, and then mix on top of the current value. + // Mix : first interpolate the KeyFrames, + // and then mix on top of the current value. double val = _value[ridx] * fi + v[ridx] * f; gradient.start[0] = gradient.start[0] * imix + val * mix; ridx++; @@ -919,7 +949,7 @@ class KeyFrameGradient extends KeyFrameWithInterpolation { } @override - apply(ActorComponent component, double mix) { + void apply(ActorComponent component, double mix) { GradientColor gradient = component as GradientColor; int ridx = 0; @@ -953,7 +983,7 @@ class KeyFrameGradient extends KeyFrameWithInterpolation { class KeyFrameRadial extends KeyFrameWithInterpolation { Float32List _value; - get value => _value; + Float32List get value => _value; static KeyFrame read(StreamReader reader, ActorComponent component) { KeyFrameRadial frame = KeyFrameRadial(); @@ -966,7 +996,7 @@ class KeyFrameRadial extends KeyFrameWithInterpolation { } @override - applyInterpolation( + void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { RadialGradientColor radial = component as RadialGradientColor; Float32List v = (toFrame as KeyFrameRadial)._value; @@ -993,7 +1023,8 @@ class KeyFrameRadial extends KeyFrameWithInterpolation { } else { double imix = 1.0 - mix; - // Mix : first interpolate the KeyFrames, and then mix on top of the current value. + // Mix : first interpolate the KeyFrames, + // and then mix on top of the current value. double val = _value[ridx] * fi + v[ridx] * f; radial.secondaryRadiusScale = _value[ridx] * fi + v[ridx++] * f; val = _value[ridx] * fi + v[ridx] * f; @@ -1017,7 +1048,7 @@ class KeyFrameRadial extends KeyFrameWithInterpolation { } @override - apply(ActorComponent component, double mix) { + void apply(ActorComponent component, double mix) { RadialGradientColor radial = component as RadialGradientColor; int ridx = 0; @@ -1059,7 +1090,7 @@ class KeyFrameShapeWidth extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1077,7 +1108,7 @@ class KeyFrameShapeHeight extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1095,7 +1126,7 @@ class KeyFrameStrokeWidth extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; ActorStroke stroke = component as ActorStroke; @@ -1111,7 +1142,7 @@ class KeyFrameInnerRadius extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1128,7 +1159,7 @@ class KeyFrameStrokeStart extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1145,7 +1176,7 @@ class KeyFrameStrokeEnd extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1162,7 +1193,7 @@ class KeyFrameStrokeOffset extends KeyFrameNumeric { } return null; } - + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; From bc666310bbe2493bd15d924974a452de38a9dd45 Mon Sep 17 00:00:00 2001 From: Luigi Rosso Date: Wed, 12 Jun 2019 17:42:48 -0700 Subject: [PATCH 3/4] Cleanup. --- flare_dart/lib/animation/actor_animation.dart | 197 ++---------------- .../lib/animation/interpolation/hold.dart | 3 +- .../lib/animation/interpolation/linear.dart | 3 +- flare_dart/lib/animation/keyframe.dart | 124 +++++++---- 4 files changed, 104 insertions(+), 223 deletions(-) diff --git a/flare_dart/lib/animation/actor_animation.dart b/flare_dart/lib/animation/actor_animation.dart index 22527c3..3dcc4b6 100644 --- a/flare_dart/lib/animation/actor_animation.dart +++ b/flare_dart/lib/animation/actor_animation.dart @@ -1,9 +1,10 @@ -import "../stream_reader.dart"; +import "../actor_artboard.dart"; import "../actor_component.dart"; import "../actor_event.dart"; -import "../actor_artboard.dart"; -import "property_types.dart"; +import "../stream_reader.dart"; import "keyframe.dart"; +import "property_types.dart"; + typedef KeyFrame KeyFrameReader(StreamReader reader, ActorComponent component); @@ -26,13 +27,6 @@ class PropertyAnimation { } PropertyAnimation propertyAnimation = PropertyAnimation(); int type = propertyBlock.blockType; - // Wish there were a way do to this in Dart without having to create my own hash set. - // if(!Enum.IsDefined(typeof(PropertyTypes), type)) - // { - // return null; - // } - // else - // { propertyAnimation._type = type; KeyFrameReader keyFrameReader; @@ -167,7 +161,7 @@ class PropertyAnimation { } void apply(double time, ActorComponent component, double mix) { - if (_keyFrames.length == 0) { + if (_keyFrames.isEmpty) { return; } @@ -180,7 +174,7 @@ class PropertyAnimation { int end = _keyFrames.length - 1; while (start <= end) { - mid = ((start + end) >> 1); + mid = (start + end) >> 1; element = _keyFrames[mid].time; if (element < time) { start = mid + 1; @@ -243,7 +237,7 @@ class ComponentAnimation { } void apply(double time, List components, double mix) { - for (PropertyAnimation propertyAnimation in _properties) { + for (final PropertyAnimation propertyAnimation in _properties) { if (propertyAnimation != null) { propertyAnimation.apply(time, components[_componentIndex], mix); } @@ -296,34 +290,21 @@ class ActorAnimation { List _components; List _triggerComponents; - String get name { - return _name; - } + String get name => _name; - bool get isLooping { - return _isLooping; - } + int get fps => _fps; - double get duration { - return _duration; - } + bool get isLooping => _isLooping; - List get animatedComponents { - return _components; - } + double get duration => _duration; + + List get animatedComponents => _components; - //Animation.prototype.triggerEvents = function(actorComponents, fromTime, toTime, triggered) - /* - name:component._Name, - component:component, - propertyType:property._Type, - keyFrameTime:toTime, - elapsed:0*/ void triggerEvents(List components, double fromTime, double toTime, List triggerEvents) { for (int i = 0; i < _triggerComponents.length; i++) { ComponentAnimation keyedComponent = _triggerComponents[i]; - for (PropertyAnimation property in keyedComponent.properties) { + for (final PropertyAnimation property in keyedComponent.properties) { switch (property.propertyType) { case PropertyTypes.Trigger: List keyFrames = property.keyFrames; @@ -342,7 +323,7 @@ class ActorAnimation { int end = kfl - 1; while (start <= end) { - mid = ((start + end) >> 1); + mid = (start + end) >> 1; element = keyFrames[mid].time; if (element < toTime) { start = mid + 1; @@ -357,7 +338,6 @@ class ActorAnimation { idx = start; } - //int idx = keyFrameLocation(toTime, keyFrames, 0, keyFrames.length-1); if (idx == 0) { if (kfl > 0 && keyFrames[0].time == toTime) { ActorComponent component = @@ -408,6 +388,7 @@ class ActorAnimation { StreamReader reader, List components) { ActorAnimation animation = ActorAnimation(); animation._name = reader.readString("name"); + print("NAME ${animation._name}"); animation._fps = reader.readUint8("fps"); animation._duration = reader.readFloat32("duration"); animation._isLooping = reader.readBool("isLooping"); @@ -415,9 +396,10 @@ class ActorAnimation { reader.openArray("keyed"); int numKeyedComponents = reader.readUint16Length(); - // We distinguish between animated and triggered components as ActorEvents - // are currently only used to trigger events and don't need the full animation - // cycle. This lets them optimize them out of the regular animation cycle. + // We distinguish between animated and triggered components as ActorEvents + // are currently only used to trigger events and don't need the full + // animation cycle. This lets them optimize them out of the regular animation + // cycle. int animatedComponentCount = 0; int triggerComponentCount = 0; @@ -468,142 +450,3 @@ class ActorAnimation { return animation; } } - -// class ActorAnimationInstance -// { -// Actor _actor; -// ActorAnimation _animation; -// double _time; -// double _min; -// double _max; -// double _range; -// bool loop; - -// event EventHandler AnimationEvent; - -// ActorAnimationInstance(Actor actor, ActorAnimation animation) -// { -// _actor = actor; -// _animation = animation; -// _time = 0.0; -// _min = 0.0; -// _max = animation.Duration; -// _range = _max - _min; -// loop = animation.IsLooping; -// } - -// double get minTime -// { -// return _min; -// } - -// double get maxTime -// { -// return _max; -// } - -// double get time -// { -// return _time; -// } - -// set time(double value) -// { -// double delta = value - _time; -// double time = _time + (delta % _range); - -// if(time < _min) -// { -// if(loop) -// { -// time = _max - (_min - time); -// } -// else -// { -// time = _min; -// } -// } -// else if(time > _max) -// { -// if(loop) -// { -// time = _min + (time - _max); -// } -// else -// { -// time = _max; -// } -// } -// _time = time; -// } - -// void advance(float seconds) -// { -// List triggeredEvents = new List(); -// float time = _time; -// time += seconds % _range; -// if(time < _min) -// { -// if(loop) -// { -// _animation.TriggerEvents(_actor.components, time, _time, triggeredEvents); -// time = _max - (_min - time); -// _animation.TriggerEvents(_actor.components, time, _max, triggeredEvents); -// } -// else -// { -// time = _min; -// if(_time != time) -// { -// _animation.TriggerEvents(_actor.components, _min, _time, triggeredEvents); -// } -// } -// } -// else if(time > _max) -// { -// if(loop) -// { -// _animation.TriggerEvents(_actor.components, time, _time, triggeredEvents); -// time = _min + (time - _max); -// _animation.TriggerEvents(_actor.components, _min-0.001f, time, triggeredEvents); -// } -// else -// { -// time = _max; -// if(_time != time) -// { -// _animation.TriggerEvents(_actor.components, _time, _max, triggeredEvents); -// } -// } -// } -// else if(time > _time) -// { -// _animation.TriggerEvents(_actor.components, _time, time, triggeredEvents); -// } -// else -// { -// _animation.TriggerEvents(_actor.components, time, _time, triggeredEvents); -// } - -// for(AnimationEventArgs ev in triggeredEvents) -// { -// if (AnimationEvent != null) -// { -// AnimationEvent(this, ev); -// } -// _actor.OnAnimationEvent(ev); -// } -// /*for(var i = 0; i < triggeredEvents.length; i++) -// { -// var event = triggeredEvents[i]; -// this.dispatch("animationEvent", event); -// _actor.dispatch("animationEvent", event); -// }*/ -// _time = time; -// } - -// void Apply(float mix) -// { -// _animation.apply(_time, _actor, mix); -// } -// } diff --git a/flare_dart/lib/animation/interpolation/hold.dart b/flare_dart/lib/animation/interpolation/hold.dart index ce67583..13896b8 100644 --- a/flare_dart/lib/animation/interpolation/hold.dart +++ b/flare_dart/lib/animation/interpolation/hold.dart @@ -1,10 +1,11 @@ import "./interpolator.dart"; class HoldInterpolator extends Interpolator { - static get instance { + static Interpolator get instance { return _instance; } + @override double getEasedMix(double mix) { return 0.0; } diff --git a/flare_dart/lib/animation/interpolation/linear.dart b/flare_dart/lib/animation/interpolation/linear.dart index f57e102..81d0cd7 100644 --- a/flare_dart/lib/animation/interpolation/linear.dart +++ b/flare_dart/lib/animation/interpolation/linear.dart @@ -1,10 +1,11 @@ import "./interpolator.dart"; class LinearInterpolator extends Interpolator { - static get instance { + static Interpolator get instance { return _instance; } + @override double getEasedMix(double mix) { return mix; } diff --git a/flare_dart/lib/animation/keyframe.dart b/flare_dart/lib/animation/keyframe.dart index 0acd1c7..c4254fc 100644 --- a/flare_dart/lib/animation/keyframe.dart +++ b/flare_dart/lib/animation/keyframe.dart @@ -1,24 +1,24 @@ -import '../actor_drawable.dart'; -import "../stream_reader.dart"; -import "../actor_component.dart"; -import "../actor_node.dart"; +import "dart:collection"; +import "dart:typed_data"; + +import "../actor_artboard.dart"; import "../actor_bone_base.dart"; +import "../actor_color.dart"; +import "../actor_component.dart"; import "../actor_constraint.dart"; +import '../actor_drawable.dart'; import "../actor_image.dart"; -import "../actor_artboard.dart"; +import "../actor_node.dart"; import "../actor_node_solo.dart"; -import "../actor_star.dart"; +import "../actor_path.dart"; import "../actor_rectangle.dart"; -import "../math/mat2d.dart"; -import "./interpolation/interpolator.dart"; +import "../actor_star.dart"; +import "../path_point.dart"; +import "../stream_reader.dart"; +import "./interpolation/cubic.dart"; import "./interpolation/hold.dart"; +import "./interpolation/interpolator.dart"; import "./interpolation/linear.dart"; -import "./interpolation/cubic.dart"; -import "dart:collection"; -import "dart:typed_data"; -import "../actor_path.dart"; -import "../path_point.dart"; -import "../actor_color.dart"; enum InterpolationTypes { Hold, Linear, Cubic } @@ -91,6 +91,7 @@ abstract class KeyFrameWithInterpolation extends KeyFrame { return true; } + @override void setNext(KeyFrame frame) { // Null out the interpolator if the next frame doesn't validate. // if(_interpolator != null && !_interpolator.setNextFrame(this, frame)) @@ -112,18 +113,10 @@ abstract class KeyFrameNumeric extends KeyFrameWithInterpolation { return false; } frame._value = reader.readFloat32("value"); - /*if(frame._interpolator != null) - { - // TODO: in the future, this could also be a progression curve. - ValueTimeCurveInterpolator vtci = frame._interpolator as ValueTimeCurveInterpolator; - if(vtci != null) - { - vtci.SetKeyFrameValue(m_Value); - } - }*/ return true; } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { KeyFrameNumeric to = toFrame as KeyFrameNumeric; @@ -134,6 +127,7 @@ abstract class KeyFrameNumeric extends KeyFrameWithInterpolation { setValue(component, _value * (1.0 - f) + to._value * f, mix); } + @override void apply(ActorComponent component, double mix) { setValue(component, _value, mix); } @@ -156,6 +150,7 @@ abstract class KeyFrameInt extends KeyFrameWithInterpolation { return true; } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { KeyFrameNumeric to = toFrame as KeyFrameNumeric; @@ -166,6 +161,7 @@ abstract class KeyFrameInt extends KeyFrameWithInterpolation { setValue(component, _value * (1.0 - f) + to._value * f, mix); } + @override void apply(ActorComponent component, double mix) { setValue(component, _value, mix); } @@ -182,6 +178,7 @@ class KeyFrameIntProperty extends KeyFrameInt { return null; } + @override void setValue(ActorComponent component, double value, double mix) { // TODO //CustomIntProperty node = component as CustomIntProperty; @@ -198,6 +195,7 @@ class KeyFrameFloatProperty extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { // TODO // CustomFloatProperty node = component as CustomFloatProperty; @@ -216,15 +214,17 @@ class KeyFrameStringProperty extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } - + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { // CustomStringProperty prop = component as CustomStringProperty; // prop.value = _value; @@ -242,15 +242,17 @@ class KeyFrameBooleanProperty extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } - + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { // CustomBooleanProperty prop = component as CustomBooleanProperty; // prop.value = _value; @@ -268,15 +270,18 @@ class KeyFrameCollisionEnabledProperty extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { // ActorCollider collider = component as ActorCollider; // collider.isCollisionEnabled = _value; @@ -292,6 +297,7 @@ class KeyFramePosX extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.x = node.x * (1.0 - mix) + value * mix; @@ -307,6 +313,7 @@ class KeyFramePosY extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.y = node.y * (1.0 - mix) + value * mix; @@ -322,6 +329,7 @@ class KeyFrameScaleX extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.scaleX = node.scaleX * (1.0 - mix) + value * mix; @@ -337,6 +345,7 @@ class KeyFrameScaleY extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.scaleY = node.scaleY * (1.0 - mix) + value * mix; @@ -352,6 +361,7 @@ class KeyFrameRotation extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.rotation = node.rotation * (1.0 - mix) + value * mix; @@ -367,6 +377,7 @@ class KeyFrameOpacity extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorNode node = component as ActorNode; node.opacity = node.opacity * (1.0 - mix) + value * mix; @@ -382,6 +393,7 @@ class KeyFrameLength extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorBoneBase bone = component as ActorBoneBase; if (bone == null) { @@ -400,6 +412,7 @@ class KeyFrameConstraintStrength extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorConstraint constraint = component as ActorConstraint; constraint.strength = constraint.strength * (1.0 - mix) + value * mix; @@ -434,19 +447,21 @@ class KeyFrameDrawOrder extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } - + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { ActorArtboard artboard = component.artboard; - for (DrawOrderIndex doi in _orderedNodes) { + for (final DrawOrderIndex doi in _orderedNodes) { ActorComponent component = artboard[doi.componentIndex]; if (component is ActorDrawable) { component.drawOrder = doi.order; @@ -477,10 +492,11 @@ class KeyFrameImageVertices extends KeyFrameWithInterpolation { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } - + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { ActorImage imageNode = component as ActorImage; @@ -510,6 +526,7 @@ class KeyFrameImageVertices extends KeyFrameWithInterpolation { imageNode.invalidateDrawable(); } + @override void apply(ActorComponent component, double mix) { ActorImage imageNode = component as ActorImage; int l = _vertices.length; @@ -538,13 +555,14 @@ class KeyFrameTrigger extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } - + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) {} - + @override void apply(ActorComponent component, double mix) {} } @@ -560,15 +578,17 @@ class KeyFrameActiveChild extends KeyFrame { return frame; } + @override void setNext(KeyFrame frame) { // No Interpolation } - + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { apply(component, mix); } + @override void apply(ActorComponent component, double mix) { ActorNodeSolo soloNode = component as ActorNodeSolo; soloNode.activeChildIndex = _value; @@ -584,6 +604,7 @@ class KeyFrameSequence extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorImage node = component as ActorImage; int frameIndex = value.floor() % node.sequenceFrames.length; @@ -611,10 +632,11 @@ class KeyFrameFillColor extends KeyFrameWithInterpolation { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } - + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { ActorColor ac = component as ActorColor; @@ -639,6 +661,7 @@ class KeyFrameFillColor extends KeyFrameWithInterpolation { ac.markPaintDirty(); } + @override void apply(ActorComponent component, double mix) { ActorColor ac = component as ActorColor; int l = _value.length; @@ -678,7 +701,7 @@ class KeyFramePathVertices extends KeyFrameWithInterpolation { frame._vertices = Float32List(length); int readIdx = 0; reader.openArray("value"); - for (PathPoint point in pathNode.points) { + for (final PathPoint point in pathNode.points) { frame._vertices[readIdx++] = reader.readFloat32("translationX"); frame._vertices[readIdx++] = reader.readFloat32("translationY"); if (point.pointType == PointType.Straight) { @@ -698,10 +721,11 @@ class KeyFramePathVertices extends KeyFrameWithInterpolation { return frame; } + @override void setNext(KeyFrame frame) { // Do nothing. } - + @override void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { ActorPath path = component as ActorPath; @@ -727,6 +751,7 @@ class KeyFramePathVertices extends KeyFrameWithInterpolation { path.markVertexDeformDirty(); } + @override void apply(ActorComponent component, double mix) { ActorPath path = component as ActorPath; int l = _vertices.length; @@ -755,6 +780,7 @@ class KeyFramePaintOpacity extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorPaint node = component as ActorPaint; node.opacity = node.opacity * (1.0 - mix) + value * mix; @@ -778,7 +804,7 @@ class KeyFrameStrokeColor extends KeyFrameWithInterpolation { } @override - applyInterpolation( + void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { ColorStroke cs = component as ColorStroke; Float32List wr = cs.color; @@ -803,7 +829,7 @@ class KeyFrameStrokeColor extends KeyFrameWithInterpolation { } @override - apply(ActorComponent component, double mix) { + void apply(ActorComponent component, double mix) { ColorStroke node = component as ColorStroke; Float32List wr = node.color; int len = wr.length; @@ -830,6 +856,7 @@ class KeyFrameCornerRadius extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { ActorRectangle node = component as ActorRectangle; node.radius = node.radius * (1.0 - mix) + value * mix; @@ -838,7 +865,7 @@ class KeyFrameCornerRadius extends KeyFrameNumeric { class KeyFrameGradient extends KeyFrameWithInterpolation { Float32List _value; - get value => _value; + Float32List get value => _value; static KeyFrame read(StreamReader reader, ActorComponent component) { KeyFrameGradient frame = KeyFrameGradient(); @@ -851,7 +878,7 @@ class KeyFrameGradient extends KeyFrameWithInterpolation { } @override - applyInterpolation( + void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { GradientColor gradient = component as GradientColor; Float32List v = (toFrame as KeyFrameGradient)._value; @@ -877,7 +904,8 @@ class KeyFrameGradient extends KeyFrameWithInterpolation { } else { double imix = 1.0 - mix; - // Mix : first interpolate the KeyFrames, and then mix on top of the current value. + // Mix : first interpolate the KeyFrames, and then mix on top + // of the current value. double val = _value[ridx] * fi + v[ridx] * f; gradient.start[0] = gradient.start[0] * imix + val * mix; ridx++; @@ -906,7 +934,7 @@ class KeyFrameGradient extends KeyFrameWithInterpolation { } @override - apply(ActorComponent component, double mix) { + void apply(ActorComponent component, double mix) { GradientColor gradient = component as GradientColor; int ridx = 0; @@ -940,7 +968,7 @@ class KeyFrameGradient extends KeyFrameWithInterpolation { class KeyFrameRadial extends KeyFrameWithInterpolation { Float32List _value; - get value => _value; + Float32List get value => _value; static KeyFrame read(StreamReader reader, ActorComponent component) { KeyFrameRadial frame = KeyFrameRadial(); @@ -953,7 +981,7 @@ class KeyFrameRadial extends KeyFrameWithInterpolation { } @override - applyInterpolation( + void applyInterpolation( ActorComponent component, double time, KeyFrame toFrame, double mix) { RadialGradientColor radial = component as RadialGradientColor; Float32List v = (toFrame as KeyFrameRadial)._value; @@ -980,7 +1008,8 @@ class KeyFrameRadial extends KeyFrameWithInterpolation { } else { double imix = 1.0 - mix; - // Mix : first interpolate the KeyFrames, and then mix on top of the current value. + // Mix : first interpolate the KeyFrames, and then mix on top of the + // current value. double val = _value[ridx] * fi + v[ridx] * f; radial.secondaryRadiusScale = _value[ridx] * fi + v[ridx++] * f; val = _value[ridx] * fi + v[ridx] * f; @@ -1004,7 +1033,7 @@ class KeyFrameRadial extends KeyFrameWithInterpolation { } @override - apply(ActorComponent component, double mix) { + void apply(ActorComponent component, double mix) { RadialGradientColor radial = component as RadialGradientColor; int ridx = 0; @@ -1047,6 +1076,7 @@ class KeyFrameShapeWidth extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1065,6 +1095,7 @@ class KeyFrameShapeHeight extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1083,6 +1114,7 @@ class KeyFrameStrokeWidth extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; ActorStroke stroke = component as ActorStroke; @@ -1099,6 +1131,7 @@ class KeyFrameInnerRadius extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1116,6 +1149,7 @@ class KeyFrameStrokeStart extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1133,6 +1167,7 @@ class KeyFrameStrokeEnd extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; @@ -1150,6 +1185,7 @@ class KeyFrameStrokeOffset extends KeyFrameNumeric { return null; } + @override void setValue(ActorComponent component, double value, double mix) { if (component == null) return; From 865e090c93a0d0ac92dac2b236054bef4b091d71 Mon Sep 17 00:00:00 2001 From: Umberto Sonnino Date: Fri, 14 Jun 2019 01:02:03 +0200 Subject: [PATCH 4/4] Use different logic for split trim paths #95 --- flare_flutter/lib/flare.dart | 1 - flare_flutter/lib/trim_path.dart | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/flare_flutter/lib/flare.dart b/flare_flutter/lib/flare.dart index 9d6d743..607bb46 100644 --- a/flare_flutter/lib/flare.dart +++ b/flare_flutter/lib/flare.dart @@ -8,7 +8,6 @@ import 'dart:ui' as ui; import 'package:flare_dart/actor_flags.dart'; import 'package:flare_dart/actor_image.dart'; import 'package:flare_dart/math/aabb.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; diff --git a/flare_flutter/lib/trim_path.dart b/flare_flutter/lib/trim_path.dart index ea546b9..6acdbac 100644 --- a/flare_flutter/lib/trim_path.dart +++ b/flare_flutter/lib/trim_path.dart @@ -2,10 +2,11 @@ library flare_flutter; import 'dart:ui'; -double _appendPathSegmentSequential( - PathMetrics metrics, Path to, double offset, double start, double stop) { +double _appendPathSegmentSequential(Iterator metricsIterator, + Path to, double offset, double start, double stop) { double nextOffset = offset; - for (final PathMetric metric in metrics) { + do { + PathMetric metric = metricsIterator.current; nextOffset = offset + metric.length; if (start < nextOffset) { Path extracted = metric.extractPath(start - offset, stop - offset); @@ -17,7 +18,7 @@ double _appendPathSegmentSequential( } } offset = nextOffset; - } + } while (metricsIterator.moveNext()); return offset; } @@ -49,19 +50,21 @@ Path _trimPathSequential( double trimStop = totalLength * stopT; double offset = 0.0; + Iterator metricsIterator = metrics.iterator; + metricsIterator.moveNext(); if (complement) { if (trimStart > 0.0) { - offset = - _appendPathSegmentSequential(metrics, result, offset, 0.0, trimStart); + offset = _appendPathSegmentSequential( + metricsIterator, result, offset, 0.0, trimStart); } if (trimStop < totalLength) { offset = _appendPathSegmentSequential( - metrics, result, offset, trimStop, totalLength); + metricsIterator, result, offset, trimStop, totalLength); } } else { if (trimStart < trimStop) { offset = _appendPathSegmentSequential( - metrics, result, offset, trimStart, trimStop); + metricsIterator, result, offset, trimStart, trimStop); } }