pathFromCubics function
Returns a Path for a Cubic list.
path is a Path to reset and set with the new path data.
startAngle is an angle (in degrees) to rotate the Path to start
drawing from. If startAngle is non zero, then caller has to use the
returned Path, as path transformation creates a new path.
repeatPath is whether or not to repeat the Path twice before closing
it. This flag is useful when the caller would like to draw parts of the
path while offsetting the start and stop positions (for example, when
phasing and rotating a path to simulate a motion as a Star circular
progress indicator advances).
closePath is whether or not to close the created Path.
cubics is list of Cubics to build path from.
rotationPivotX is the rotation pivot on the X axis.
rotationPivotY is the rotation pivot on the Y axis.
Implementation
Path pathFromCubics({
required Path path,
required int startAngle,
required bool repeatPath,
required bool closePath,
required List<Cubic> cubics,
required double rotationPivotX,
required double rotationPivotY,
}) {
var first = true;
Cubic? firstCubic;
path.reset();
for (final cubic in cubics) {
if (first) {
path.moveTo(cubic.anchor0X, cubic.anchor0Y);
if (startAngle != 0) {
firstCubic = cubic;
}
first = false;
}
path.cubicTo(
cubic.control0X,
cubic.control0Y,
cubic.control1X,
cubic.control1Y,
cubic.anchor1X,
cubic.anchor1Y,
);
}
if (repeatPath) {
var firstInRepeat = true;
for (final cubic in cubics) {
if (firstInRepeat) {
path.lineTo(cubic.anchor0X, cubic.anchor0Y);
firstInRepeat = false;
}
path.cubicTo(
cubic.control0X,
cubic.control0Y,
cubic.control1X,
cubic.control1Y,
cubic.anchor1X,
cubic.anchor1Y,
);
}
}
if (closePath) {
path.close();
}
if (startAngle != 0 && firstCubic != null) {
final angleToFirstCubic = math.atan2(
cubics[0].anchor0Y - rotationPivotY,
cubics[0].anchor0X - rotationPivotX,
);
// Rotate the Path to to start from the given angle.
path = path.transform(
(Matrix4.identity()
..rotateZ(
-angleToFirstCubic + (startAngle * math.pi / 180),
))
.storage,
);
}
return path;
}