Skip to content

Commit b4d1cc7

Browse files
committed
fix(ui): Implement Deck of Cards drawing order (largest circles on top) for better animation aesthetics
1 parent f82c8b6 commit b4d1cc7

1 file changed

Lines changed: 11 additions & 8 deletions

File tree

lib/flutter_circle_pack_chart_painter.dart

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,16 @@ class FlutterCirclePackChartPainter extends CustomPainter {
4848
final Color color = node.node.color ?? parentColor;
4949

5050
if (node.node == focusedNode) {
51-
// Current focus level
52-
for (final child in node.children) {
51+
// Current focus level: Sort children by radius ascending to ensure
52+
// larger ones are drawn LAST (on top).
53+
final sortedChildren = List<PackedNode>.from(node.children)
54+
..sort((a, b) => a.r.compareTo(b.r));
55+
56+
for (final child in sortedChildren) {
5357
if (isDrillingIn) {
5458
// Drill In: children explode from parent center
5559
final double x = node.x + (child.x - node.x) * animationValue;
5660
final double y = node.y + (child.y - node.y) * animationValue;
57-
// Use parent radius (node.r) as start for interpolation
5861
final double r = lerpDouble(node.r, child.r, animationValue)!;
5962
_drawLeaf(canvas, x, y, r, child.node, color, opacity: 1.0);
6063
} else {
@@ -80,10 +83,11 @@ class FlutterCirclePackChartPainter extends CustomPainter {
8083
void _drawImplodingNode(Canvas canvas, PackedNode node, Color parentColor) {
8184
final Color color = node.node.color ?? parentColor;
8285

83-
// Exact inverse of the explosion:
84-
// Children move from their packed positions back to the parent's center
85-
// and grow to match the parent's radius.
86-
for (final child in node.children) {
86+
// Sort children by radius ascending to ensure larger ones stay on top during implosion.
87+
final sortedChildren = List<PackedNode>.from(node.children)
88+
..sort((a, b) => a.r.compareTo(b.r));
89+
90+
for (final child in sortedChildren) {
8791
final double x = child.x + (node.x - child.x) * animationValue;
8892
final double y = child.y + (node.y - child.y) * animationValue;
8993
final double r = lerpDouble(child.r, node.r, animationValue)!;
@@ -132,7 +136,6 @@ class FlutterCirclePackChartPainter extends CustomPainter {
132136
double radius,
133137
double opacity,
134138
) {
135-
// Use "Anti-Scaling": divide baseFontSize by cameraScale to keep it constant on screen.
136139
final double targetScreenSize = 12.0;
137140
final double fontSize = (targetScreenSize / cameraScale).clamp(0.1, 100.0);
138141

0 commit comments

Comments
 (0)