diff --git a/lib/src/generated/artboard_base.dart b/lib/src/generated/artboard_base.dart index b8f3754..d5b688a 100644 --- a/lib/src/generated/artboard_base.dart +++ b/lib/src/generated/artboard_base.dart @@ -105,7 +105,7 @@ abstract class ArtboardBase extends ContainerComponent { double _originX; static const int originXPropertyKey = 11; - /// Origin x in normalized coordinates (0 = center, -1 = left, 1 = right). + /// Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right). double get originX => _originX; /// Change the [_originX] field value. @@ -126,7 +126,7 @@ abstract class ArtboardBase extends ContainerComponent { double _originY; static const int originYPropertyKey = 12; - /// Origin y in normalized coordinates (0 = center, -1 = left, 1 = right). + /// Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom). double get originY => _originY; /// Change the [_originY] field value. diff --git a/lib/src/generated/rive_core_context.dart b/lib/src/generated/rive_core_context.dart index 82b75e5..385a04d 100644 --- a/lib/src/generated/rive_core_context.dart +++ b/lib/src/generated/rive_core_context.dart @@ -500,6 +500,16 @@ class RiveCoreContext { object.height = value; } break; + case ParametricPathBase.originXPropertyKey: + if (object is ParametricPathBase && value is double) { + object.originX = value; + } + break; + case ParametricPathBase.originYPropertyKey: + if (object is ParametricPathBase && value is double) { + object.originY = value; + } + break; case RectangleBase.cornerRadiusPropertyKey: if (object is RectangleBase && value is double) { object.cornerRadius = value; @@ -738,6 +748,8 @@ class RiveCoreContext { case CubicAsymmetricVertexBase.outDistancePropertyKey: case ParametricPathBase.widthPropertyKey: case ParametricPathBase.heightPropertyKey: + case ParametricPathBase.originXPropertyKey: + case ParametricPathBase.originYPropertyKey: case RectangleBase.cornerRadiusPropertyKey: case CubicMirroredVertexBase.rotationPropertyKey: case CubicMirroredVertexBase.distancePropertyKey: @@ -918,6 +930,10 @@ class RiveCoreContext { return (object as ParametricPathBase).width; case ParametricPathBase.heightPropertyKey: return (object as ParametricPathBase).height; + case ParametricPathBase.originXPropertyKey: + return (object as ParametricPathBase).originX; + case ParametricPathBase.originYPropertyKey: + return (object as ParametricPathBase).originY; case RectangleBase.cornerRadiusPropertyKey: return (object as RectangleBase).cornerRadius; case CubicMirroredVertexBase.rotationPropertyKey: @@ -1201,6 +1217,12 @@ class RiveCoreContext { case ParametricPathBase.heightPropertyKey: (object as ParametricPathBase).height = value; break; + case ParametricPathBase.originXPropertyKey: + (object as ParametricPathBase).originX = value; + break; + case ParametricPathBase.originYPropertyKey: + (object as ParametricPathBase).originY = value; + break; case RectangleBase.cornerRadiusPropertyKey: (object as RectangleBase).cornerRadius = value; break; diff --git a/lib/src/generated/shapes/parametric_path_base.dart b/lib/src/generated/shapes/parametric_path_base.dart index 675ab7b..79ad3e6 100644 --- a/lib/src/generated/shapes/parametric_path_base.dart +++ b/lib/src/generated/shapes/parametric_path_base.dart @@ -64,4 +64,46 @@ abstract class ParametricPathBase extends Path { } void heightChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// OriginX field with key 123. + double _originX = 0.5; + static const int originXPropertyKey = 123; + + /// Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right). + double get originX => _originX; + + /// Change the [_originX] field value. + /// [originXChanged] will be invoked only if the field's value has changed. + set originX(double value) { + if (_originX == value) { + return; + } + double from = _originX; + _originX = value; + originXChanged(from, value); + } + + void originXChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// OriginY field with key 124. + double _originY = 0.5; + static const int originYPropertyKey = 124; + + /// Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom). + double get originY => _originY; + + /// Change the [_originY] field value. + /// [originYChanged] will be invoked only if the field's value has changed. + set originY(double value) { + if (_originY == value) { + return; + } + double from = _originY; + _originY = value; + originYChanged(from, value); + } + + void originYChanged(double from, double to); } diff --git a/lib/src/rive.dart b/lib/src/rive.dart index 4e58cb2..249bfeb 100644 --- a/lib/src/rive.dart +++ b/lib/src/rive.dart @@ -64,9 +64,7 @@ class RiveRenderObject extends RiveRenderBox { AABB get aabb { var width = _artboard.width; var height = _artboard.height; - double minX = -1 * _artboard.originX * width; - double minY = -1 * _artboard.originY * height; - return AABB.fromValues(minX, minY, minX + width, minY + height); + return AABB.fromValues(0, 0, width, height); } @override diff --git a/lib/src/rive_core/container_component.dart b/lib/src/rive_core/container_component.dart index 649506c..c7967a7 100644 --- a/lib/src/rive_core/container_component.dart +++ b/lib/src/rive_core/container_component.dart @@ -13,6 +13,10 @@ abstract class ContainerComponent extends ContainerComponentBase { child.parent = this; } + void prependChild(Component child) { + child.parent = this; + } + @mustCallSuper void childAdded(Component child) {} void childRemoved(Component child) {} diff --git a/lib/src/rive_core/drawable.dart b/lib/src/rive_core/drawable.dart index 6676be7..2b3f7b6 100644 --- a/lib/src/rive_core/drawable.dart +++ b/lib/src/rive_core/drawable.dart @@ -39,6 +39,12 @@ abstract class Drawable extends DrawableBase { return true; } + @override + void parentChanged(ContainerComponent from, ContainerComponent to) { + super.parentChanged(from, to); + addDirt(ComponentDirt.clip); + } + @override void update(int dirt) { super.update(dirt); diff --git a/lib/src/rive_core/math/aabb.dart b/lib/src/rive_core/math/aabb.dart index 8d0698a..a84d0fb 100644 --- a/lib/src/rive_core/math/aabb.dart +++ b/lib/src/rive_core/math/aabb.dart @@ -45,13 +45,7 @@ class AABB { ]); } double get area => width * height; - bool get isEmpty { - return _buffer[0] == double.maxFinite && - _buffer[1] == double.maxFinite && - _buffer[2] == -double.maxFinite && - _buffer[3] == -double.maxFinite; - } - + bool get isEmpty => !AABB.isValid(this); Vec2D includePoint(Vec2D point, Mat2D transform) { var transformedPoint = transform == null ? point diff --git a/lib/src/rive_core/math/transform_components.dart b/lib/src/rive_core/math/transform_components.dart index bb65125..1e6fab8 100644 --- a/lib/src/rive_core/math/transform_components.dart +++ b/lib/src/rive_core/math/transform_components.dart @@ -78,6 +78,15 @@ class TransformComponents { return Vec2D.fromValues(_buffer[2], _buffer[3]); } + static void copy(TransformComponents source, TransformComponents other) { + source._buffer[0] = other._buffer[0]; + source._buffer[1] = other._buffer[1]; + source._buffer[2] = other._buffer[2]; + source._buffer[3] = other._buffer[3]; + source._buffer[4] = other._buffer[4]; + source._buffer[5] = other._buffer[5]; + } + @override String toString() { return 'TransformComponents(x: $x y: $y sx: $scaleX ' diff --git a/lib/src/rive_core/shapes/clipping_shape.dart b/lib/src/rive_core/shapes/clipping_shape.dart index a34a667..9de56e5 100644 --- a/lib/src/rive_core/shapes/clipping_shape.dart +++ b/lib/src/rive_core/shapes/clipping_shape.dart @@ -28,7 +28,7 @@ class ClippingShape extends ClippingShapeBase { @override void sourceIdChanged(int from, int to) { - _source = context?.resolve(to); + source = context?.resolve(to); } @override diff --git a/lib/src/rive_core/shapes/ellipse.dart b/lib/src/rive_core/shapes/ellipse.dart index 2e934a7..0f76b63 100644 --- a/lib/src/rive_core/shapes/ellipse.dart +++ b/lib/src/rive_core/shapes/ellipse.dart @@ -6,36 +6,41 @@ export 'package:rive/src/generated/shapes/ellipse_base.dart'; class Ellipse extends EllipseBase { @override - List get vertices => [ - CubicDetachedVertex.fromValues( - x: 0, - y: -radiusY, - inX: -radiusX * circleConstant, - inY: -radiusY, - outX: radiusX * circleConstant, - outY: -radiusY), - CubicDetachedVertex.fromValues( - x: radiusX, - y: 0, - inX: radiusX, - inY: circleConstant * -radiusY, - outX: radiusX, - outY: circleConstant * radiusY), - CubicDetachedVertex.fromValues( - x: 0, - y: radiusY, - inX: radiusX * circleConstant, - inY: radiusY, - outX: -radiusX * circleConstant, - outY: radiusY), - CubicDetachedVertex.fromValues( - x: -radiusX, - y: 0, - inX: -radiusX, - inY: radiusY * circleConstant, - outX: -radiusX, - outY: -radiusY * circleConstant) - ]; + List get vertices { + double ox = -originX * width + radiusX; + double oy = -originY * height + radiusY; + return [ + CubicDetachedVertex.fromValues( + x: ox, + y: oy - radiusY, + inX: ox - radiusX * circleConstant, + inY: oy - radiusY, + outX: ox + radiusX * circleConstant, + outY: oy - radiusY), + CubicDetachedVertex.fromValues( + x: ox + radiusX, + y: oy, + inX: ox + radiusX, + inY: oy + circleConstant * -radiusY, + outX: ox + radiusX, + outY: oy + circleConstant * radiusY), + CubicDetachedVertex.fromValues( + x: ox, + y: oy + radiusY, + inX: ox + radiusX * circleConstant, + inY: oy + radiusY, + outX: ox - radiusX * circleConstant, + outY: oy + radiusY), + CubicDetachedVertex.fromValues( + x: ox - radiusX, + y: oy, + inX: ox - radiusX, + inY: oy + radiusY * circleConstant, + outX: ox - radiusX, + outY: oy - radiusY * circleConstant) + ]; + } + double get radiusX => width / 2; double get radiusY => height / 2; } diff --git a/lib/src/rive_core/shapes/parametric_path.dart b/lib/src/rive_core/shapes/parametric_path.dart index b0d8355..7f38e77 100644 --- a/lib/src/rive_core/shapes/parametric_path.dart +++ b/lib/src/rive_core/shapes/parametric_path.dart @@ -42,4 +42,9 @@ abstract class ParametricPath extends ParametricPathBase { super.scaleYChanged(from, to); shape?.pathChanged(this); } + + @override + void originXChanged(double from, double to) => markPathDirty(); + @override + void originYChanged(double from, double to) => markPathDirty(); } diff --git a/lib/src/rive_core/shapes/path_composer.dart b/lib/src/rive_core/shapes/path_composer.dart index d775468..b6bd4b3 100644 --- a/lib/src/rive_core/shapes/path_composer.dart +++ b/lib/src/rive_core/shapes/path_composer.dart @@ -30,18 +30,17 @@ class PathComposer extends PathComposerBase { localPath.reset(); var world = _shape.worldTransform; Mat2D inverseWorld = Mat2D(); - if (!Mat2D.invert(inverseWorld, world)) { - Mat2D.identity(inverseWorld); - } - for (final path in _shape.paths) { - Mat2D localTransform; - var transform = path.pathTransform; - if (transform != null) { - localTransform = Mat2D(); - Mat2D.multiply(localTransform, inverseWorld, transform); + if (Mat2D.invert(inverseWorld, world)) { + for (final path in _shape.paths) { + Mat2D localTransform; + var transform = path.pathTransform; + if (transform != null) { + localTransform = Mat2D(); + Mat2D.multiply(localTransform, inverseWorld, transform); + } + localPath.addPath(path.uiPath, ui.Offset.zero, + matrix4: localTransform?.mat4); } - localPath.addPath(path.uiPath, ui.Offset.zero, - matrix4: localTransform?.mat4); } } if (buildWorldPath) { diff --git a/lib/src/rive_core/shapes/path_vertex.dart b/lib/src/rive_core/shapes/path_vertex.dart index ec6b9e1..b2d7c7e 100644 --- a/lib/src/rive_core/shapes/path_vertex.dart +++ b/lib/src/rive_core/shapes/path_vertex.dart @@ -10,7 +10,7 @@ export 'package:rive/src/generated/shapes/path_vertex_base.dart'; abstract class PathVertex extends PathVertexBase { T _weight; T get weight => _weight; - Path get path => parent as Path; + Path get path => parent is Path ? parent as Path : null; @override void update(int dirt) {} final Vec2D _renderTranslation = Vec2D(); diff --git a/lib/src/rive_core/shapes/rectangle.dart b/lib/src/rive_core/shapes/rectangle.dart index 95f3ac6..2d460e4 100644 --- a/lib/src/rive_core/shapes/rectangle.dart +++ b/lib/src/rive_core/shapes/rectangle.dart @@ -5,24 +5,29 @@ export 'package:rive/src/generated/shapes/rectangle_base.dart'; class Rectangle extends RectangleBase { @override - List get vertices => [ - StraightVertex() - ..x = -width / 2 - ..y = -height / 2 - ..radius = cornerRadius, - StraightVertex() - ..x = width / 2 - ..y = -height / 2 - ..radius = cornerRadius, - StraightVertex() - ..x = width / 2 - ..y = height / 2 - ..radius = cornerRadius, - StraightVertex() - ..x = -width / 2 - ..y = height / 2 - ..radius = cornerRadius - ]; + List get vertices { + double ox = -originX * width; + double oy = -originY * height; + return [ + StraightVertex() + ..x = ox + ..y = oy + ..radius = cornerRadius, + StraightVertex() + ..x = ox + width + ..y = oy + ..radius = cornerRadius, + StraightVertex() + ..x = ox + width + ..y = oy + height + ..radius = cornerRadius, + StraightVertex() + ..x = ox + ..y = oy + height + ..radius = cornerRadius + ]; + } + @override void cornerRadiusChanged(double from, double to) => markPathDirty(); } diff --git a/lib/src/rive_core/shapes/triangle.dart b/lib/src/rive_core/shapes/triangle.dart index 949e74f..7c6af84 100644 --- a/lib/src/rive_core/shapes/triangle.dart +++ b/lib/src/rive_core/shapes/triangle.dart @@ -5,15 +5,19 @@ export 'package:rive/src/generated/shapes/triangle_base.dart'; class Triangle extends TriangleBase { @override - List get vertices => [ - StraightVertex() - ..x = 0 - ..y = -height / 2, - StraightVertex() - ..x = width / 2 - ..y = height / 2, - StraightVertex() - ..x = -width / 2 - ..y = height / 2 - ]; + List get vertices { + double ox = -originX * width; + double oy = -originY * height; + return [ + StraightVertex() + ..x = ox + width / 2 + ..y = oy, + StraightVertex() + ..x = ox + width + ..y = oy + height, + StraightVertex() + ..x = ox + ..y = oy + height + ]; + } } diff --git a/lib/src/utilities/binary_buffer/binary_reader.dart b/lib/src/utilities/binary_buffer/binary_reader.dart index e3fc826..ccfab4f 100644 --- a/lib/src/utilities/binary_buffer/binary_reader.dart +++ b/lib/src/utilities/binary_buffer/binary_reader.dart @@ -1,9 +1,8 @@ import 'dart:convert'; import 'dart:typed_data'; -var _utf8Decoder = const Utf8Decoder(); - class BinaryReader { + final _utf8Decoder = const Utf8Decoder(); final ByteData buffer; final Endian endian; @@ -106,7 +105,7 @@ class BinaryReader { return value; } - Uint8List read(int length, [bool allocNew = false]) { + Uint8List read(int length, [bool allocNew = true]) { var view = Uint8List.view(buffer.buffer, buffer.offsetInBytes + readIndex, length); readIndex += length; diff --git a/lib/src/utilities/binary_buffer/binary_writer.dart b/lib/src/utilities/binary_buffer/binary_writer.dart index b8c6015..427705e 100644 --- a/lib/src/utilities/binary_buffer/binary_writer.dart +++ b/lib/src/utilities/binary_buffer/binary_writer.dart @@ -3,10 +3,10 @@ import 'dart:math'; import 'dart:typed_data'; -var _variableEncodeList = Uint8List(8); -var _utf8Encoder = const Utf8Encoder(); - class BinaryWriter { + final _variableEncodeList = Uint8List(8); + final _utf8Encoder = const Utf8Encoder(); + /// Stride we allocate buffer in chunks of. final int _alignment; int get alignment => _alignment;