mirror of
https://github.com/rive-app/rive-flutter.git
synced 2025-06-26 01:18:13 +08:00
Adding support for parametric path origin.
This commit is contained in:
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 '
|
||||
|
@ -28,7 +28,7 @@ class ClippingShape extends ClippingShapeBase {
|
||||
|
||||
@override
|
||||
void sourceIdChanged(int from, int to) {
|
||||
_source = context?.resolve(to);
|
||||
source = context?.resolve(to);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -6,36 +6,41 @@ export 'package:rive/src/generated/shapes/ellipse_base.dart';
|
||||
|
||||
class Ellipse extends EllipseBase {
|
||||
@override
|
||||
List<PathVertex> 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<PathVertex> 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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -10,7 +10,7 @@ export 'package:rive/src/generated/shapes/path_vertex_base.dart';
|
||||
abstract class PathVertex<T extends Weight> 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();
|
||||
|
@ -5,24 +5,29 @@ export 'package:rive/src/generated/shapes/rectangle_base.dart';
|
||||
|
||||
class Rectangle extends RectangleBase {
|
||||
@override
|
||||
List<PathVertex> 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<PathVertex> 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();
|
||||
}
|
||||
|
@ -5,15 +5,19 @@ export 'package:rive/src/generated/shapes/triangle_base.dart';
|
||||
|
||||
class Triangle extends TriangleBase {
|
||||
@override
|
||||
List<PathVertex> get vertices => [
|
||||
StraightVertex()
|
||||
..x = 0
|
||||
..y = -height / 2,
|
||||
StraightVertex()
|
||||
..x = width / 2
|
||||
..y = height / 2,
|
||||
StraightVertex()
|
||||
..x = -width / 2
|
||||
..y = height / 2
|
||||
];
|
||||
List<PathVertex> 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
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user