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
- 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.
## Bring Your Apps and Games to Life with Real-Time Animation
@ -7,8 +7,8 @@
## Add to pubspec.yaml
```yaml
dependencies:
rive: ^0.0.1+2
rive: ^0.0.1+3
```
## 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
// 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 {
var file = RiveFile();
// 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
// artboard.We store a reference to it so we can toggle playback.
artboard.addController(
_controller = SimpleAnimation('walk'),
_controller = SimpleAnimation('idle'),
);
setState(() => _riveArtboard = artboard);
}

View File

@ -21,7 +21,7 @@ packages:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
version: "1.1.0-nullsafety"
charcode:
dependency: transitive
description:
@ -42,7 +42,7 @@ packages:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.13"
version: "1.15.0-nullsafety"
fake_async:
dependency: transitive
description:
@ -80,7 +80,7 @@ packages:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.8"
version: "1.3.0-nullsafety"
path:
dependency: transitive
description:
@ -94,7 +94,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.0.1+2"
version: "0.0.4"
sky_engine:
dependency: transitive
description: flutter
@ -148,13 +148,13 @@ packages:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.3.0-nullsafety"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
version: "2.1.0-nullsafety"
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.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/controllers/simple_controller.dart';
export 'package:rive/src/controllers/simple_controller.dart';
export 'package:rive/src/rive_core/animation/linear_animation.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/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/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/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
/// defined in the Rive editor.
class SimpleAnimation extends RiveAnimationController<RuntimeArtboard> {
LinearAnimation _animation;
double _time = 0;
int _direction = 1;
LinearAnimationInstance _instance;
final String animationName;
SimpleAnimation(this.animationName);
@override
bool init(RuntimeArtboard artboard) {
_animation = artboard.animations.firstWhere(
(animation) => animation.name == animationName,
var animation = artboard.animations.firstWhere(
(animation) =>
animation is LinearAnimation && animation.name == animationName,
orElse: () => null,
) as LinearAnimation;
);
if (animation != null) {
_instance = LinearAnimationInstance(animation as LinearAnimation);
}
isActive = true;
return _animation != null;
return _instance != null;
}
@override
void apply(RuntimeArtboard artboard, double elapsedSeconds) {
_animation.apply(_time, coreContext: artboard);
_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;
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;
_instance.animation.apply(_instance.time, coreContext: artboard);
if (!_instance.advance(elapsedSeconds)) {
isActive = false;
}
}

View File

@ -1,11 +1,7 @@
import 'package:rive/src/core/field_types/core_field_type.dart';
import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
class CoreBoolType extends CoreFieldType<bool> {
@override
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> {
@override
double deserialize(BinaryReader reader) => reader.buffer.lengthInBytes == 4
? reader.readFloat32()
: reader.readFloat64();
@override
double lerp(double from, double to, double f) => from + (to - from) * f;
double deserialize(BinaryReader reader) => reader.readFloat32();
}

View File

@ -1,6 +1,6 @@
import 'package:rive/src/utilities/binary_buffer/binary_reader.dart';
// ignore: one_member_abstracts
abstract class CoreFieldType<T> {
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/utilities/binary_buffer/binary_reader.dart';
class CoreIntType extends CoreFieldType<int> {
@override
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> {
@override
String deserialize(BinaryReader reader) => reader.readString();
@override
String lerp(String from, String to, double f) => from;
String deserialize(BinaryReader reader) =>
reader.readString(explicitLength: true);
}

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/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_field_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_uint_type.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/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/triangle.dart';
// ignore: avoid_classes_with_only_static_members
class RiveCoreContext {
static Core makeCoreInstance(int typeKey) {
switch (typeKey) {
@ -475,30 +478,32 @@ class RiveCoreContext {
}
}
static CoreFieldType uintType = CoreUintType();
static CoreFieldType intType = CoreIntType();
static CoreFieldType stringType = CoreStringType();
static CoreFieldType doubleType = CoreDoubleType();
static CoreFieldType colorType = CoreIntType();
static CoreFieldType colorType = CoreColorType();
static CoreFieldType boolType = CoreBoolType();
static CoreFieldType coreType(int propertyKey) {
switch (propertyKey) {
case KeyedObjectBase.objectIdPropertyKey:
case KeyFrameBase.interpolatorIdPropertyKey:
case KeyFrameDrawOrderValueBase.drawableIdPropertyKey:
case KeyFrameDrawOrderValueBase.valuePropertyKey:
case ComponentBase.parentIdPropertyKey:
case DrawableBase.drawOrderPropertyKey:
return uintType;
case KeyedPropertyBase.propertyKeyPropertyKey:
case KeyFrameBase.framePropertyKey:
case KeyFrameBase.interpolationTypePropertyKey:
case KeyFrameBase.interpolatorIdPropertyKey:
case LinearAnimationBase.fpsPropertyKey:
case LinearAnimationBase.durationPropertyKey:
case LinearAnimationBase.loopValuePropertyKey:
case LinearAnimationBase.workStartPropertyKey:
case LinearAnimationBase.workEndPropertyKey:
case KeyFrameDrawOrderValueBase.drawableIdPropertyKey:
case KeyFrameDrawOrderValueBase.valuePropertyKey:
case ComponentBase.parentIdPropertyKey:
case StrokeBase.capPropertyKey:
case StrokeBase.joinPropertyKey:
case FillBase.fillRulePropertyKey:
case DrawableBase.drawOrderPropertyKey:
case DrawableBase.blendModeValuePropertyKey:
return intType;
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) {
case KeyedObjectBase.objectIdPropertyKey:
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:
return (object as KeyedPropertyBase).propertyKey;
case KeyFrameBase.framePropertyKey:
return (object as KeyFrameBase).frame;
case KeyFrameBase.interpolationTypePropertyKey:
return (object as KeyFrameBase).interpolationType;
case KeyFrameBase.interpolatorIdPropertyKey:
return (object as KeyFrameBase).interpolatorId;
case LinearAnimationBase.fpsPropertyKey:
return (object as LinearAnimationBase).fps;
case LinearAnimationBase.durationPropertyKey:
@ -581,20 +600,12 @@ class RiveCoreContext {
return (object as LinearAnimationBase).workStart;
case LinearAnimationBase.workEndPropertyKey:
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:
return (object as StrokeBase).cap;
case StrokeBase.joinPropertyKey:
return (object as StrokeBase).join;
case FillBase.fillRulePropertyKey:
return (object as FillBase).fillRule;
case DrawableBase.drawOrderPropertyKey:
return (object as DrawableBase).drawOrder;
case DrawableBase.blendModeValuePropertyKey:
return (object as DrawableBase).blendModeValue;
}
@ -723,11 +734,31 @@ class RiveCoreContext {
return false;
}
static void setInt(Core object, int propertyKey, int value) {
static void setUint(Core object, int propertyKey, int value) {
switch (propertyKey) {
case KeyedObjectBase.objectIdPropertyKey:
(object as KeyedObjectBase).objectId = value;
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:
(object as KeyedPropertyBase).propertyKey = value;
break;
@ -737,9 +768,6 @@ class RiveCoreContext {
case KeyFrameBase.interpolationTypePropertyKey:
(object as KeyFrameBase).interpolationType = value;
break;
case KeyFrameBase.interpolatorIdPropertyKey:
(object as KeyFrameBase).interpolatorId = value;
break;
case LinearAnimationBase.fpsPropertyKey:
(object as LinearAnimationBase).fps = value;
break;
@ -755,15 +783,6 @@ class RiveCoreContext {
case LinearAnimationBase.workEndPropertyKey:
(object as LinearAnimationBase).workEnd = 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 StrokeBase.capPropertyKey:
(object as StrokeBase).cap = value;
break;
@ -773,9 +792,6 @@ class RiveCoreContext {
case FillBase.fillRulePropertyKey:
(object as FillBase).fillRule = value;
break;
case DrawableBase.drawOrderPropertyKey:
(object as DrawableBase).drawOrder = value;
break;
case DrawableBase.blendModeValuePropertyKey:
(object as DrawableBase).blendModeValue = value;
break;

View File

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

View File

@ -19,10 +19,4 @@ class KeyFrameDrawOrderValue extends KeyFrameDrawOrderValueBase {
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.clipRect(Rect.fromLTWH(0, 0, width, height));
canvas.translate(width * (originX ?? 0), height * (originY ?? 0));
for (final drawable in _drawables) {
drawable.draw(canvas);
}
@ -202,9 +203,15 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
@override
Mat2D get worldTransform => Mat2D();
@override
void originXChanged(double from, double to) {}
void originXChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform);
}
@override
void originYChanged(double from, double to) {}
void originYChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform);
}
bool internalAddAnimation(Animation animation) {
if (_animations.contains(animation)) {
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) {
_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) {
_buffer = Float32List.fromList(copy.values);
}

View File

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

View File

@ -1,7 +1,7 @@
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/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/vec2d.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 {
final Mat2D transform = Mat2D();
final Mat2D worldTransform = Mat2D();
BoundsDelegate _delegate;
double _renderOpacity = 0;
double get renderOpacity => _renderOpacity;
@override
@ -60,16 +59,6 @@ class Node extends NodeBase {
} else {
Mat2D.copy(worldTransform, transform);
}
_delegate?.boundsChanged();
}
@override
void userDataChanged(dynamic from, dynamic to) {
if (to is BoundsDelegate) {
_delegate = to;
} else {
_delegate = null;
}
}
void calculateWorldTransform() {
@ -139,4 +128,6 @@ class Node extends NodeBase {
super.parentChanged(from, to);
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';
class RuntimeHeader {
static const int majorVersion = 1;
static const int majorVersion = 3;
static const int minorVersion = 0;
static const String fingerprint = 'RIVE';
final int ownerId;

View File

@ -16,6 +16,11 @@ class CubicAsymmetricVertex extends CubicAsymmetricVertexBase {
cos(rotation) * outDistance, sin(rotation) * outDistance));
}
@override
set outPoint(Vec2D value) {
_outPoint = Vec2D.clone(value);
}
@override
Vec2D get inPoint {
return _inPoint ??= Vec2D.add(
@ -25,6 +30,11 @@ class CubicAsymmetricVertex extends CubicAsymmetricVertexBase {
cos(rotation) * -inDistance, sin(rotation) * -inDistance));
}
@override
set inPoint(Vec2D value) {
_inPoint = Vec2D.clone(value);
}
@override
String 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));
}
@override
set outPoint(Vec2D value) {
_outPoint = Vec2D.clone(value);
}
@override
Vec2D get inPoint {
return _inPoint ??= Vec2D.add(Vec2D(), translation,
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
String 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 {
Vec2D get outPoint;
Vec2D get inPoint;
set outPoint(Vec2D value);
set inPoint(Vec2D value);
}

View File

@ -1,17 +1,10 @@
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/generated/shapes/paint/gradient_stop_base.dart';
import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart';
export 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart';
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 get gradient => _gradient;
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 {
final List<GradientStop> gradientStops = [];
@override
Component get timelineProxy => parent;
bool _paintsInWorldSpace = true;
bool get paintsInWorldSpace => _paintsInWorldSpace;
set paintsInWorldSpace(bool value) {

View File

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

View File

@ -1,5 +1,4 @@
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/shapes/paint/shape_paint_mutator.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';
class SolidColor extends SolidColorBase with ShapePaintMutator {
@override
Component get timelineProxy => parent;
Color get color => Color(colorValue);
set color(Color c) {
colorValue = c.value;

View File

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

View File

@ -1,6 +1,5 @@
import 'dart:math';
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_dirt.dart';
import 'package:rive/src/rive_core/math/aabb.dart';
@ -33,27 +32,11 @@ abstract class Path extends PathBase {
Mat2D get inversePathTransform;
Mat2D get inverseWorldTransform => _inverseWorldTransform;
@override
Component get timelineParent => _shape;
@override
bool resolveArtboard() {
_changeShape(null);
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
void visitAncestor(Component ancestor) {
if (_shape == null && ancestor is Shape) {
@ -95,18 +78,9 @@ abstract class Path extends PathBase {
void markPathDirty() {
addDirt(ComponentDirt.path);
_shape?.pathChanged(this);
}
void _invalidatePath() {
_isValid = false;
_cachedRenderVertices = null;
}
@override
bool addDirt(int value, {bool recurse = false}) {
_invalidatePath();
return super.addDirt(value, recurse: recurse);
_shape?.pathChanged(this);
}
List<PathVertex> get vertices;
@ -126,6 +100,7 @@ abstract class Path extends PathBase {
List<PathVertex> renderPoints = [];
int pl = pts.length;
const double iarcConstant = 1.0 - circleConstant;
PathVertex previous = isClosed ? pts[pl - 1] : null;
for (int i = 0; i < pl; i++) {
PathVertex point = pts[i];
@ -221,7 +196,10 @@ abstract class Path extends PathBase {
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) {
return AABB();
}
@ -247,7 +225,6 @@ abstract class Path extends PathBase {
cin = Vec2D.transformMat2D(Vec2D(), cin, transform);
cout = Vec2D.transformMat2D(Vec2D(), cout, transform);
}
const double epsilon = 0.000000001;
final double startX = lastPoint[0];
final double startY = lastPoint[1];
final double cpX1 = cout[0];
@ -257,121 +234,55 @@ abstract class Path extends PathBase {
final double endX = next[0];
final double endY = next[1];
lastPoint = next;
double extremaX;
double extremaY;
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;
}
}
}
}
}
_expandBoundsForAxis(bounds, 0, startX, cpX1, cpX2, endX);
_expandBoundsForAxis(bounds, 1, startY, cpY1, cpY2, endY);
}
}
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/shapes/cubic_vertex.dart';
import 'package:rive/src/utilities/binary_buffer/binary_writer.dart';
class RenderCubicVertex extends CubicVertex {
@override
void changeNonNull() {}
@override
Vec2D inPoint;
@override
Vec2D outPoint;
@override
void onAddedDirty() {}
@override
void writeRuntimeProperties(
BinaryWriter writer, HashMap<int, int> idLookup) {}
}

View File

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

View File

@ -97,10 +97,10 @@ class RiveFile {
continue;
} else if (keyframe is KeyFrameDrawOrder) {
int numValues = reader.readVarUint();
for (int i = 0; i < numValues; i++) {
for (int m = 0; m < numValues; m++) {
var valueObject = KeyFrameDrawOrderValue();
valueObject.drawableId = reader.readVarInt();
valueObject.value = i;
valueObject.drawableId = reader.readVarUint();
valueObject.value = m;
keyframe.internalAddValue(valueObject);
}
}
@ -153,30 +153,15 @@ T readRuntimeObject<T extends Core<CoreContext>>(BinaryReader reader,
// Terminator. https://media.giphy.com/media/7TtvTUMm9mp20/giphy.gif
break;
}
int propertyLength = reader.readVarUint();
Uint8List valueBytes = reader.read(propertyLength);
var fieldType = RiveCoreContext.coreType(propertyKey);
if (fieldType == null) {
// This is considered an acceptable failure. A runtime may not support
// the same properties that were exported. The older object could still
// 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;
throw UnsupportedError('Unsupported property key $propertyKey. '
'A new runtime is likely necessary to play this file.');
}
// 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(
object, propertyKey, fieldType.deserialize(valueReader));
object, propertyKey, fieldType.deserialize(reader));
}
return object as T;
}

View File

@ -7,6 +7,7 @@ class BinaryReader {
final ByteData buffer;
final Endian endian;
int _readIndex = 0;
int get position => _readIndex;
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
/// integer length written first followed by length number of utf8 encoded
/// bytes.
String readString() {
int length = readVarUint();
String readString({bool explicitLength = true}) {
int length = explicitLength ? readVarUint() : buffer.lengthInBytes;
String value = _utf8Decoder.convert(Uint8List.view(
buffer.buffer, buffer.offsetInBytes + _readIndex, length));
_readIndex += length;

View File

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

View File

@ -21,7 +21,7 @@ packages:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
version: "1.1.0-nullsafety"
charcode:
dependency: transitive
description:
@ -42,7 +42,7 @@ packages:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.13"
version: "1.15.0-nullsafety"
fake_async:
dependency: transitive
description:
@ -80,7 +80,7 @@ packages:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.8"
version: "1.3.0-nullsafety"
path:
dependency: transitive
description:
@ -141,13 +141,13 @@ packages:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.3.0-nullsafety"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
version: "2.1.0-nullsafety"
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
description: Rive 2 Flutter Runtime
version: 0.0.1+2
version: 0.0.4
repository: https://github.com/rive-app/rive-flutter
homepage: https://rive.app
environment:
sdk: ">=2.2.2 <3.0.0"
@ -15,5 +16,3 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
flutter: