generateOuterDynamicPath method
Implementation
DynamicPath generateOuterDynamicPath(Rect rect) {
List<DynamicNode> nodes = [];
double scale = min(rect.width, rect.height) / 2;
double cornerRadius = this.cornerRadius.toPX(constraint: scale / 2);
double insetRadius = this.insetRadius.toPX(constraint: scale / 2);
final int vertices = corners * 2;
final double alpha = (2 * pi) / vertices;
final double centerX = scale;
final double centerY = scale;
double inset = this.inset.toPX(constraint: scale);
inset = inset.clamp(0.0, scale * 0.999);
double sideLength = getThirdSideLength(scale, scale - inset, alpha);
double beta = getThirdAngle(sideLength, scale, scale - inset);
double gamma = alpha + beta;
cornerRadius = cornerRadius.clamp(0, sideLength * tan(beta));
double avalSideLength = max(sideLength - cornerRadius / tan(beta), 0.0);
if (gamma <= pi / 2) {
insetRadius = insetRadius.clamp(0, avalSideLength * tan(gamma));
} else {
insetRadius = insetRadius.clamp(0, avalSideLength * tan(pi - gamma));
}
for (int i = 0; i < vertices; i++) {
double r;
double omega = -pi / 2 + alpha * i;
if (i.isEven) {
r = scale - cornerRadius / sin(beta);
Offset center =
Offset((r * cos(omega)) + centerX, (r * sin(omega)) + centerY);
double sweepAngle = 2 * (pi / 2 - beta);
Offset start = arcToCubicBezier(
Rect.fromCircle(center: center, radius: cornerRadius),
omega - sweepAngle / 2,
sweepAngle)
.first;
Offset end = arcToCubicBezier(
Rect.fromCircle(center: center, radius: cornerRadius),
omega - sweepAngle / 2,
sweepAngle)
.last;
switch (cornerStyle) {
case CornerStyle.rounded:
nodes.addArc(Rect.fromCircle(center: center, radius: cornerRadius),
omega - sweepAngle / 2, sweepAngle,
splitTimes: 1);
break;
case CornerStyle.concave:
nodes.addStyledCorner(
center, cornerRadius, omega - sweepAngle / 2, sweepAngle,
splitTimes: 1, style: CornerStyle.concave);
break;
case CornerStyle.straight:
nodes.add(DynamicNode(position: start));
nodes.add(DynamicNode(position: (start + end) / 2));
nodes.add(DynamicNode(position: end));
break;
case CornerStyle.cutout:
nodes.add(DynamicNode(position: start));
nodes.add(DynamicNode(position: center));
nodes.add(DynamicNode(position: end));
break;
}
} else {
double sweepAngle = pi - 2 * gamma;
if (gamma <= pi / 2) {
r = scale - inset + insetRadius / sin(gamma);
Offset center =
Offset((r * cos(omega)) + centerX, (r * sin(omega)) + centerY);
Offset start = arcToCubicBezier(
Rect.fromCircle(center: center, radius: insetRadius),
omega + sweepAngle / 2 + pi,
-sweepAngle)
.first;
Offset end = arcToCubicBezier(
Rect.fromCircle(center: center, radius: insetRadius),
omega + sweepAngle / 2 + pi,
-sweepAngle)
.last;
switch (insetStyle) {
case CornerStyle.rounded:
nodes.addArc(Rect.fromCircle(center: center, radius: insetRadius),
omega + sweepAngle / 2 + pi, -sweepAngle,
splitTimes: 1);
break;
case CornerStyle.concave:
r = scale - inset;
Offset center = Offset(
(r * cos(omega)) + centerX, (r * sin(omega)) + centerY);
double newSweep = ((pi - sweepAngle)).clampAngleWithin();
double newStart =
((omega + sweepAngle / 2 + pi + sweepAngle / 2) +
newSweep / 2)
.clampAngleWithin();
nodes.addArc(
Rect.fromCircle(
center: center,
radius: insetRadius * tan(sweepAngle / 2)),
newStart,
newSweep,
splitTimes: 1);
break;
case CornerStyle.straight:
nodes.add(DynamicNode(position: start));
nodes.add(DynamicNode(position: (start + end) / 2));
nodes.add(DynamicNode(position: end));
break;
case CornerStyle.cutout:
nodes.add(DynamicNode(position: start));
nodes.add(DynamicNode(position: center));
nodes.add(DynamicNode(position: end));
break;
}
} else {
sweepAngle = -sweepAngle;
r = scale - inset - insetRadius / sin(gamma);
Offset center =
Offset((r * cos(omega)) + centerX, (r * sin(omega)) + centerY);
Offset start = arcToCubicBezier(
Rect.fromCircle(center: center, radius: insetRadius),
omega - sweepAngle / 2,
sweepAngle)
.first;
Offset end = arcToCubicBezier(
Rect.fromCircle(center: center, radius: insetRadius),
omega - sweepAngle / 2,
sweepAngle)
.last;
switch (insetStyle) {
case CornerStyle.rounded:
nodes.addArc(Rect.fromCircle(center: center, radius: insetRadius),
omega - sweepAngle / 2, sweepAngle,
splitTimes: 1);
break;
case CornerStyle.concave:
nodes.addStyledCorner(
center, insetRadius, omega - sweepAngle / 2, sweepAngle,
splitTimes: 1, style: CornerStyle.concave);
break;
case CornerStyle.straight:
nodes.add(DynamicNode(position: start));
nodes.add(DynamicNode(position: (start + end) / 2));
nodes.add(DynamicNode(position: end));
break;
case CornerStyle.cutout:
nodes.add(DynamicNode(position: start));
nodes.add(DynamicNode(position: center));
nodes.add(DynamicNode(position: end));
break;
}
}
}
}
return DynamicPath(size: Size(2 * scale, 2 * scale), nodes: nodes)
..resize(rect.size);
}