mirror of
https://github.com/rive-app/rive-flutter.git
synced 2025-05-17 21:36:06 +08:00
Add elastic interpolation to Flutter runtime
Fixes crash @LauraRive caught when editing a file with nested artboards. Diffs= 389618e94 Add elastic interpolation to Flutter runtime (#6158) Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
This commit is contained in:
@ -1 +1 @@
|
||||
6d9aa017961638f7576a2ea52a8928c813e28dbb
|
||||
389618e94df7e4bc002a06cb84ce1ec9ac3b0ab0
|
||||
|
@ -1,7 +1,6 @@
|
||||
## 0.12.0
|
||||
## 0.12.1
|
||||
|
||||
- Increase HTTP dependency range for Rive and Rive Common
|
||||
- Update api for loading rive files, simplifying loading external images & fonts.
|
||||
- Elastic easing.
|
||||
|
||||
## 0.11.17
|
||||
|
||||
|
@ -50,12 +50,11 @@ linter:
|
||||
- hash_and_equals
|
||||
- implementation_imports
|
||||
# - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
|
||||
- iterable_contains_unrelated_type
|
||||
- collection_methods_unrelated_type
|
||||
- join_return_with_assignment
|
||||
- library_names
|
||||
- library_prefixes
|
||||
- lines_longer_than_80_chars
|
||||
- list_remove_unrelated_type
|
||||
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
|
||||
- no_adjacent_strings_in_list
|
||||
- no_duplicate_case_values
|
||||
|
@ -2,6 +2,7 @@
|
||||
// lib/src/generated/animation/cubic_ease_interpolator_base.dart.
|
||||
// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/generated/animation/keyframe_interpolator_base.dart';
|
||||
import 'package:rive/src/rive_core/animation/cubic_interpolator.dart';
|
||||
|
||||
abstract class CubicEaseInterpolatorBase extends CubicInterpolator {
|
||||
@ -9,6 +10,9 @@ abstract class CubicEaseInterpolatorBase extends CubicInterpolator {
|
||||
@override
|
||||
int get coreType => CubicEaseInterpolatorBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes =>
|
||||
{CubicEaseInterpolatorBase.typeKey, CubicInterpolatorBase.typeKey};
|
||||
Set<int> get coreTypes => {
|
||||
CubicEaseInterpolatorBase.typeKey,
|
||||
CubicInterpolatorBase.typeKey,
|
||||
KeyFrameInterpolatorBase.typeKey
|
||||
};
|
||||
}
|
||||
|
@ -3,13 +3,15 @@
|
||||
// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyframe_interpolator.dart';
|
||||
|
||||
abstract class CubicInterpolatorBase<T extends CoreContext> extends Core<T> {
|
||||
abstract class CubicInterpolatorBase extends KeyFrameInterpolator {
|
||||
static const int typeKey = 139;
|
||||
@override
|
||||
int get coreType => CubicInterpolatorBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes => {CubicInterpolatorBase.typeKey};
|
||||
Set<int> get coreTypes =>
|
||||
{CubicInterpolatorBase.typeKey, KeyFrameInterpolatorBase.typeKey};
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// X1 field with key 63.
|
||||
@ -101,6 +103,7 @@ abstract class CubicInterpolatorBase<T extends CoreContext> extends Core<T> {
|
||||
|
||||
@override
|
||||
void copy(Core source) {
|
||||
super.copy(source);
|
||||
if (source is CubicInterpolatorBase) {
|
||||
_x1 = source._x1;
|
||||
_y1 = source._y1;
|
||||
|
@ -2,6 +2,7 @@
|
||||
// lib/src/generated/animation/cubic_value_interpolator_base.dart.
|
||||
// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/generated/animation/keyframe_interpolator_base.dart';
|
||||
import 'package:rive/src/rive_core/animation/cubic_interpolator.dart';
|
||||
|
||||
abstract class CubicValueInterpolatorBase extends CubicInterpolator {
|
||||
@ -9,6 +10,9 @@ abstract class CubicValueInterpolatorBase extends CubicInterpolator {
|
||||
@override
|
||||
int get coreType => CubicValueInterpolatorBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes =>
|
||||
{CubicValueInterpolatorBase.typeKey, CubicInterpolatorBase.typeKey};
|
||||
Set<int> get coreTypes => {
|
||||
CubicValueInterpolatorBase.typeKey,
|
||||
CubicInterpolatorBase.typeKey,
|
||||
KeyFrameInterpolatorBase.typeKey
|
||||
};
|
||||
}
|
||||
|
97
lib/src/generated/animation/elastic_interpolator_base.dart
Normal file
97
lib/src/generated/animation/elastic_interpolator_base.dart
Normal file
@ -0,0 +1,97 @@
|
||||
// Core automatically generated
|
||||
// lib/src/generated/animation/elastic_interpolator_base.dart.
|
||||
// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyframe_interpolator.dart';
|
||||
|
||||
abstract class ElasticInterpolatorBase extends KeyFrameInterpolator {
|
||||
static const int typeKey = 174;
|
||||
@override
|
||||
int get coreType => ElasticInterpolatorBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes =>
|
||||
{ElasticInterpolatorBase.typeKey, KeyFrameInterpolatorBase.typeKey};
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// EasingValue field with key 405.
|
||||
static const int easingValuePropertyKey = 405;
|
||||
static const int easingValueInitialValue = 1;
|
||||
int _easingValue = easingValueInitialValue;
|
||||
int get easingValue => _easingValue;
|
||||
|
||||
/// Change the [_easingValue] field value.
|
||||
/// [easingValueChanged] will be invoked only if the field's value has
|
||||
/// changed.
|
||||
set easingValue(int value) {
|
||||
if (_easingValue == value) {
|
||||
return;
|
||||
}
|
||||
int from = _easingValue;
|
||||
_easingValue = value;
|
||||
if (hasValidated) {
|
||||
easingValueChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void easingValueChanged(int from, int to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Amplitude field with key 406.
|
||||
static const int amplitudePropertyKey = 406;
|
||||
static const double amplitudeInitialValue = 1;
|
||||
double _amplitude = amplitudeInitialValue;
|
||||
|
||||
/// The amplitude for the easing expressed as a percentage of the change.
|
||||
double get amplitude => _amplitude;
|
||||
|
||||
/// Change the [_amplitude] field value.
|
||||
/// [amplitudeChanged] will be invoked only if the field's value has changed.
|
||||
set amplitude(double value) {
|
||||
if (_amplitude == value) {
|
||||
return;
|
||||
}
|
||||
double from = _amplitude;
|
||||
_amplitude = value;
|
||||
if (hasValidated) {
|
||||
amplitudeChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void amplitudeChanged(double from, double to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Period field with key 407.
|
||||
static const int periodPropertyKey = 407;
|
||||
static const double periodInitialValue = 1;
|
||||
double _period = periodInitialValue;
|
||||
|
||||
/// The period of the elastic expressed as a percentage of the time
|
||||
/// difference.
|
||||
double get period => _period;
|
||||
|
||||
/// Change the [_period] field value.
|
||||
/// [periodChanged] will be invoked only if the field's value has changed.
|
||||
set period(double value) {
|
||||
if (_period == value) {
|
||||
return;
|
||||
}
|
||||
double from = _period;
|
||||
_period = value;
|
||||
if (hasValidated) {
|
||||
periodChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void periodChanged(double from, double to);
|
||||
|
||||
@override
|
||||
void copy(Core source) {
|
||||
super.copy(source);
|
||||
if (source is ElasticInterpolatorBase) {
|
||||
_easingValue = source._easingValue;
|
||||
_amplitude = source._amplitude;
|
||||
_period = source._period;
|
||||
}
|
||||
}
|
||||
}
|
13
lib/src/generated/animation/keyframe_interpolator_base.dart
Normal file
13
lib/src/generated/animation/keyframe_interpolator_base.dart
Normal file
@ -0,0 +1,13 @@
|
||||
// Core automatically generated
|
||||
// lib/src/generated/animation/keyframe_interpolator_base.dart.
|
||||
// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/core/core.dart';
|
||||
|
||||
abstract class KeyFrameInterpolatorBase<T extends CoreContext> extends Core<T> {
|
||||
static const int typeKey = 175;
|
||||
@override
|
||||
int get coreType => KeyFrameInterpolatorBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes => {KeyFrameInterpolatorBase.typeKey};
|
||||
}
|
@ -47,6 +47,7 @@ import 'package:rive/src/rive_core/animation/blend_state_transition.dart';
|
||||
import 'package:rive/src/rive_core/animation/cubic_ease_interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/cubic_interpolator_component.dart';
|
||||
import 'package:rive/src/rive_core/animation/cubic_value_interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/elastic_interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/entry_state.dart';
|
||||
import 'package:rive/src/rive_core/animation/exit_state.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyed_object.dart';
|
||||
@ -240,6 +241,8 @@ class RiveCoreContext {
|
||||
return BlendStateDirect();
|
||||
case NestedStateMachineBase.typeKey:
|
||||
return NestedStateMachine();
|
||||
case ElasticInterpolatorBase.typeKey:
|
||||
return ElasticInterpolator();
|
||||
case ExitStateBase.typeKey:
|
||||
return ExitState();
|
||||
case NestedNumberBase.typeKey:
|
||||
@ -878,6 +881,21 @@ class RiveCoreContext {
|
||||
object.occursValue = value;
|
||||
}
|
||||
break;
|
||||
case ElasticInterpolatorBase.easingValuePropertyKey:
|
||||
if (object is ElasticInterpolatorBase && value is int) {
|
||||
object.easingValue = value;
|
||||
}
|
||||
break;
|
||||
case ElasticInterpolatorBase.amplitudePropertyKey:
|
||||
if (object is ElasticInterpolatorBase && value is double) {
|
||||
object.amplitude = value;
|
||||
}
|
||||
break;
|
||||
case ElasticInterpolatorBase.periodPropertyKey:
|
||||
if (object is ElasticInterpolatorBase && value is double) {
|
||||
object.period = value;
|
||||
}
|
||||
break;
|
||||
case NestedNumberBase.nestedValuePropertyKey:
|
||||
if (object is NestedNumberBase && value is double) {
|
||||
object.nestedValue = value;
|
||||
@ -1718,6 +1736,7 @@ class RiveCoreContext {
|
||||
case StateTransitionBase.interpolatorIdPropertyKey:
|
||||
case StateMachineFireEventBase.eventIdPropertyKey:
|
||||
case StateMachineFireEventBase.occursValuePropertyKey:
|
||||
case ElasticInterpolatorBase.easingValuePropertyKey:
|
||||
case BlendState1DBase.inputIdPropertyKey:
|
||||
case BlendStateTransitionBase.exitBlendAnimationIdPropertyKey:
|
||||
case StrokeBase.capPropertyKey:
|
||||
@ -1795,6 +1814,8 @@ class RiveCoreContext {
|
||||
case CubicInterpolatorComponentBase.y2PropertyKey:
|
||||
case ListenerNumberChangeBase.valuePropertyKey:
|
||||
case KeyFrameDoubleBase.valuePropertyKey:
|
||||
case ElasticInterpolatorBase.amplitudePropertyKey:
|
||||
case ElasticInterpolatorBase.periodPropertyKey:
|
||||
case NestedNumberBase.nestedValuePropertyKey:
|
||||
case BlendAnimation1DBase.valuePropertyKey:
|
||||
case NestedRemapAnimationBase.timePropertyKey:
|
||||
@ -2063,6 +2084,8 @@ class RiveCoreContext {
|
||||
return (object as StateMachineFireEventBase).eventId;
|
||||
case StateMachineFireEventBase.occursValuePropertyKey:
|
||||
return (object as StateMachineFireEventBase).occursValue;
|
||||
case ElasticInterpolatorBase.easingValuePropertyKey:
|
||||
return (object as ElasticInterpolatorBase).easingValue;
|
||||
case BlendState1DBase.inputIdPropertyKey:
|
||||
return (object as BlendState1DBase).inputId;
|
||||
case BlendStateTransitionBase.exitBlendAnimationIdPropertyKey:
|
||||
@ -2221,6 +2244,10 @@ class RiveCoreContext {
|
||||
return (object as ListenerNumberChangeBase).value;
|
||||
case KeyFrameDoubleBase.valuePropertyKey:
|
||||
return (object as KeyFrameDoubleBase).value;
|
||||
case ElasticInterpolatorBase.amplitudePropertyKey:
|
||||
return (object as ElasticInterpolatorBase).amplitude;
|
||||
case ElasticInterpolatorBase.periodPropertyKey:
|
||||
return (object as ElasticInterpolatorBase).period;
|
||||
case NestedNumberBase.nestedValuePropertyKey:
|
||||
return (object as NestedNumberBase).nestedValue;
|
||||
case BlendAnimation1DBase.valuePropertyKey:
|
||||
@ -2783,6 +2810,11 @@ class RiveCoreContext {
|
||||
object.occursValue = value;
|
||||
}
|
||||
break;
|
||||
case ElasticInterpolatorBase.easingValuePropertyKey:
|
||||
if (object is ElasticInterpolatorBase) {
|
||||
object.easingValue = value;
|
||||
}
|
||||
break;
|
||||
case BlendState1DBase.inputIdPropertyKey:
|
||||
if (object is BlendState1DBase) {
|
||||
object.inputId = value;
|
||||
@ -3168,6 +3200,16 @@ class RiveCoreContext {
|
||||
object.value = value;
|
||||
}
|
||||
break;
|
||||
case ElasticInterpolatorBase.amplitudePropertyKey:
|
||||
if (object is ElasticInterpolatorBase) {
|
||||
object.amplitude = value;
|
||||
}
|
||||
break;
|
||||
case ElasticInterpolatorBase.periodPropertyKey:
|
||||
if (object is ElasticInterpolatorBase) {
|
||||
object.period = value;
|
||||
}
|
||||
break;
|
||||
case NestedNumberBase.nestedValuePropertyKey:
|
||||
if (object is NestedNumberBase) {
|
||||
object.nestedValue = value;
|
||||
|
@ -43,8 +43,8 @@ class CubicEaseInterpolator extends CubicEaseInterpolatorBase {
|
||||
from + (to - from) * _ease.transform(value);
|
||||
|
||||
@override
|
||||
void updateStoredCubic() {
|
||||
void updateInterpolator() {
|
||||
_ease = CubicEase.make(x1, y1, x2, y2);
|
||||
super.updateStoredCubic();
|
||||
super.updateInterpolator();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/animation/cubic_interpolator_base.dart';
|
||||
import 'package:rive/src/rive_core/animation/interpolator.dart';
|
||||
import 'package:rive/src/rive_core/artboard.dart';
|
||||
|
||||
export 'package:rive/src/generated/animation/cubic_interpolator_base.dart';
|
||||
|
||||
@ -31,7 +30,7 @@ abstract class CubicInterface {
|
||||
|
||||
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
|
||||
abstract class CubicInterpolator extends CubicInterpolatorBase
|
||||
implements Interpolator, CubicInterface {
|
||||
implements CubicInterface {
|
||||
@override
|
||||
bool equalParameters(Interpolator other) {
|
||||
if (other is CubicInterpolator) {
|
||||
@ -43,9 +42,6 @@ abstract class CubicInterpolator extends CubicInterpolatorBase
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
void onAdded() => updateStoredCubic();
|
||||
|
||||
@override
|
||||
void onAddedDirty() {}
|
||||
|
||||
@ -56,30 +52,16 @@ abstract class CubicInterpolator extends CubicInterpolatorBase
|
||||
double transformValue(double from, double to, double value);
|
||||
|
||||
@override
|
||||
void x1Changed(double from, double to) => updateStoredCubic();
|
||||
void x1Changed(double from, double to) => updateInterpolator();
|
||||
|
||||
@override
|
||||
void x2Changed(double from, double to) => updateStoredCubic();
|
||||
void x2Changed(double from, double to) => updateInterpolator();
|
||||
|
||||
@override
|
||||
void y1Changed(double from, double to) => updateStoredCubic();
|
||||
void y1Changed(double from, double to) => updateInterpolator();
|
||||
|
||||
@override
|
||||
void y2Changed(double from, double to) => updateStoredCubic();
|
||||
|
||||
@protected
|
||||
void updateStoredCubic() {}
|
||||
|
||||
@override
|
||||
bool import(ImportStack stack) {
|
||||
var artboardHelper = stack.latest<ArtboardImporter>(ArtboardBase.typeKey);
|
||||
if (artboardHelper == null) {
|
||||
return false;
|
||||
}
|
||||
artboardHelper.addComponent(this);
|
||||
|
||||
return super.import(stack);
|
||||
}
|
||||
void y2Changed(double from, double to) => updateInterpolator();
|
||||
}
|
||||
|
||||
// Helper to convert a factor in cubic space to t value. We use this to compute
|
||||
|
@ -50,14 +50,14 @@ class CubicValueInterpolator extends CubicValueInterpolatorBase {
|
||||
if (_from != from || _to != to) {
|
||||
_from = from;
|
||||
_to = to;
|
||||
updateStoredCubic();
|
||||
updateInterpolator();
|
||||
}
|
||||
return _cubic.transform(value);
|
||||
}
|
||||
|
||||
@override
|
||||
void updateStoredCubic() {
|
||||
void updateInterpolator() {
|
||||
_cubic = _CubicValue(x1, x2, _from, y1, y2, _to);
|
||||
super.updateStoredCubic();
|
||||
super.updateInterpolator();
|
||||
}
|
||||
}
|
||||
|
146
lib/src/rive_core/animation/elastic_interpolator.dart
Normal file
146
lib/src/rive_core/animation/elastic_interpolator.dart
Normal file
@ -0,0 +1,146 @@
|
||||
// ignore_for_file: parameter_assignments
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/animation/elastic_interpolator_base.dart';
|
||||
import 'package:rive/src/rive_core/animation/interpolator.dart';
|
||||
import 'package:rive/src/rive_core/artboard.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
|
||||
export 'package:rive/src/generated/animation/elastic_interpolator_base.dart';
|
||||
|
||||
enum Easing {
|
||||
easeIn,
|
||||
easeOut,
|
||||
easeInOut,
|
||||
}
|
||||
|
||||
class ElasticEase {
|
||||
final double amplitude;
|
||||
final double s;
|
||||
final double period;
|
||||
|
||||
ElasticEase(this.amplitude, this.period)
|
||||
: s = amplitude < 1.0
|
||||
? period / 4
|
||||
: period / (2 * pi) * asin(1.0 / amplitude);
|
||||
|
||||
double computeActualAmplitude(double time) {
|
||||
if (amplitude < 1.0) {
|
||||
/// We use this when the amplitude is less than 1.0 (amplitude is
|
||||
/// described as factor of change in value). We also precompute s which is
|
||||
/// the effective starting period we use to align the decaying sin with
|
||||
/// our keyframe.
|
||||
double t = s.abs();
|
||||
if (time.abs() < t) {
|
||||
double l = time.abs() / t;
|
||||
return (amplitude * l) + (1.0 - l);
|
||||
}
|
||||
}
|
||||
|
||||
return amplitude;
|
||||
}
|
||||
|
||||
double easeOut(double value) {
|
||||
var time = value;
|
||||
|
||||
var actualAmplitude = computeActualAmplitude(time);
|
||||
|
||||
return (actualAmplitude *
|
||||
pow(2, 10 * -time) *
|
||||
sin((time - s) * (2 * pi) / period)) +
|
||||
1;
|
||||
}
|
||||
|
||||
double easeIn(double value) {
|
||||
var time = value - 1;
|
||||
|
||||
var actualAmplitude = computeActualAmplitude(time);
|
||||
|
||||
return -(actualAmplitude *
|
||||
pow(2, 10 * time) *
|
||||
sin((-time - s) * (2 * pi) / period));
|
||||
}
|
||||
|
||||
double easeInOut(double value) {
|
||||
var time = value * 2 - 1;
|
||||
var actualAmplitude = computeActualAmplitude(time);
|
||||
if (time < 0) {
|
||||
return -0.5 *
|
||||
actualAmplitude *
|
||||
pow(2, 10 * time) *
|
||||
sin((-time - s) * (2 * pi) / period);
|
||||
} else {
|
||||
return 0.5 *
|
||||
(actualAmplitude *
|
||||
pow(2, 10 * -time) *
|
||||
sin((time - s) * (2 * pi) / period)) +
|
||||
1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ElasticInterpolator extends ElasticInterpolatorBase {
|
||||
ElasticEase _elastic = ElasticEase(1.0, 0.5);
|
||||
|
||||
@override
|
||||
bool equalParameters(Interpolator other) {
|
||||
if (other is ElasticInterpolator) {
|
||||
return easingValue == other.easingValue &&
|
||||
amplitude == other.amplitude &&
|
||||
period == other.period;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
void onAddedDirty() {}
|
||||
|
||||
@override
|
||||
double transform(double value) {
|
||||
switch (easing) {
|
||||
case Easing.easeIn:
|
||||
return _elastic.easeIn(value);
|
||||
case Easing.easeOut:
|
||||
return _elastic.easeOut(value);
|
||||
case Easing.easeInOut:
|
||||
return _elastic.easeInOut(value);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double transformValue(double from, double to, double value) {
|
||||
var f = transform(value);
|
||||
return from + (to - from) * f;
|
||||
}
|
||||
|
||||
@override
|
||||
bool import(ImportStack stack) {
|
||||
var artboardHelper = stack.latest<ArtboardImporter>(ArtboardBase.typeKey);
|
||||
if (artboardHelper == null) {
|
||||
return false;
|
||||
}
|
||||
artboardHelper.addComponent(this);
|
||||
|
||||
return super.import(stack);
|
||||
}
|
||||
|
||||
Easing get easing => enumAt(Easing.values, easingValue);
|
||||
set easing(Easing value) => easingValue = value.index;
|
||||
|
||||
@override
|
||||
void updateInterpolator() {
|
||||
_elastic = ElasticEase(amplitude, period);
|
||||
super.updateInterpolator();
|
||||
}
|
||||
|
||||
@override
|
||||
void amplitudeChanged(double from, double to) => updateInterpolator();
|
||||
|
||||
@override
|
||||
void easingValueChanged(int from, int to) => updateInterpolator();
|
||||
|
||||
@override
|
||||
void periodChanged(double from, double to) => updateInterpolator();
|
||||
}
|
@ -4,6 +4,7 @@ import 'package:rive/src/rive_core/animation/cubic_interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/cubic_value_interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyframe_interpolation.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
|
||||
export 'package:rive/src/generated/animation/interpolating_keyframe_base.dart';
|
||||
|
||||
@ -12,7 +13,7 @@ abstract class InterpolatingKeyFrame extends InterpolatingKeyFrameBase {
|
||||
bool get canInterpolate => true;
|
||||
|
||||
KeyFrameInterpolation get interpolation =>
|
||||
KeyFrameInterpolation.values[interpolationType];
|
||||
enumAt(KeyFrameInterpolation.values, interpolationType);
|
||||
set interpolation(KeyFrameInterpolation value) {
|
||||
interpolationType = value.index;
|
||||
}
|
||||
|
@ -13,4 +13,17 @@ enum KeyFrameInterpolation {
|
||||
/// Cubicly interpolate from incoming to outgoing value based on the
|
||||
/// [CubicInterpolator]'s parameters.
|
||||
cubicValue,
|
||||
|
||||
/// Elastic easing.
|
||||
elastic,
|
||||
}
|
||||
|
||||
extension KeyFrameInterpolationExtension on KeyFrameInterpolation {
|
||||
/// Should this type use the interpolation value field beneath the
|
||||
/// curve preview
|
||||
bool get usesValuesField => [
|
||||
KeyFrameInterpolation.hold,
|
||||
KeyFrameInterpolation.linear,
|
||||
KeyFrameInterpolation.cubic,
|
||||
].contains(this);
|
||||
}
|
||||
|
26
lib/src/rive_core/animation/keyframe_interpolator.dart
Normal file
26
lib/src/rive_core/animation/keyframe_interpolator.dart
Normal file
@ -0,0 +1,26 @@
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/animation/keyframe_interpolator_base.dart';
|
||||
import 'package:rive/src/rive_core/animation/interpolator.dart';
|
||||
import 'package:rive/src/rive_core/artboard.dart';
|
||||
|
||||
export 'package:rive/src/generated/animation/keyframe_interpolator_base.dart';
|
||||
|
||||
abstract class KeyFrameInterpolator extends KeyFrameInterpolatorBase
|
||||
implements Interpolator {
|
||||
@override
|
||||
void onAdded() => updateInterpolator();
|
||||
|
||||
@protected
|
||||
void updateInterpolator() {}
|
||||
|
||||
@override
|
||||
bool import(ImportStack stack) {
|
||||
var artboardHelper = stack.latest<ArtboardImporter>(ArtboardBase.typeKey);
|
||||
if (artboardHelper == null) {
|
||||
return false;
|
||||
}
|
||||
artboardHelper.addComponent(this);
|
||||
|
||||
return super.import(stack);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ library rive_core;
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/animation/state_machine_fire_event_base.dart';
|
||||
import 'package:rive/src/rive_core/animation/state_machine_layer_component.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
|
||||
export 'package:rive/src/generated/animation/state_machine_fire_event_base.dart';
|
||||
|
||||
@ -22,7 +23,7 @@ class StateMachineFireEvent extends StateMachineFireEventBase {
|
||||
void occursValueChanged(int from, int to) {}
|
||||
|
||||
StateMachineFireOccurance get occurs =>
|
||||
StateMachineFireOccurance.values[occursValue];
|
||||
enumAt(StateMachineFireOccurance.values, occursValue);
|
||||
|
||||
@override
|
||||
bool import(ImportStack importStack) {
|
||||
|
@ -15,6 +15,7 @@ import 'package:rive/src/rive_core/animation/loop.dart';
|
||||
import 'package:rive/src/rive_core/animation/state_instance.dart';
|
||||
import 'package:rive/src/rive_core/animation/transition_condition.dart';
|
||||
import 'package:rive/src/rive_core/animation/transition_trigger_condition.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
import 'package:rive/src/rive_core/state_transition_flags.dart';
|
||||
|
||||
export 'package:rive/src/generated/animation/state_transition_base.dart';
|
||||
@ -221,7 +222,7 @@ class StateTransition extends StateTransitionBase {
|
||||
bool get canInterpolate => stateTo is! EntryState;
|
||||
|
||||
KeyFrameInterpolation get interpolation =>
|
||||
KeyFrameInterpolation.values[interpolationType];
|
||||
enumAt(KeyFrameInterpolation.values, interpolationType);
|
||||
set interpolation(KeyFrameInterpolation value) {
|
||||
if (canInterpolate) {
|
||||
interpolationType = value.index;
|
||||
|
@ -113,11 +113,6 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Find all components of a specific type.
|
||||
Iterable<T> components<T>() {
|
||||
return _components.whereType<T>();
|
||||
}
|
||||
|
||||
@override
|
||||
Artboard get artboard => this;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:rive/src/generated/constraints/distance_constraint_base.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
import 'package:rive/src/rive_core/transform_component.dart';
|
||||
import 'package:rive_common/math.dart';
|
||||
|
||||
@ -57,6 +58,7 @@ class DistanceConstraint extends DistanceConstraintBase {
|
||||
@override
|
||||
void modeValueChanged(int from, int to) => markConstraintDirty();
|
||||
|
||||
DistanceConstraintMode get mode => DistanceConstraintMode.values[modeValue];
|
||||
DistanceConstraintMode get mode =>
|
||||
enumAt(DistanceConstraintMode.values, modeValue);
|
||||
set mode(DistanceConstraintMode value) => modeValue = value.index;
|
||||
}
|
||||
|
@ -40,5 +40,4 @@ abstract class TargetedConstraint extends TargetedConstraintBase {
|
||||
super.onAddedDirty();
|
||||
target = context.resolve(targetId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:rive/src/generated/constraints/transform_space_constraint_base.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
import 'package:rive/src/rive_core/transform_space.dart';
|
||||
import 'package:rive_common/math.dart';
|
||||
|
||||
@ -8,7 +9,7 @@ abstract class TransformSpaceConstraint extends TransformSpaceConstraintBase {
|
||||
final TransformComponents componentsA = TransformComponents();
|
||||
final TransformComponents componentsB = TransformComponents();
|
||||
|
||||
TransformSpace get destSpace => TransformSpace.values[destSpaceValue];
|
||||
TransformSpace get destSpace => enumAt(TransformSpace.values, destSpaceValue);
|
||||
set destSpace(TransformSpace value) => destSpaceValue = value.index;
|
||||
|
||||
TransformSpace get sourceSpace => TransformSpace.values[sourceSpaceValue];
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/draw_target_base.dart';
|
||||
import 'package:rive/src/rive_core/drawable.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
|
||||
export 'package:rive/src/generated/draw_target_base.dart';
|
||||
|
||||
@ -23,7 +24,7 @@ class DrawTarget extends DrawTargetBase {
|
||||
}
|
||||
|
||||
DrawTargetPlacement get placement =>
|
||||
DrawTargetPlacement.values[placementValue];
|
||||
enumAt(DrawTargetPlacement.values, placementValue);
|
||||
set placement(DrawTargetPlacement value) => placementValue = value.index;
|
||||
|
||||
@override
|
||||
|
3
lib/src/rive_core/enum_helper.dart
Normal file
3
lib/src/rive_core/enum_helper.dart
Normal file
@ -0,0 +1,3 @@
|
||||
/// Helper for getting a valid enum at an index (or default to the first one).
|
||||
T enumAt<T>(List<T> values, int index) =>
|
||||
index < values.length ? values[index] : values.first;
|
@ -12,7 +12,6 @@ abstract class NestedAnimation<T extends Animation>
|
||||
@override
|
||||
void animationIdChanged(int from, int to) {}
|
||||
|
||||
|
||||
bool get isEnabled;
|
||||
|
||||
/// Returns true when the NestedAnimation needs to keep advancing. Returning
|
||||
|
@ -64,7 +64,6 @@ class NestedArtboard extends NestedArtboardBase {
|
||||
@override
|
||||
void artboardIdChanged(int from, int to) {}
|
||||
|
||||
|
||||
@override
|
||||
void childAdded(Component child) {
|
||||
super.childAdded(child);
|
||||
|
@ -2,6 +2,7 @@ import 'dart:ui';
|
||||
|
||||
import 'package:rive/src/generated/shapes/clipping_shape_base.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
import 'package:rive/src/rive_core/node.dart';
|
||||
import 'package:rive/src/rive_core/shapes/shape.dart';
|
||||
|
||||
@ -10,7 +11,7 @@ export 'package:rive/src/generated/shapes/clipping_shape_base.dart';
|
||||
class ClippingShape extends ClippingShapeBase {
|
||||
final Path clippingPath = Path();
|
||||
final List<Shape> _shapes = [];
|
||||
PathFillType get fillType => PathFillType.values[fillRule];
|
||||
PathFillType get fillType => enumAt(PathFillType.values, fillRule);
|
||||
set fillType(PathFillType type) => fillRule = type.index;
|
||||
|
||||
Node _source = Node.unknown;
|
||||
|
@ -91,7 +91,6 @@ class Image extends ImageBase
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get assetIdPropertyKey => ImageBase.assetIdPropertyKey;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rive/src/generated/shapes/paint/stroke_base.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
import 'package:rive/src/rive_core/shapes/paint/stroke_effect.dart';
|
||||
import 'package:rive/src/rive_core/shapes/shape.dart';
|
||||
import 'package:rive/src/rive_core/shapes/shape_paint_container.dart';
|
||||
@ -31,21 +32,21 @@ class Stroke extends StrokeBase {
|
||||
..strokeJoin = strokeJoin
|
||||
..strokeWidth = thickness;
|
||||
|
||||
StrokeCap get strokeCap => StrokeCap.values[cap];
|
||||
StrokeCap get strokeCap => enumAt(StrokeCap.values, cap);
|
||||
set strokeCap(StrokeCap value) => cap = value.index;
|
||||
|
||||
StrokeJoin get strokeJoin => StrokeJoin.values[join];
|
||||
StrokeJoin get strokeJoin => enumAt(StrokeJoin.values, join);
|
||||
set strokeJoin(StrokeJoin value) => join = value.index;
|
||||
|
||||
@override
|
||||
void capChanged(int from, int to) {
|
||||
paint.strokeCap = StrokeCap.values[to];
|
||||
paint.strokeCap = enumAt(StrokeCap.values, to);
|
||||
parent?.addDirt(ComponentDirt.paint);
|
||||
}
|
||||
|
||||
@override
|
||||
void joinChanged(int from, int to) {
|
||||
paint.strokeJoin = StrokeJoin.values[to];
|
||||
paint.strokeJoin = enumAt(StrokeJoin.values, to);
|
||||
parent?.addDirt(ComponentDirt.paint);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import 'dart:ui';
|
||||
|
||||
import 'package:rive/src/generated/text/text_base.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
import 'package:rive/src/rive_core/text/styled_text.dart';
|
||||
import 'package:rive/src/rive_core/text/text_modifier_group.dart';
|
||||
import 'package:rive/src/rive_core/text/text_style.dart' as rive;
|
||||
@ -170,7 +171,6 @@ class Text extends TextBase with TextStyleContainer {
|
||||
_syncRuns();
|
||||
}
|
||||
|
||||
|
||||
Mat2D get originTransform => Mat2D.multiply(
|
||||
Mat2D(),
|
||||
worldTransform,
|
||||
@ -575,7 +575,7 @@ class Text extends TextBase with TextStyleContainer {
|
||||
markShapeDirty();
|
||||
}
|
||||
|
||||
TextAlign get align => TextAlign.values[alignValue];
|
||||
TextAlign get align => enumAt(TextAlign.values, alignValue);
|
||||
set align(TextAlign value) => alignValue = value.index;
|
||||
|
||||
@override
|
||||
@ -588,7 +588,7 @@ class Text extends TextBase with TextStyleContainer {
|
||||
TextSizing get sizing => TextSizing.values[sizingValue];
|
||||
set sizing(TextSizing value) => sizingValue = value.index;
|
||||
TextOverflow get overflow {
|
||||
return TextOverflow.values[overflowValue];
|
||||
return enumAt(TextOverflow.values, overflowValue);
|
||||
}
|
||||
|
||||
set overflow(TextOverflow value) => overflowValue = value.index;
|
||||
|
@ -7,6 +7,7 @@ import 'package:rive/src/rive_core/animation/cubic_interpolator_component.dart';
|
||||
import 'package:rive/src/rive_core/animation/interpolator.dart';
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
import 'package:rive/src/rive_core/enum_helper.dart';
|
||||
import 'package:rive/src/rive_core/text/text_modifier_group.dart';
|
||||
import 'package:rive/src/rive_core/text/text_value_run.dart';
|
||||
import 'package:rive_common/rive_text.dart';
|
||||
@ -236,7 +237,7 @@ class TextModifierRange extends TextModifierRangeBase {
|
||||
}
|
||||
}
|
||||
|
||||
TextRangeUnits get units => TextRangeUnits.values[unitsValue];
|
||||
TextRangeUnits get units => enumAt(TextRangeUnits.values, unitsValue);
|
||||
set units(TextRangeUnits units) => unitsValue = units.index;
|
||||
|
||||
@override
|
||||
@ -248,7 +249,7 @@ class TextModifierRange extends TextModifierRangeBase {
|
||||
@override
|
||||
void modeValueChanged(int from, int to) => modifierGroup?.rangeChanged();
|
||||
|
||||
TextRangeType get type => TextRangeType.values[typeValue];
|
||||
TextRangeType get type => enumAt(TextRangeType.values, typeValue);
|
||||
set type(TextRangeType value) => typeValue = value.index;
|
||||
|
||||
@override
|
||||
|
@ -166,7 +166,6 @@ class TextStyle extends TextStyleBase
|
||||
_variationHelper?.addDirt(ComponentDirt.textShape);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void onDirty(int mask) {
|
||||
super.onDirty(mask);
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: rive
|
||||
version: 0.12.0
|
||||
version: 0.12.1
|
||||
homepage: https://rive.app
|
||||
description: Rive 2 Flutter Runtime. This package provides runtime functionality for playing back and interacting with animations built with the Rive editor available at https://rive.app.
|
||||
repository: https://github.com/rive-app/rive-flutter
|
||||
@ -18,7 +18,7 @@ dependencies:
|
||||
sdk: flutter
|
||||
flutter_web_plugins:
|
||||
sdk: flutter
|
||||
http: ">=0.13.3 <2.0.0"
|
||||
http: '>=0.13.3 <2.0.0'
|
||||
meta: ^1.3.0
|
||||
plugin_platform_interface: ^2.0.2
|
||||
rive_common: 0.2.7
|
||||
|
Reference in New Issue
Block a user