mirror of
https://github.com/rive-app/rive-flutter.git
synced 2025-07-20 21:24:54 +08:00
Adding support for parametric path origin.
This commit is contained in:
lib/src
@ -105,7 +105,7 @@ abstract class ArtboardBase extends ContainerComponent {
|
|||||||
double _originX;
|
double _originX;
|
||||||
static const int originXPropertyKey = 11;
|
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;
|
double get originX => _originX;
|
||||||
|
|
||||||
/// Change the [_originX] field value.
|
/// Change the [_originX] field value.
|
||||||
@ -126,7 +126,7 @@ abstract class ArtboardBase extends ContainerComponent {
|
|||||||
double _originY;
|
double _originY;
|
||||||
static const int originYPropertyKey = 12;
|
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;
|
double get originY => _originY;
|
||||||
|
|
||||||
/// Change the [_originY] field value.
|
/// Change the [_originY] field value.
|
||||||
|
@ -500,6 +500,16 @@ class RiveCoreContext {
|
|||||||
object.height = value;
|
object.height = value;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case RectangleBase.cornerRadiusPropertyKey:
|
||||||
if (object is RectangleBase && value is double) {
|
if (object is RectangleBase && value is double) {
|
||||||
object.cornerRadius = value;
|
object.cornerRadius = value;
|
||||||
@ -738,6 +748,8 @@ class RiveCoreContext {
|
|||||||
case CubicAsymmetricVertexBase.outDistancePropertyKey:
|
case CubicAsymmetricVertexBase.outDistancePropertyKey:
|
||||||
case ParametricPathBase.widthPropertyKey:
|
case ParametricPathBase.widthPropertyKey:
|
||||||
case ParametricPathBase.heightPropertyKey:
|
case ParametricPathBase.heightPropertyKey:
|
||||||
|
case ParametricPathBase.originXPropertyKey:
|
||||||
|
case ParametricPathBase.originYPropertyKey:
|
||||||
case RectangleBase.cornerRadiusPropertyKey:
|
case RectangleBase.cornerRadiusPropertyKey:
|
||||||
case CubicMirroredVertexBase.rotationPropertyKey:
|
case CubicMirroredVertexBase.rotationPropertyKey:
|
||||||
case CubicMirroredVertexBase.distancePropertyKey:
|
case CubicMirroredVertexBase.distancePropertyKey:
|
||||||
@ -918,6 +930,10 @@ class RiveCoreContext {
|
|||||||
return (object as ParametricPathBase).width;
|
return (object as ParametricPathBase).width;
|
||||||
case ParametricPathBase.heightPropertyKey:
|
case ParametricPathBase.heightPropertyKey:
|
||||||
return (object as ParametricPathBase).height;
|
return (object as ParametricPathBase).height;
|
||||||
|
case ParametricPathBase.originXPropertyKey:
|
||||||
|
return (object as ParametricPathBase).originX;
|
||||||
|
case ParametricPathBase.originYPropertyKey:
|
||||||
|
return (object as ParametricPathBase).originY;
|
||||||
case RectangleBase.cornerRadiusPropertyKey:
|
case RectangleBase.cornerRadiusPropertyKey:
|
||||||
return (object as RectangleBase).cornerRadius;
|
return (object as RectangleBase).cornerRadius;
|
||||||
case CubicMirroredVertexBase.rotationPropertyKey:
|
case CubicMirroredVertexBase.rotationPropertyKey:
|
||||||
@ -1201,6 +1217,12 @@ class RiveCoreContext {
|
|||||||
case ParametricPathBase.heightPropertyKey:
|
case ParametricPathBase.heightPropertyKey:
|
||||||
(object as ParametricPathBase).height = value;
|
(object as ParametricPathBase).height = value;
|
||||||
break;
|
break;
|
||||||
|
case ParametricPathBase.originXPropertyKey:
|
||||||
|
(object as ParametricPathBase).originX = value;
|
||||||
|
break;
|
||||||
|
case ParametricPathBase.originYPropertyKey:
|
||||||
|
(object as ParametricPathBase).originY = value;
|
||||||
|
break;
|
||||||
case RectangleBase.cornerRadiusPropertyKey:
|
case RectangleBase.cornerRadiusPropertyKey:
|
||||||
(object as RectangleBase).cornerRadius = value;
|
(object as RectangleBase).cornerRadius = value;
|
||||||
break;
|
break;
|
||||||
|
@ -64,4 +64,46 @@ abstract class ParametricPathBase extends Path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void heightChanged(double from, double to);
|
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 {
|
AABB get aabb {
|
||||||
var width = _artboard.width;
|
var width = _artboard.width;
|
||||||
var height = _artboard.height;
|
var height = _artboard.height;
|
||||||
double minX = -1 * _artboard.originX * width;
|
return AABB.fromValues(0, 0, width, height);
|
||||||
double minY = -1 * _artboard.originY * height;
|
|
||||||
return AABB.fromValues(minX, minY, minX + width, minY + height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -13,6 +13,10 @@ abstract class ContainerComponent extends ContainerComponentBase {
|
|||||||
child.parent = this;
|
child.parent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void prependChild(Component child) {
|
||||||
|
child.parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
@mustCallSuper
|
@mustCallSuper
|
||||||
void childAdded(Component child) {}
|
void childAdded(Component child) {}
|
||||||
void childRemoved(Component child) {}
|
void childRemoved(Component child) {}
|
||||||
|
@ -39,6 +39,12 @@ abstract class Drawable extends DrawableBase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void parentChanged(ContainerComponent from, ContainerComponent to) {
|
||||||
|
super.parentChanged(from, to);
|
||||||
|
addDirt(ComponentDirt.clip);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void update(int dirt) {
|
void update(int dirt) {
|
||||||
super.update(dirt);
|
super.update(dirt);
|
||||||
|
@ -45,13 +45,7 @@ class AABB {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
double get area => width * height;
|
double get area => width * height;
|
||||||
bool get isEmpty {
|
bool get isEmpty => !AABB.isValid(this);
|
||||||
return _buffer[0] == double.maxFinite &&
|
|
||||||
_buffer[1] == double.maxFinite &&
|
|
||||||
_buffer[2] == -double.maxFinite &&
|
|
||||||
_buffer[3] == -double.maxFinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D includePoint(Vec2D point, Mat2D transform) {
|
Vec2D includePoint(Vec2D point, Mat2D transform) {
|
||||||
var transformedPoint = transform == null
|
var transformedPoint = transform == null
|
||||||
? point
|
? point
|
||||||
|
@ -78,6 +78,15 @@ class TransformComponents {
|
|||||||
return Vec2D.fromValues(_buffer[2], _buffer[3]);
|
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
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'TransformComponents(x: $x y: $y sx: $scaleX '
|
return 'TransformComponents(x: $x y: $y sx: $scaleX '
|
||||||
|
@ -28,7 +28,7 @@ class ClippingShape extends ClippingShapeBase {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void sourceIdChanged(int from, int to) {
|
void sourceIdChanged(int from, int to) {
|
||||||
_source = context?.resolve(to);
|
source = context?.resolve(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -6,36 +6,41 @@ export 'package:rive/src/generated/shapes/ellipse_base.dart';
|
|||||||
|
|
||||||
class Ellipse extends EllipseBase {
|
class Ellipse extends EllipseBase {
|
||||||
@override
|
@override
|
||||||
List<PathVertex> get vertices => [
|
List<PathVertex> get vertices {
|
||||||
|
double ox = -originX * width + radiusX;
|
||||||
|
double oy = -originY * height + radiusY;
|
||||||
|
return [
|
||||||
CubicDetachedVertex.fromValues(
|
CubicDetachedVertex.fromValues(
|
||||||
x: 0,
|
x: ox,
|
||||||
y: -radiusY,
|
y: oy - radiusY,
|
||||||
inX: -radiusX * circleConstant,
|
inX: ox - radiusX * circleConstant,
|
||||||
inY: -radiusY,
|
inY: oy - radiusY,
|
||||||
outX: radiusX * circleConstant,
|
outX: ox + radiusX * circleConstant,
|
||||||
outY: -radiusY),
|
outY: oy - radiusY),
|
||||||
CubicDetachedVertex.fromValues(
|
CubicDetachedVertex.fromValues(
|
||||||
x: radiusX,
|
x: ox + radiusX,
|
||||||
y: 0,
|
y: oy,
|
||||||
inX: radiusX,
|
inX: ox + radiusX,
|
||||||
inY: circleConstant * -radiusY,
|
inY: oy + circleConstant * -radiusY,
|
||||||
outX: radiusX,
|
outX: ox + radiusX,
|
||||||
outY: circleConstant * radiusY),
|
outY: oy + circleConstant * radiusY),
|
||||||
CubicDetachedVertex.fromValues(
|
CubicDetachedVertex.fromValues(
|
||||||
x: 0,
|
x: ox,
|
||||||
y: radiusY,
|
y: oy + radiusY,
|
||||||
inX: radiusX * circleConstant,
|
inX: ox + radiusX * circleConstant,
|
||||||
inY: radiusY,
|
inY: oy + radiusY,
|
||||||
outX: -radiusX * circleConstant,
|
outX: ox - radiusX * circleConstant,
|
||||||
outY: radiusY),
|
outY: oy + radiusY),
|
||||||
CubicDetachedVertex.fromValues(
|
CubicDetachedVertex.fromValues(
|
||||||
x: -radiusX,
|
x: ox - radiusX,
|
||||||
y: 0,
|
y: oy,
|
||||||
inX: -radiusX,
|
inX: ox - radiusX,
|
||||||
inY: radiusY * circleConstant,
|
inY: oy + radiusY * circleConstant,
|
||||||
outX: -radiusX,
|
outX: ox - radiusX,
|
||||||
outY: -radiusY * circleConstant)
|
outY: oy - radiusY * circleConstant)
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
double get radiusX => width / 2;
|
double get radiusX => width / 2;
|
||||||
double get radiusY => height / 2;
|
double get radiusY => height / 2;
|
||||||
}
|
}
|
||||||
|
@ -42,4 +42,9 @@ abstract class ParametricPath extends ParametricPathBase {
|
|||||||
super.scaleYChanged(from, to);
|
super.scaleYChanged(from, to);
|
||||||
shape?.pathChanged(this);
|
shape?.pathChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void originXChanged(double from, double to) => markPathDirty();
|
||||||
|
@override
|
||||||
|
void originYChanged(double from, double to) => markPathDirty();
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,7 @@ class PathComposer extends PathComposerBase {
|
|||||||
localPath.reset();
|
localPath.reset();
|
||||||
var world = _shape.worldTransform;
|
var world = _shape.worldTransform;
|
||||||
Mat2D inverseWorld = Mat2D();
|
Mat2D inverseWorld = Mat2D();
|
||||||
if (!Mat2D.invert(inverseWorld, world)) {
|
if (Mat2D.invert(inverseWorld, world)) {
|
||||||
Mat2D.identity(inverseWorld);
|
|
||||||
}
|
|
||||||
for (final path in _shape.paths) {
|
for (final path in _shape.paths) {
|
||||||
Mat2D localTransform;
|
Mat2D localTransform;
|
||||||
var transform = path.pathTransform;
|
var transform = path.pathTransform;
|
||||||
@ -44,6 +42,7 @@ class PathComposer extends PathComposerBase {
|
|||||||
matrix4: localTransform?.mat4);
|
matrix4: localTransform?.mat4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (buildWorldPath) {
|
if (buildWorldPath) {
|
||||||
worldPath.reset();
|
worldPath.reset();
|
||||||
for (final path in _shape.paths) {
|
for (final path in _shape.paths) {
|
||||||
|
@ -10,7 +10,7 @@ export 'package:rive/src/generated/shapes/path_vertex_base.dart';
|
|||||||
abstract class PathVertex<T extends Weight> extends PathVertexBase {
|
abstract class PathVertex<T extends Weight> extends PathVertexBase {
|
||||||
T _weight;
|
T _weight;
|
||||||
T get weight => _weight;
|
T get weight => _weight;
|
||||||
Path get path => parent as Path;
|
Path get path => parent is Path ? parent as Path : null;
|
||||||
@override
|
@override
|
||||||
void update(int dirt) {}
|
void update(int dirt) {}
|
||||||
final Vec2D _renderTranslation = Vec2D();
|
final Vec2D _renderTranslation = Vec2D();
|
||||||
|
@ -5,24 +5,29 @@ export 'package:rive/src/generated/shapes/rectangle_base.dart';
|
|||||||
|
|
||||||
class Rectangle extends RectangleBase {
|
class Rectangle extends RectangleBase {
|
||||||
@override
|
@override
|
||||||
List<PathVertex> get vertices => [
|
List<PathVertex> get vertices {
|
||||||
|
double ox = -originX * width;
|
||||||
|
double oy = -originY * height;
|
||||||
|
return [
|
||||||
StraightVertex()
|
StraightVertex()
|
||||||
..x = -width / 2
|
..x = ox
|
||||||
..y = -height / 2
|
..y = oy
|
||||||
..radius = cornerRadius,
|
..radius = cornerRadius,
|
||||||
StraightVertex()
|
StraightVertex()
|
||||||
..x = width / 2
|
..x = ox + width
|
||||||
..y = -height / 2
|
..y = oy
|
||||||
..radius = cornerRadius,
|
..radius = cornerRadius,
|
||||||
StraightVertex()
|
StraightVertex()
|
||||||
..x = width / 2
|
..x = ox + width
|
||||||
..y = height / 2
|
..y = oy + height
|
||||||
..radius = cornerRadius,
|
..radius = cornerRadius,
|
||||||
StraightVertex()
|
StraightVertex()
|
||||||
..x = -width / 2
|
..x = ox
|
||||||
..y = height / 2
|
..y = oy + height
|
||||||
..radius = cornerRadius
|
..radius = cornerRadius
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void cornerRadiusChanged(double from, double to) => markPathDirty();
|
void cornerRadiusChanged(double from, double to) => markPathDirty();
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,19 @@ export 'package:rive/src/generated/shapes/triangle_base.dart';
|
|||||||
|
|
||||||
class Triangle extends TriangleBase {
|
class Triangle extends TriangleBase {
|
||||||
@override
|
@override
|
||||||
List<PathVertex> get vertices => [
|
List<PathVertex> get vertices {
|
||||||
|
double ox = -originX * width;
|
||||||
|
double oy = -originY * height;
|
||||||
|
return [
|
||||||
StraightVertex()
|
StraightVertex()
|
||||||
..x = 0
|
..x = ox + width / 2
|
||||||
..y = -height / 2,
|
..y = oy,
|
||||||
StraightVertex()
|
StraightVertex()
|
||||||
..x = width / 2
|
..x = ox + width
|
||||||
..y = height / 2,
|
..y = oy + height,
|
||||||
StraightVertex()
|
StraightVertex()
|
||||||
..x = -width / 2
|
..x = ox
|
||||||
..y = height / 2
|
..y = oy + height
|
||||||
];
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
var _utf8Decoder = const Utf8Decoder();
|
|
||||||
|
|
||||||
class BinaryReader {
|
class BinaryReader {
|
||||||
|
final _utf8Decoder = const Utf8Decoder();
|
||||||
final ByteData buffer;
|
final ByteData buffer;
|
||||||
final Endian endian;
|
final Endian endian;
|
||||||
|
|
||||||
@ -106,7 +105,7 @@ class BinaryReader {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8List read(int length, [bool allocNew = false]) {
|
Uint8List read(int length, [bool allocNew = true]) {
|
||||||
var view =
|
var view =
|
||||||
Uint8List.view(buffer.buffer, buffer.offsetInBytes + readIndex, length);
|
Uint8List.view(buffer.buffer, buffer.offsetInBytes + readIndex, length);
|
||||||
readIndex += length;
|
readIndex += length;
|
||||||
|
@ -3,10 +3,10 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
var _variableEncodeList = Uint8List(8);
|
|
||||||
var _utf8Encoder = const Utf8Encoder();
|
|
||||||
|
|
||||||
class BinaryWriter {
|
class BinaryWriter {
|
||||||
|
final _variableEncodeList = Uint8List(8);
|
||||||
|
final _utf8Encoder = const Utf8Encoder();
|
||||||
|
|
||||||
/// Stride we allocate buffer in chunks of.
|
/// Stride we allocate buffer in chunks of.
|
||||||
final int _alignment;
|
final int _alignment;
|
||||||
int get alignment => _alignment;
|
int get alignment => _alignment;
|
||||||
|
Reference in New Issue
Block a user