Fixing merge conflict

This commit is contained in:
Matt Sullivan
2020-08-02 18:37:46 -07:00
49 changed files with 297 additions and 383 deletions

View File

@ -1,3 +1,15 @@
## [0.0.4] - 2020-07-28 18:35:44
- Fundamental changes to runtime format enabling smaller file sizes. Format bumps to version 3.0 as it breaks backwards compatibility.
## [0.0.3] - 2020-07-19 18:18:50
- Support shorter string encoding. Format bumps to version 2.0 as it breaks backwards compatibility.
## [0.0.1+3] - 2020-07-09 11:13:22
- Fixing up ```flutter analyze``` issues thanks to @creativecreatorormaybenot.
## [0.0.1+2] - 2020-07-08 16:47:10 ## [0.0.1+2] - 2020-07-08 16:47:10
- Updating meta dependency to one that is compatible with Flutter 😶 - Updating meta dependency to one that is compatible with Flutter 😶

View File

@ -1,4 +1,4 @@
# Rive # Rive [![Pub Version](https://img.shields.io/pub/v/rive)](https://pub.dev/packages/rive)
[Flutter package](https://pub.dev/packages/rive) for Rive 2. [Flutter package](https://pub.dev/packages/rive) for Rive 2.
## Bring Your Apps and Games to Life with Real-Time Animation ## Bring Your Apps and Games to Life with Real-Time Animation
@ -7,8 +7,8 @@
## Add to pubspec.yaml ## Add to pubspec.yaml
```yaml ```yaml
dependencies: dependencies:
rive: ^0.0.1+2 rive: ^0.0.1+3
``` ```
## Example ## Example
See how to use it in [example](example/). See how to use it in [example](example).

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -44,7 +44,7 @@ class _MyHomePageState extends State<MyHomePage> {
// Load the animation file from the bundle, note that you could also // Load the animation file from the bundle, note that you could also
// download this. The RiveFile just expects a list of bytes. // download this. The RiveFile just expects a list of bytes.
rootBundle.load('assets/colors_juice.riv').then( rootBundle.load('assets/teeny_tiny.riv').then(
(data) async { (data) async {
var file = RiveFile(); var file = RiveFile();
// Load the RiveFile from the binary data. // Load the RiveFile from the binary data.
@ -56,7 +56,7 @@ class _MyHomePageState extends State<MyHomePage> {
// Add a controller to play back a known animation on the main/default // Add a controller to play back a known animation on the main/default
// artboard.We store a reference to it so we can toggle playback. // artboard.We store a reference to it so we can toggle playback.
artboard.addController( artboard.addController(
_controller = SimpleAnimation('walk'), _controller = SimpleAnimation('idle'),
); );
setState(() => _riveArtboard = artboard); setState(() => _riveArtboard = artboard);
} }

View File

@ -21,7 +21,7 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.1.0-nullsafety"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -42,7 +42,7 @@ packages:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.13" version: "1.15.0-nullsafety"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -80,7 +80,7 @@ packages:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.8" version: "1.3.0-nullsafety"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -94,7 +94,7 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.0.1+2" version: "0.0.4"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -148,13 +148,13 @@ packages:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0-nullsafety"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.8" version: "2.1.0-nullsafety"
sdks: sdks:
dart: ">=2.9.0-14.0.dev <3.0.0" dart: ">=2.9.0-18.0 <2.9.0"

View File

@ -1,6 +1,16 @@
library rive;
export 'package:rive/src/rive_file.dart'; export 'package:rive/src/rive_file.dart';
export 'package:rive/src/rive.dart'; export 'package:rive/src/rive.dart';
export 'package:rive/src/runtime_artboard.dart';
export 'package:rive/src/controllers/simple_controller.dart';
export 'package:rive/src/rive_core/rive_animation_controller.dart'; export 'package:rive/src/rive_core/rive_animation_controller.dart';
export 'package:rive/src/controllers/simple_controller.dart'; export 'package:rive/src/rive_core/animation/linear_animation.dart';
export 'package:rive/src/controllers/simple_controller.dart'; export 'package:rive/src/rive_core/animation/linear_animation_instance.dart';
export 'package:rive/src/rive_core/artboard.dart'; export 'package:rive/src/rive_core/artboard.dart';
export 'package:rive/src/rive_core/shapes/shape.dart';
export 'package:rive/src/rive_core/shapes/paint/fill.dart';
export 'package:rive/src/rive_core/shapes/paint/stroke.dart';
export 'package:rive/src/rive_core/shapes/paint/solid_color.dart';
export 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart';
export 'package:rive/src/rive_core/shapes/paint/radial_gradient.dart';

View File

@ -1,5 +1,5 @@
import 'package:rive/src/rive_core/animation/linear_animation.dart'; import 'package:rive/src/rive_core/animation/linear_animation.dart';
import 'package:rive/src/rive_core/animation/loop.dart'; import 'package:rive/src/rive_core/animation/linear_animation_instance.dart';
import 'package:rive/src/rive_core/rive_animation_controller.dart'; import 'package:rive/src/rive_core/rive_animation_controller.dart';
import 'package:rive/src/runtime_artboard.dart'; import 'package:rive/src/runtime_artboard.dart';
@ -7,70 +7,29 @@ import 'package:rive/src/runtime_artboard.dart';
/// by an artist. All playback parameters (looping, speed, keyframes) are artist /// by an artist. All playback parameters (looping, speed, keyframes) are artist
/// defined in the Rive editor. /// defined in the Rive editor.
class SimpleAnimation extends RiveAnimationController<RuntimeArtboard> { class SimpleAnimation extends RiveAnimationController<RuntimeArtboard> {
LinearAnimation _animation; LinearAnimationInstance _instance;
double _time = 0;
int _direction = 1;
final String animationName; final String animationName;
SimpleAnimation(this.animationName); SimpleAnimation(this.animationName);
@override @override
bool init(RuntimeArtboard artboard) { bool init(RuntimeArtboard artboard) {
_animation = artboard.animations.firstWhere( var animation = artboard.animations.firstWhere(
(animation) => animation.name == animationName, (animation) =>
animation is LinearAnimation && animation.name == animationName,
orElse: () => null, orElse: () => null,
) as LinearAnimation; );
if (animation != null) {
_instance = LinearAnimationInstance(animation as LinearAnimation);
}
isActive = true; isActive = true;
return _animation != null; return _instance != null;
} }
@override @override
void apply(RuntimeArtboard artboard, double elapsedSeconds) { void apply(RuntimeArtboard artboard, double elapsedSeconds) {
_animation.apply(_time, coreContext: artboard); _instance.animation.apply(_instance.time, coreContext: artboard);
_time += elapsedSeconds * _animation.speed * _direction; if (!_instance.advance(elapsedSeconds)) {
isActive = false;
double frames = _time * _animation.fps;
var start = _animation.enableWorkArea ? _animation.workStart : 0;
var end =
_animation.enableWorkArea ? _animation.workEnd : _animation.duration;
var range = end - start;
switch (_animation.loop) {
case Loop.oneShot:
if (frames > end) {
isActive = false;
frames = end.toDouble();
_time = frames / _animation.fps;
}
break;
case Loop.loop:
if (frames >= end) {
frames = _time * _animation.fps;
frames = start + (frames - start) % range;
_time = frames / _animation.fps;
}
break;
case Loop.pingPong:
// ignore: literal_only_boolean_expressions
while (true) {
if (_direction == 1 && frames >= end) {
_direction = -1;
frames = end + (end - frames);
_time = frames / _animation.fps;
} else if (_direction == -1 && frames < start) {
_direction = 1;
frames = start + (start - frames);
_time = frames / _animation.fps;
} else {
// we're within the range, we can stop fixing. We do this in a
// loop to fix conditions when time has advanced so far that we've
// ping-ponged back and forth a few times in a single frame. We
// want to accomodate for this in cases where animations are not
// advanced on regular intervals.
break;
}
}
break;
} }
} }

View File

@ -1,11 +1,7 @@
import 'package:rive/src/core/field_types/core_field_type.dart'; import 'package:rive/src/core/field_types/core_field_type.dart';
import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
class CoreBoolType extends CoreFieldType<bool> { class CoreBoolType extends CoreFieldType<bool> {
@override @override
bool deserialize(BinaryReader reader) => reader.readInt8() == 1; bool deserialize(BinaryReader reader) => reader.readInt8() == 1;
@override
bool lerp(bool from, bool to, double f) => from;
} }

View File

@ -0,0 +1,7 @@
import 'package:rive/src/core/field_types/core_field_type.dart';
import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
class CoreColorType extends CoreFieldType<int> {
@override
int deserialize(BinaryReader reader) => reader.readUint32();
}

View File

@ -3,10 +3,5 @@ import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
class CoreDoubleType extends CoreFieldType<double> { class CoreDoubleType extends CoreFieldType<double> {
@override @override
double deserialize(BinaryReader reader) => reader.buffer.lengthInBytes == 4 double deserialize(BinaryReader reader) => reader.readFloat32();
? reader.readFloat32()
: reader.readFloat64();
@override
double lerp(double from, double to, double f) => from + (to - from) * f;
} }

View File

@ -1,6 +1,6 @@
import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
// ignore: one_member_abstracts
abstract class CoreFieldType<T> { abstract class CoreFieldType<T> {
T deserialize(BinaryReader reader); T deserialize(BinaryReader reader);
T lerp(T from, T to, double f);
} }

View File

@ -1,18 +0,0 @@
import 'package:rive/src/core/core.dart';
import 'package:rive/src/core/field_types/core_field_type.dart';
import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
class CoreFractionalIndexType extends CoreFieldType<FractionalIndex> {
@override
FractionalIndex deserialize(BinaryReader reader) {
var numerator = reader.readVarInt();
var denominator = reader.readVarInt();
return FractionalIndex(numerator, denominator);
}
@override
FractionalIndex lerp(FractionalIndex from, FractionalIndex to, double f) =>
from;
}

View File

@ -1,11 +1,7 @@
import 'package:rive/src/core/field_types/core_field_type.dart'; import 'package:rive/src/core/field_types/core_field_type.dart';
import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
class CoreIntType extends CoreFieldType<int> { class CoreIntType extends CoreFieldType<int> {
@override @override
int deserialize(BinaryReader reader) => reader.readVarInt(); int deserialize(BinaryReader reader) => reader.readVarInt();
@override
int lerp(int from, int to, double f) => (from + (to - from) * f).round();
} }

View File

@ -3,8 +3,6 @@ import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
class CoreStringType extends CoreFieldType<String> { class CoreStringType extends CoreFieldType<String> {
@override @override
String deserialize(BinaryReader reader) => reader.readString(); String deserialize(BinaryReader reader) =>
reader.readString(explicitLength: true);
@override
String lerp(String from, String to, double f) => from;
} }

View File

@ -0,0 +1,7 @@
import 'package:rive/src/core/field_types/core_field_type.dart';
import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
class CoreUintType extends CoreFieldType<int> {
@override
int deserialize(BinaryReader reader) => reader.readVarUint();
}

View File

@ -1,9 +1,11 @@
import 'package:rive/src/core/core.dart'; import 'package:rive/src/core/core.dart';
import 'package:rive/src/core/field_types/core_bool_type.dart'; import 'package:rive/src/core/field_types/core_bool_type.dart';
import 'package:rive/src/core/field_types/core_color_type.dart';
import 'package:rive/src/core/field_types/core_double_type.dart'; import 'package:rive/src/core/field_types/core_double_type.dart';
import 'package:rive/src/core/field_types/core_field_type.dart'; import 'package:rive/src/core/field_types/core_field_type.dart';
import 'package:rive/src/core/field_types/core_int_type.dart'; import 'package:rive/src/core/field_types/core_int_type.dart';
import 'package:rive/src/core/field_types/core_string_type.dart'; import 'package:rive/src/core/field_types/core_string_type.dart';
import 'package:rive/src/core/field_types/core_uint_type.dart';
import 'package:rive/src/generated/animation/animation_base.dart'; import 'package:rive/src/generated/animation/animation_base.dart';
import 'package:rive/src/generated/animation/cubic_interpolator_base.dart'; import 'package:rive/src/generated/animation/cubic_interpolator_base.dart';
import 'package:rive/src/generated/animation/keyed_object_base.dart'; import 'package:rive/src/generated/animation/keyed_object_base.dart';
@ -67,6 +69,7 @@ import 'package:rive/src/rive_core/shapes/shape.dart';
import 'package:rive/src/rive_core/shapes/straight_vertex.dart'; import 'package:rive/src/rive_core/shapes/straight_vertex.dart';
import 'package:rive/src/rive_core/shapes/triangle.dart'; import 'package:rive/src/rive_core/shapes/triangle.dart';
// ignore: avoid_classes_with_only_static_members
class RiveCoreContext { class RiveCoreContext {
static Core makeCoreInstance(int typeKey) { static Core makeCoreInstance(int typeKey) {
switch (typeKey) { switch (typeKey) {
@ -475,30 +478,32 @@ class RiveCoreContext {
} }
} }
static CoreFieldType uintType = CoreUintType();
static CoreFieldType intType = CoreIntType(); static CoreFieldType intType = CoreIntType();
static CoreFieldType stringType = CoreStringType(); static CoreFieldType stringType = CoreStringType();
static CoreFieldType doubleType = CoreDoubleType(); static CoreFieldType doubleType = CoreDoubleType();
static CoreFieldType colorType = CoreIntType(); static CoreFieldType colorType = CoreColorType();
static CoreFieldType boolType = CoreBoolType(); static CoreFieldType boolType = CoreBoolType();
static CoreFieldType coreType(int propertyKey) { static CoreFieldType coreType(int propertyKey) {
switch (propertyKey) { switch (propertyKey) {
case KeyedObjectBase.objectIdPropertyKey: case KeyedObjectBase.objectIdPropertyKey:
case KeyFrameBase.interpolatorIdPropertyKey:
case KeyFrameDrawOrderValueBase.drawableIdPropertyKey:
case KeyFrameDrawOrderValueBase.valuePropertyKey:
case ComponentBase.parentIdPropertyKey:
case DrawableBase.drawOrderPropertyKey:
return uintType;
case KeyedPropertyBase.propertyKeyPropertyKey: case KeyedPropertyBase.propertyKeyPropertyKey:
case KeyFrameBase.framePropertyKey: case KeyFrameBase.framePropertyKey:
case KeyFrameBase.interpolationTypePropertyKey: case KeyFrameBase.interpolationTypePropertyKey:
case KeyFrameBase.interpolatorIdPropertyKey:
case LinearAnimationBase.fpsPropertyKey: case LinearAnimationBase.fpsPropertyKey:
case LinearAnimationBase.durationPropertyKey: case LinearAnimationBase.durationPropertyKey:
case LinearAnimationBase.loopValuePropertyKey: case LinearAnimationBase.loopValuePropertyKey:
case LinearAnimationBase.workStartPropertyKey: case LinearAnimationBase.workStartPropertyKey:
case LinearAnimationBase.workEndPropertyKey: case LinearAnimationBase.workEndPropertyKey:
case KeyFrameDrawOrderValueBase.drawableIdPropertyKey:
case KeyFrameDrawOrderValueBase.valuePropertyKey:
case ComponentBase.parentIdPropertyKey:
case StrokeBase.capPropertyKey: case StrokeBase.capPropertyKey:
case StrokeBase.joinPropertyKey: case StrokeBase.joinPropertyKey:
case FillBase.fillRulePropertyKey: case FillBase.fillRulePropertyKey:
case DrawableBase.drawOrderPropertyKey:
case DrawableBase.blendModeValuePropertyKey: case DrawableBase.blendModeValuePropertyKey:
return intType; return intType;
case AnimationBase.namePropertyKey: case AnimationBase.namePropertyKey:
@ -559,18 +564,32 @@ class RiveCoreContext {
} }
} }
static int getInt(Core object, int propertyKey) { static int getUint(Core object, int propertyKey) {
switch (propertyKey) { switch (propertyKey) {
case KeyedObjectBase.objectIdPropertyKey: case KeyedObjectBase.objectIdPropertyKey:
return (object as KeyedObjectBase).objectId; return (object as KeyedObjectBase).objectId;
case KeyFrameBase.interpolatorIdPropertyKey:
return (object as KeyFrameBase).interpolatorId;
case KeyFrameDrawOrderValueBase.drawableIdPropertyKey:
return (object as KeyFrameDrawOrderValueBase).drawableId;
case KeyFrameDrawOrderValueBase.valuePropertyKey:
return (object as KeyFrameDrawOrderValueBase).value;
case ComponentBase.parentIdPropertyKey:
return (object as ComponentBase).parentId;
case DrawableBase.drawOrderPropertyKey:
return (object as DrawableBase).drawOrder;
}
return 0;
}
static int getInt(Core object, int propertyKey) {
switch (propertyKey) {
case KeyedPropertyBase.propertyKeyPropertyKey: case KeyedPropertyBase.propertyKeyPropertyKey:
return (object as KeyedPropertyBase).propertyKey; return (object as KeyedPropertyBase).propertyKey;
case KeyFrameBase.framePropertyKey: case KeyFrameBase.framePropertyKey:
return (object as KeyFrameBase).frame; return (object as KeyFrameBase).frame;
case KeyFrameBase.interpolationTypePropertyKey: case KeyFrameBase.interpolationTypePropertyKey:
return (object as KeyFrameBase).interpolationType; return (object as KeyFrameBase).interpolationType;
case KeyFrameBase.interpolatorIdPropertyKey:
return (object as KeyFrameBase).interpolatorId;
case LinearAnimationBase.fpsPropertyKey: case LinearAnimationBase.fpsPropertyKey:
return (object as LinearAnimationBase).fps; return (object as LinearAnimationBase).fps;
case LinearAnimationBase.durationPropertyKey: case LinearAnimationBase.durationPropertyKey:
@ -581,20 +600,12 @@ class RiveCoreContext {
return (object as LinearAnimationBase).workStart; return (object as LinearAnimationBase).workStart;
case LinearAnimationBase.workEndPropertyKey: case LinearAnimationBase.workEndPropertyKey:
return (object as LinearAnimationBase).workEnd; return (object as LinearAnimationBase).workEnd;
case KeyFrameDrawOrderValueBase.drawableIdPropertyKey:
return (object as KeyFrameDrawOrderValueBase).drawableId;
case KeyFrameDrawOrderValueBase.valuePropertyKey:
return (object as KeyFrameDrawOrderValueBase).value;
case ComponentBase.parentIdPropertyKey:
return (object as ComponentBase).parentId;
case StrokeBase.capPropertyKey: case StrokeBase.capPropertyKey:
return (object as StrokeBase).cap; return (object as StrokeBase).cap;
case StrokeBase.joinPropertyKey: case StrokeBase.joinPropertyKey:
return (object as StrokeBase).join; return (object as StrokeBase).join;
case FillBase.fillRulePropertyKey: case FillBase.fillRulePropertyKey:
return (object as FillBase).fillRule; return (object as FillBase).fillRule;
case DrawableBase.drawOrderPropertyKey:
return (object as DrawableBase).drawOrder;
case DrawableBase.blendModeValuePropertyKey: case DrawableBase.blendModeValuePropertyKey:
return (object as DrawableBase).blendModeValue; return (object as DrawableBase).blendModeValue;
} }
@ -723,11 +734,31 @@ class RiveCoreContext {
return false; return false;
} }
static void setInt(Core object, int propertyKey, int value) { static void setUint(Core object, int propertyKey, int value) {
switch (propertyKey) { switch (propertyKey) {
case KeyedObjectBase.objectIdPropertyKey: case KeyedObjectBase.objectIdPropertyKey:
(object as KeyedObjectBase).objectId = value; (object as KeyedObjectBase).objectId = value;
break; break;
case KeyFrameBase.interpolatorIdPropertyKey:
(object as KeyFrameBase).interpolatorId = value;
break;
case KeyFrameDrawOrderValueBase.drawableIdPropertyKey:
(object as KeyFrameDrawOrderValueBase).drawableId = value;
break;
case KeyFrameDrawOrderValueBase.valuePropertyKey:
(object as KeyFrameDrawOrderValueBase).value = value;
break;
case ComponentBase.parentIdPropertyKey:
(object as ComponentBase).parentId = value;
break;
case DrawableBase.drawOrderPropertyKey:
(object as DrawableBase).drawOrder = value;
break;
}
}
static void setInt(Core object, int propertyKey, int value) {
switch (propertyKey) {
case KeyedPropertyBase.propertyKeyPropertyKey: case KeyedPropertyBase.propertyKeyPropertyKey:
(object as KeyedPropertyBase).propertyKey = value; (object as KeyedPropertyBase).propertyKey = value;
break; break;
@ -737,9 +768,6 @@ class RiveCoreContext {
case KeyFrameBase.interpolationTypePropertyKey: case KeyFrameBase.interpolationTypePropertyKey:
(object as KeyFrameBase).interpolationType = value; (object as KeyFrameBase).interpolationType = value;
break; break;
case KeyFrameBase.interpolatorIdPropertyKey:
(object as KeyFrameBase).interpolatorId = value;
break;
case LinearAnimationBase.fpsPropertyKey: case LinearAnimationBase.fpsPropertyKey:
(object as LinearAnimationBase).fps = value; (object as LinearAnimationBase).fps = value;
break; break;
@ -755,15 +783,6 @@ class RiveCoreContext {
case LinearAnimationBase.workEndPropertyKey: case LinearAnimationBase.workEndPropertyKey:
(object as LinearAnimationBase).workEnd = value; (object as LinearAnimationBase).workEnd = value;
break; break;
case KeyFrameDrawOrderValueBase.drawableIdPropertyKey:
(object as KeyFrameDrawOrderValueBase).drawableId = value;
break;
case KeyFrameDrawOrderValueBase.valuePropertyKey:
(object as KeyFrameDrawOrderValueBase).value = value;
break;
case ComponentBase.parentIdPropertyKey:
(object as ComponentBase).parentId = value;
break;
case StrokeBase.capPropertyKey: case StrokeBase.capPropertyKey:
(object as StrokeBase).cap = value; (object as StrokeBase).cap = value;
break; break;
@ -773,9 +792,6 @@ class RiveCoreContext {
case FillBase.fillRulePropertyKey: case FillBase.fillRulePropertyKey:
(object as FillBase).fillRule = value; (object as FillBase).fillRule = value;
break; break;
case DrawableBase.drawOrderPropertyKey:
(object as DrawableBase).drawOrder = value;
break;
case DrawableBase.blendModeValuePropertyKey: case DrawableBase.blendModeValuePropertyKey:
(object as DrawableBase).blendModeValue = value; (object as DrawableBase).blendModeValue = value;
break; break;

View File

@ -24,7 +24,7 @@ abstract class RectangleBase extends ParametricPath {
/// -------------------------------------------------------------------------- /// --------------------------------------------------------------------------
/// CornerRadius field with key 31. /// CornerRadius field with key 31.
double _cornerRadius; double _cornerRadius = 0;
static const int cornerRadiusPropertyKey = 31; static const int cornerRadiusPropertyKey = 31;
/// Radius of the corners of this rectangle /// Radius of the corners of this rectangle

View File

@ -19,10 +19,4 @@ class KeyFrameDrawOrderValue extends KeyFrameDrawOrderValueBase {
drawable.drawOrder = value; drawable.drawOrder = value;
} }
} }
@override
int runtimeValueValue(int editorValue) {
assert(false, 'this should never get called');
return 0;
}
} }

View File

@ -0,0 +1,58 @@
import 'package:rive/src/rive_core/animation/linear_animation.dart';
import 'package:rive/src/rive_core/animation/loop.dart';
class LinearAnimationInstance {
final LinearAnimation animation;
double _time = 0;
int direction = 1;
LinearAnimationInstance(this.animation);
double get time => _time;
set time(double value) {
if (_time == value) {
return;
}
_time = value;
direction = 1;
}
bool advance(double elapsedSeconds) {
_time += elapsedSeconds * animation.speed * direction;
double frames = _time * animation.fps;
var start = animation.enableWorkArea ? animation.workStart : 0;
var end = animation.enableWorkArea ? animation.workEnd : animation.duration;
var range = end - start;
bool keepGoing = true;
switch (animation.loop) {
case Loop.oneShot:
if (frames > end) {
keepGoing = false;
frames = end.toDouble();
_time = frames / animation.fps;
}
break;
case Loop.loop:
if (frames >= end) {
frames = _time * animation.fps;
frames = start + (frames - start) % range;
_time = frames / animation.fps;
}
break;
case Loop.pingPong:
while (true) {
if (direction == 1 && frames >= end) {
direction = -1;
frames = end + (end - frames);
_time = frames / animation.fps;
} else if (direction == -1 && frames < start) {
direction = 1;
frames = start + (start - frames);
_time = frames / animation.fps;
} else {
break;
}
}
break;
}
return keepGoing;
}
}

View File

@ -189,6 +189,7 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
} }
canvas.save(); canvas.save();
canvas.clipRect(Rect.fromLTWH(0, 0, width, height)); canvas.clipRect(Rect.fromLTWH(0, 0, width, height));
canvas.translate(width * (originX ?? 0), height * (originY ?? 0));
for (final drawable in _drawables) { for (final drawable in _drawables) {
drawable.draw(canvas); drawable.draw(canvas);
} }
@ -202,9 +203,15 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
@override @override
Mat2D get worldTransform => Mat2D(); Mat2D get worldTransform => Mat2D();
@override @override
void originXChanged(double from, double to) {} void originXChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform);
}
@override @override
void originYChanged(double from, double to) {} void originYChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform);
}
bool internalAddAnimation(Animation animation) { bool internalAddAnimation(Animation animation) {
if (_animations.contains(animation)) { if (_animations.contains(animation)) {
return false; return false;

View File

@ -1,3 +0,0 @@
abstract class BoundsDelegate {
void boundsChanged();
}

View File

@ -48,6 +48,10 @@ class Mat2D {
Mat2D.fromScaling(Vec2D scaling) { Mat2D.fromScaling(Vec2D scaling) {
_buffer = Float32List.fromList([scaling[0], 0, 0, scaling[1], 0, 0]); _buffer = Float32List.fromList([scaling[0], 0, 0, scaling[1], 0, 0]);
} }
Mat2D.fromMat4(Float64List mat4) {
_buffer = Float32List.fromList(
[mat4[0], mat4[1], mat4[4], mat4[5], mat4[12], mat4[13]]);
}
Mat2D.clone(Mat2D copy) { Mat2D.clone(Mat2D copy) {
_buffer = Float32List.fromList(copy.values); _buffer = Float32List.fromList(copy.values);
} }

View File

@ -12,7 +12,7 @@ class Segment2D {
Vec2D diff; Vec2D diff;
double lengthSquared; double lengthSquared;
Segment2D(this.start, this.end); Segment2D(this.start, this.end);
ProjectionResult projectPoint(Vec2D point) { ProjectionResult projectPoint(Vec2D point, {bool clamp = true}) {
if (diff == null) { if (diff == null) {
diff = Vec2D.subtract(Vec2D(), start, end); diff = Vec2D.subtract(Vec2D(), start, end);
lengthSquared = Vec2D.squaredLength(diff); lengthSquared = Vec2D.squaredLength(diff);
@ -23,11 +23,13 @@ class Segment2D {
double t = ((point[0] - start[0]) * (end[0] - start[0]) + double t = ((point[0] - start[0]) * (end[0] - start[0]) +
(point[1] - start[1]) * (end[1] - start[1])) / (point[1] - start[1]) * (end[1] - start[1])) /
lengthSquared; lengthSquared;
if (t < 0.0) { if (clamp) {
return ProjectionResult(0, start); if (t < 0.0) {
} return ProjectionResult(0, start);
if (t > 1.0) { }
return ProjectionResult(1, end); if (t > 1.0) {
return ProjectionResult(1, end);
}
} }
return ProjectionResult( return ProjectionResult(
t, t,

View File

@ -1,7 +1,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:rive/src/rive_core/bounds_delegate.dart';
import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/component_dirt.dart';
import 'package:rive/src/rive_core/container_component.dart'; import 'package:rive/src/rive_core/container_component.dart';
import 'package:rive/src/rive_core/math/aabb.dart';
import 'package:rive/src/rive_core/math/mat2d.dart'; import 'package:rive/src/rive_core/math/mat2d.dart';
import 'package:rive/src/rive_core/math/vec2d.dart'; import 'package:rive/src/rive_core/math/vec2d.dart';
import 'package:rive/src/generated/node_base.dart'; import 'package:rive/src/generated/node_base.dart';
@ -11,7 +11,6 @@ export 'package:rive/src/generated/node_base.dart';
class Node extends NodeBase { class Node extends NodeBase {
final Mat2D transform = Mat2D(); final Mat2D transform = Mat2D();
final Mat2D worldTransform = Mat2D(); final Mat2D worldTransform = Mat2D();
BoundsDelegate _delegate;
double _renderOpacity = 0; double _renderOpacity = 0;
double get renderOpacity => _renderOpacity; double get renderOpacity => _renderOpacity;
@override @override
@ -60,16 +59,6 @@ class Node extends NodeBase {
} else { } else {
Mat2D.copy(worldTransform, transform); Mat2D.copy(worldTransform, transform);
} }
_delegate?.boundsChanged();
}
@override
void userDataChanged(dynamic from, dynamic to) {
if (to is BoundsDelegate) {
_delegate = to;
} else {
_delegate = null;
}
} }
void calculateWorldTransform() { void calculateWorldTransform() {
@ -139,4 +128,6 @@ class Node extends NodeBase {
super.parentChanged(from, to); super.parentChanged(from, to);
markWorldTransformDirty(); markWorldTransformDirty();
} }
AABB get localBounds => AABB.fromValues(x, y, x, y);
} }

View File

@ -4,7 +4,7 @@ import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
import 'exceptions/rive_format_error_exception.dart'; import 'exceptions/rive_format_error_exception.dart';
class RuntimeHeader { class RuntimeHeader {
static const int majorVersion = 1; static const int majorVersion = 3;
static const int minorVersion = 0; static const int minorVersion = 0;
static const String fingerprint = 'RIVE'; static const String fingerprint = 'RIVE';
final int ownerId; final int ownerId;

View File

@ -16,6 +16,11 @@ class CubicAsymmetricVertex extends CubicAsymmetricVertexBase {
cos(rotation) * outDistance, sin(rotation) * outDistance)); cos(rotation) * outDistance, sin(rotation) * outDistance));
} }
@override
set outPoint(Vec2D value) {
_outPoint = Vec2D.clone(value);
}
@override @override
Vec2D get inPoint { Vec2D get inPoint {
return _inPoint ??= Vec2D.add( return _inPoint ??= Vec2D.add(
@ -25,6 +30,11 @@ class CubicAsymmetricVertex extends CubicAsymmetricVertexBase {
cos(rotation) * -inDistance, sin(rotation) * -inDistance)); cos(rotation) * -inDistance, sin(rotation) * -inDistance));
} }
@override
set inPoint(Vec2D value) {
_inPoint = Vec2D.clone(value);
}
@override @override
String toString() { String toString() {
return 'in ${inPoint[0]}, ${inPoint[1]} | ${translation.toString()} ' return 'in ${inPoint[0]}, ${inPoint[1]} | ${translation.toString()} '

View File

@ -13,12 +13,23 @@ class CubicMirroredVertex extends CubicMirroredVertexBase {
Vec2D.fromValues(cos(rotation) * distance, sin(rotation) * distance)); Vec2D.fromValues(cos(rotation) * distance, sin(rotation) * distance));
} }
@override
set outPoint(Vec2D value) {
_outPoint = Vec2D.clone(value);
}
@override @override
Vec2D get inPoint { Vec2D get inPoint {
return _inPoint ??= Vec2D.add(Vec2D(), translation, return _inPoint ??= Vec2D.add(Vec2D(), translation,
Vec2D.fromValues(cos(rotation) * -distance, sin(rotation) * -distance)); Vec2D.fromValues(cos(rotation) * -distance, sin(rotation) * -distance));
} }
@override
set inPoint(Vec2D value) {
var diffIn = Vec2D.fromValues(value[0] - x, value[1] - y);
outPoint = Vec2D.subtract(Vec2D(), translation, diffIn);
}
@override @override
String toString() { String toString() {
return 'in ${inPoint[0]}, ${inPoint[1]} | ${translation.toString()} ' return 'in ${inPoint[0]}, ${inPoint[1]} | ${translation.toString()} '

View File

@ -4,4 +4,6 @@ import 'package:rive/src/generated/shapes/cubic_vertex_base.dart';
abstract class CubicVertex extends CubicVertexBase { abstract class CubicVertex extends CubicVertexBase {
Vec2D get outPoint; Vec2D get outPoint;
Vec2D get inPoint; Vec2D get inPoint;
set outPoint(Vec2D value);
set inPoint(Vec2D value);
} }

View File

@ -1,17 +1,10 @@
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:rive/src/rive_core/component.dart';
import 'package:rive/src/rive_core/container_component.dart'; import 'package:rive/src/rive_core/container_component.dart';
import 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart'; import 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart';
import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart'; import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart';
export 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart'; export 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart';
class GradientStop extends GradientStopBase { class GradientStop extends GradientStopBase {
@override
Component get timelineParent =>
_gradient is LinearGradient ? _gradient.parent : null;
@override
String get timelineName =>
'Stop ${_gradient.gradientStops.indexOf(this) + 1}';
LinearGradient _gradient; LinearGradient _gradient;
LinearGradient get gradient => _gradient; LinearGradient get gradient => _gradient;
ui.Color get color => ui.Color(colorValue); ui.Color get color => ui.Color(colorValue);

View File

@ -10,8 +10,6 @@ export 'package:rive/src/generated/shapes/paint/linear_gradient_base.dart';
class LinearGradient extends LinearGradientBase with ShapePaintMutator { class LinearGradient extends LinearGradientBase with ShapePaintMutator {
final List<GradientStop> gradientStops = []; final List<GradientStop> gradientStops = [];
@override
Component get timelineProxy => parent;
bool _paintsInWorldSpace = true; bool _paintsInWorldSpace = true;
bool get paintsInWorldSpace => _paintsInWorldSpace; bool get paintsInWorldSpace => _paintsInWorldSpace;
set paintsInWorldSpace(bool value) { set paintsInWorldSpace(bool value) {

View File

@ -21,8 +21,6 @@ abstract class ShapePaint extends ShapePaintBase {
set blendMode(BlendMode value) => _paint.blendMode = value; set blendMode(BlendMode value) => _paint.blendMode = value;
double get renderOpacity => _paintMutator.renderOpacity; double get renderOpacity => _paintMutator.renderOpacity;
set renderOpacity(double value) => _paintMutator.renderOpacity = value; set renderOpacity(double value) => _paintMutator.renderOpacity = value;
@override
Component get timelineParent => _shapePaintContainer as Component;
ShapePaintMutator get paintMutator => _paintMutator; ShapePaintMutator get paintMutator => _paintMutator;
void _changeMutator(ShapePaintMutator mutator) { void _changeMutator(ShapePaintMutator mutator) {
_paint = makePaint(); _paint = makePaint();

View File

@ -1,5 +1,4 @@
import 'dart:ui'; import 'dart:ui';
import 'package:rive/src/rive_core/component.dart';
import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/component_dirt.dart';
import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart';
import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; import 'package:rive/src/rive_core/shapes/shape_paint_container.dart';
@ -7,8 +6,6 @@ import 'package:rive/src/generated/shapes/paint/solid_color_base.dart';
export 'package:rive/src/generated/shapes/paint/solid_color_base.dart'; export 'package:rive/src/generated/shapes/paint/solid_color_base.dart';
class SolidColor extends SolidColorBase with ShapePaintMutator { class SolidColor extends SolidColorBase with ShapePaintMutator {
@override
Component get timelineProxy => parent;
Color get color => Color(colorValue); Color get color => Color(colorValue);
set color(Color c) { set color(Color c) {
colorValue = c.value; colorValue = c.value;

View File

@ -11,8 +11,6 @@ class Stroke extends StrokeBase {
..strokeCap = strokeCap ..strokeCap = strokeCap
..strokeJoin = strokeJoin ..strokeJoin = strokeJoin
..strokeWidth = thickness; ..strokeWidth = thickness;
@override
String get timelineParentGroup => 'strokes';
StrokeCap get strokeCap => StrokeCap.values[cap]; StrokeCap get strokeCap => StrokeCap.values[cap];
set strokeCap(StrokeCap value) => cap = value.index; set strokeCap(StrokeCap value) => cap = value.index;
StrokeJoin get strokeJoin => StrokeJoin.values[join]; StrokeJoin get strokeJoin => StrokeJoin.values[join];

View File

@ -1,6 +1,5 @@
import 'dart:math'; import 'dart:math';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:rive/src/rive_core/bounds_delegate.dart';
import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component.dart';
import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/component_dirt.dart';
import 'package:rive/src/rive_core/math/aabb.dart'; import 'package:rive/src/rive_core/math/aabb.dart';
@ -33,27 +32,11 @@ abstract class Path extends PathBase {
Mat2D get inversePathTransform; Mat2D get inversePathTransform;
Mat2D get inverseWorldTransform => _inverseWorldTransform; Mat2D get inverseWorldTransform => _inverseWorldTransform;
@override @override
Component get timelineParent => _shape;
@override
bool resolveArtboard() { bool resolveArtboard() {
_changeShape(null); _changeShape(null);
return super.resolveArtboard(); return super.resolveArtboard();
} }
BoundsDelegate _delegate;
void markBoundsDirty() {
_delegate?.boundsChanged();
}
@override
void userDataChanged(dynamic from, dynamic to) {
if (to is BoundsDelegate) {
_delegate = to;
} else {
_delegate = null;
}
}
@override @override
void visitAncestor(Component ancestor) { void visitAncestor(Component ancestor) {
if (_shape == null && ancestor is Shape) { if (_shape == null && ancestor is Shape) {
@ -95,18 +78,9 @@ abstract class Path extends PathBase {
void markPathDirty() { void markPathDirty() {
addDirt(ComponentDirt.path); addDirt(ComponentDirt.path);
_shape?.pathChanged(this);
}
void _invalidatePath() {
_isValid = false; _isValid = false;
_cachedRenderVertices = null; _cachedRenderVertices = null;
} _shape?.pathChanged(this);
@override
bool addDirt(int value, {bool recurse = false}) {
_invalidatePath();
return super.addDirt(value, recurse: recurse);
} }
List<PathVertex> get vertices; List<PathVertex> get vertices;
@ -126,6 +100,7 @@ abstract class Path extends PathBase {
List<PathVertex> renderPoints = []; List<PathVertex> renderPoints = [];
int pl = pts.length; int pl = pts.length;
const double iarcConstant = 1.0 - circleConstant; const double iarcConstant = 1.0 - circleConstant;
PathVertex previous = isClosed ? pts[pl - 1] : null; PathVertex previous = isClosed ? pts[pl - 1] : null;
for (int i = 0; i < pl; i++) { for (int i = 0; i < pl; i++) {
PathVertex point = pts[i]; PathVertex point = pts[i];
@ -221,7 +196,10 @@ abstract class Path extends PathBase {
return true; return true;
} }
AABB preciseComputeBounds(List<PathVertex> renderPoints, Mat2D transform) { @override
AABB get localBounds => preciseComputeBounds(renderVertices, Mat2D());
AABB preciseComputeBounds(List<PathVertex> renderPoints, Mat2D transform,
{bool debug = false}) {
if (renderPoints.isEmpty) { if (renderPoints.isEmpty) {
return AABB(); return AABB();
} }
@ -247,7 +225,6 @@ abstract class Path extends PathBase {
cin = Vec2D.transformMat2D(Vec2D(), cin, transform); cin = Vec2D.transformMat2D(Vec2D(), cin, transform);
cout = Vec2D.transformMat2D(Vec2D(), cout, transform); cout = Vec2D.transformMat2D(Vec2D(), cout, transform);
} }
const double epsilon = 0.000000001;
final double startX = lastPoint[0]; final double startX = lastPoint[0];
final double startY = lastPoint[1]; final double startY = lastPoint[1];
final double cpX1 = cout[0]; final double cpX1 = cout[0];
@ -257,121 +234,55 @@ abstract class Path extends PathBase {
final double endX = next[0]; final double endX = next[0];
final double endY = next[1]; final double endY = next[1];
lastPoint = next; lastPoint = next;
double extremaX; _expandBoundsForAxis(bounds, 0, startX, cpX1, cpX2, endX);
double extremaY; _expandBoundsForAxis(bounds, 1, startY, cpY1, cpY2, endY);
double a, b, c;
if (!(((startX < cpX1) && (cpX1 < cpX2) && (cpX2 < endX)) ||
((startX > cpX1) && (cpX1 > cpX2) && (cpX2 > endX)))) {
a = -startX + (3 * (cpX1 - cpX2)) + endX;
b = 2 * (startX - (2 * cpX1) + cpX2);
c = -startX + cpX1;
double s = (b * b) - (4 * a * c);
if ((s >= 0.0) && (a.abs() > epsilon)) {
if (s == 0.0) {
final double t = -b / (2 * a);
final double tprime = 1.0 - t;
if ((t >= 0.0) && (t <= 1.0)) {
extremaX = ((tprime * tprime * tprime) * startX) +
((3 * tprime * tprime * t) * cpX1) +
((3 * tprime * t * t) * cpX2) +
(t * t * t * endX);
if (extremaX < bounds[0]) {
bounds[0] = extremaX;
}
if (extremaX > bounds[2]) {
bounds[2] = extremaX;
}
}
} else {
s = sqrt(s);
double t = (-b - s) / (2 * a);
double tprime = 1.0 - t;
if ((t >= 0.0) && (t <= 1.0)) {
extremaX = ((tprime * tprime * tprime) * startX) +
((3 * tprime * tprime * t) * cpX1) +
((3 * tprime * t * t) * cpX2) +
(t * t * t * endX);
if (extremaX < bounds[0]) {
bounds[0] = extremaX;
}
if (extremaX > bounds[2]) {
bounds[2] = extremaX;
}
}
t = (-b + s) / (2 * a);
tprime = 1.0 - t;
if ((t >= 0.0) && (t <= 1.0)) {
extremaX = ((tprime * tprime * tprime) * startX) +
((3 * tprime * tprime * t) * cpX1) +
((3 * tprime * t * t) * cpX2) +
(t * t * t * endX);
if (extremaX < bounds[0]) {
bounds[0] = extremaX;
}
if (extremaX > bounds[2]) {
bounds[2] = extremaX;
}
}
}
}
}
if (!(((startY < cpY1) && (cpY1 < cpY2) && (cpY2 < endY)) ||
((startY > cpY1) && (cpY1 > cpY2) && (cpY2 > endY)))) {
a = -startY + (3 * (cpY1 - cpY2)) + endY;
b = 2 * (startY - (2 * cpY1) + cpY2);
c = -startY + cpY1;
double s = (b * b) - (4 * a * c);
if ((s >= 0.0) && (a.abs() > epsilon)) {
if (s == 0.0) {
final double t = -b / (2 * a);
final double tprime = 1.0 - t;
if ((t >= 0.0) && (t <= 1.0)) {
extremaY = ((tprime * tprime * tprime) * startY) +
((3 * tprime * tprime * t) * cpY1) +
((3 * tprime * t * t) * cpY2) +
(t * t * t * endY);
if (extremaY < bounds[1]) {
bounds[1] = extremaY;
}
if (extremaY > bounds[3]) {
bounds[3] = extremaY;
}
}
} else {
s = sqrt(s);
final double t = (-b - s) / (2 * a);
final double tprime = 1.0 - t;
if ((t >= 0.0) && (t <= 1.0)) {
extremaY = ((tprime * tprime * tprime) * startY) +
((3 * tprime * tprime * t) * cpY1) +
((3 * tprime * t * t) * cpY2) +
(t * t * t * endY);
if (extremaY < bounds[1]) {
bounds[1] = extremaY;
}
if (extremaY > bounds[3]) {
bounds[3] = extremaY;
}
}
final double t2 = (-b + s) / (2 * a);
final double tprime2 = 1.0 - t2;
if ((t2 >= 0.0) && (t2 <= 1.0)) {
extremaY = ((tprime2 * tprime2 * tprime2) * startY) +
((3 * tprime2 * tprime2 * t2) * cpY1) +
((3 * tprime2 * t2 * t2) * cpY2) +
(t2 * t2 * t2 * endY);
if (extremaY < bounds[1]) {
bounds[1] = extremaY;
}
if (extremaY > bounds[3]) {
bounds[3] = extremaY;
}
}
}
}
}
} }
} }
return bounds; return bounds;
} }
} }
void _expandBoundsToCubicPoint(AABB bounds, int component, double t, double a,
double b, double c, double d) {
if (t >= 0 && t <= 1) {
var ti = 1 - t;
double extremaY = ((ti * ti * ti) * a) +
((3 * ti * ti * t) * b) +
((3 * ti * t * t) * c) +
(t * t * t * d);
if (extremaY < bounds[component]) {
bounds[component] = extremaY;
}
if (extremaY > bounds[component + 2]) {
bounds[component + 2] = extremaY;
}
}
}
void _expandBoundsForAxis(AABB bounds, int component, double start, double cp1,
double cp2, double end) {
if (!(((start < cp1) && (cp1 < cp2) && (cp2 < end)) ||
((start > cp1) && (cp1 > cp2) && (cp2 > end)))) {
var a = 3 * (cp1 - start);
var b = 3 * (cp2 - cp1);
var c = 3 * (end - cp2);
var d = a - 2 * b + c;
if (d != 0) {
var m1 = -sqrt(b * b - a * c);
var m2 = -a + b;
_expandBoundsToCubicPoint(
bounds, component, -(m1 + m2) / d, start, cp1, cp2, end);
_expandBoundsToCubicPoint(
bounds, component, -(-m1 + m2) / d, start, cp1, cp2, end);
} else if (b != c && d == 0) {
_expandBoundsToCubicPoint(
bounds, component, (2 * b - c) / (2 * (b - c)), start, cp1, cp2, end);
}
var d2a = 2 * (b - a);
var d2b = 2 * (c - b);
if (d2a != b) {
_expandBoundsToCubicPoint(
bounds, component, d2a / (d2a - d2b), start, cp1, cp2, end);
}
}
}

View File

@ -1,18 +1,11 @@
import 'dart:collection';
import 'package:rive/src/rive_core/math/vec2d.dart'; import 'package:rive/src/rive_core/math/vec2d.dart';
import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; import 'package:rive/src/rive_core/shapes/cubic_vertex.dart';
import 'package:rive/src/utilities/binary_buffer/binary_writer.dart';
class RenderCubicVertex extends CubicVertex { class RenderCubicVertex extends CubicVertex {
@override
void changeNonNull() {}
@override @override
Vec2D inPoint; Vec2D inPoint;
@override @override
Vec2D outPoint; Vec2D outPoint;
@override @override
void onAddedDirty() {} void onAddedDirty() {}
@override
void writeRuntimeProperties(
BinaryWriter writer, HashMap<int, int> idLookup) {}
} }

View File

@ -1,5 +1,4 @@
import 'dart:ui'; import 'dart:ui';
import 'package:rive/src/rive_core/bounds_delegate.dart';
import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component.dart';
import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/component_dirt.dart';
import 'package:rive/src/rive_core/math/aabb.dart'; import 'package:rive/src/rive_core/math/aabb.dart';
@ -34,17 +33,12 @@ class Shape extends ShapeBase with ShapePaintContainer {
AABB _worldBounds; AABB _worldBounds;
AABB _localBounds; AABB _localBounds;
BoundsDelegate _delegate;
@override @override
AABB get worldBounds => _worldBounds ??= computeWorldBounds(); AABB get worldBounds => _worldBounds ??= computeWorldBounds();
@override @override
AABB get localBounds => _localBounds ??= computeLocalBounds(); AABB get localBounds => _localBounds ??= computeLocalBounds();
void markBoundsDirty() { void markBoundsDirty() {
_worldBounds = _localBounds = null; _worldBounds = _localBounds = null;
_delegate?.boundsChanged();
for (final path in paths) {
path.markBoundsDirty();
}
} }
@override @override
@ -202,15 +196,6 @@ class Shape extends ShapeBase with ShapePaintContainer {
return localBounds; return localBounds;
} }
@override
void userDataChanged(dynamic from, dynamic to) {
if (to is BoundsDelegate) {
_delegate = to;
} else {
_delegate = null;
}
}
@override @override
void blendModeValueChanged(int from, int to) => _markBlendModeDirty(); void blendModeValueChanged(int from, int to) => _markBlendModeDirty();
@override @override

View File

@ -97,10 +97,10 @@ class RiveFile {
continue; continue;
} else if (keyframe is KeyFrameDrawOrder) { } else if (keyframe is KeyFrameDrawOrder) {
int numValues = reader.readVarUint(); int numValues = reader.readVarUint();
for (int i = 0; i < numValues; i++) { for (int m = 0; m < numValues; m++) {
var valueObject = KeyFrameDrawOrderValue(); var valueObject = KeyFrameDrawOrderValue();
valueObject.drawableId = reader.readVarInt(); valueObject.drawableId = reader.readVarUint();
valueObject.value = i; valueObject.value = m;
keyframe.internalAddValue(valueObject); keyframe.internalAddValue(valueObject);
} }
} }
@ -153,30 +153,15 @@ T readRuntimeObject<T extends Core<CoreContext>>(BinaryReader reader,
// Terminator. https://media.giphy.com/media/7TtvTUMm9mp20/giphy.gif // Terminator. https://media.giphy.com/media/7TtvTUMm9mp20/giphy.gif
break; break;
} }
int propertyLength = reader.readVarUint();
Uint8List valueBytes = reader.read(propertyLength);
var fieldType = RiveCoreContext.coreType(propertyKey); var fieldType = RiveCoreContext.coreType(propertyKey);
if (fieldType == null) { if (fieldType == null) {
// This is considered an acceptable failure. A runtime may not support throw UnsupportedError('Unsupported property key $propertyKey. '
// the same properties that were exported. The older object could still 'A new runtime is likely necessary to play this file.');
// function without them, however, so it's up to the implementation to
// make sure that major versions are revved when breaking properties are
// added. Note that we intentionally first read the entire value bytes
// for the property so we can advance as expected even if we are
// skipping this value.
continue;
} }
// We know what to expect, let's try to read the value. We instance a new
// reader here so that we don't overflow the exact length we're allowed to
// read.
var valueReader = BinaryReader.fromList(valueBytes);
// This will attempt to set the object property, but failure here is
// acceptable.
RiveCoreContext.setObjectProperty( RiveCoreContext.setObjectProperty(
object, propertyKey, fieldType.deserialize(valueReader)); object, propertyKey, fieldType.deserialize(reader));
} }
return object as T; return object as T;
} }

View File

@ -7,6 +7,7 @@ class BinaryReader {
final ByteData buffer; final ByteData buffer;
final Endian endian; final Endian endian;
int _readIndex = 0; int _readIndex = 0;
int get position => _readIndex;
BinaryReader(this.buffer, {this.endian = Endian.little}); BinaryReader(this.buffer, {this.endian = Endian.little});
@ -115,8 +116,8 @@ class BinaryReader {
/// Read a string encoded into the stream. Strings are encoded with a varuint /// Read a string encoded into the stream. Strings are encoded with a varuint
/// integer length written first followed by length number of utf8 encoded /// integer length written first followed by length number of utf8 encoded
/// bytes. /// bytes.
String readString() { String readString({bool explicitLength = true}) {
int length = readVarUint(); int length = explicitLength ? readVarUint() : buffer.lengthInBytes;
String value = _utf8Decoder.convert(Uint8List.view( String value = _utf8Decoder.convert(Uint8List.view(
buffer.buffer, buffer.offsetInBytes + _readIndex, length)); buffer.buffer, buffer.offsetInBytes + _readIndex, length));
_readIndex += length; _readIndex += length;

View File

@ -151,9 +151,11 @@ class BinaryWriter {
/// Encode a string into the buffer. Strings are encoded with a varuint /// Encode a string into the buffer. Strings are encoded with a varuint
/// integer length written first followed by length number of utf8 encoded /// integer length written first followed by length number of utf8 encoded
/// bytes. /// bytes.
void writeString(String value) { void writeString(String value, {bool explicitLength = true}) {
var list = _utf8Encoder.convert(value); var list = _utf8Encoder.convert(value);
writeVarUint(list.length); if (explicitLength) {
writeVarUint(list.length);
}
write(list); write(list);
} }

View File

@ -21,7 +21,7 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.1.0-nullsafety"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -42,7 +42,7 @@ packages:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.13" version: "1.15.0-nullsafety"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -80,7 +80,7 @@ packages:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.8" version: "1.3.0-nullsafety"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -141,13 +141,13 @@ packages:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0-nullsafety"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.8" version: "2.1.0-nullsafety"
sdks: sdks:
dart: ">=2.9.0-14.0.dev <3.0.0" dart: ">=2.9.0-18.0 <2.9.0"

View File

@ -1,7 +1,8 @@
name: rive name: rive
description: Rive 2 Flutter Runtime description: Rive 2 Flutter Runtime
version: 0.0.1+2 version: 0.0.4
repository: https://github.com/rive-app/rive-flutter repository: https://github.com/rive-app/rive-flutter
homepage: https://rive.app
environment: environment:
sdk: ">=2.2.2 <3.0.0" sdk: ">=2.2.2 <3.0.0"
@ -15,5 +16,3 @@ dependencies:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter: