getClip method

  1. @override
Path getClip(
  1. Size size
)
override

Returns a description of the clip given that the render object being clipped is of the given size.

Implementation

@override
Path getClip(Size size) {
  // Calculate the base rect of the indicator (same logic as FractionallySizedBox)
  final tabWidth = size.width / itemCount;
  final availableWidth = size.width - tabWidth;

  // Map alignment (-1 to 1) to horizontal offset
  final left = (alignment.x + 1) / 2 * availableWidth;

  // Create the base rect
  // Note: We need to account for the padding applied to AnimatedGlassIndicator
  // AnimatedGlassIndicator has padding: const EdgeInsets.all(4)
  // So the rect should be inset by 4 on all sides, then inflated by expansion * thickness

  final baseRect = Rect.fromLTWH(left, 0, tabWidth, size.height);
  final paddedRect = Rect.fromLTRB(
    baseRect.left + 4.0, // Left padding
    baseRect.top + 4.0, // Top padding
    baseRect.right - 4.0, // Right padding
    baseRect.bottom - 4.0, // Bottom padding
  );

  // Apply expansion based on thickness (drag state)
  final inflatedRect = Rect.fromLTRB(
    paddedRect.left - (expansion.left * thickness),
    paddedRect.top - (expansion.top * thickness),
    paddedRect.right + (expansion.right * thickness),
    paddedRect.bottom + (expansion.bottom * thickness),
  );

  // Clamp radius to avoid invalid RRect paths on Impeller.
  // We subtract 0.1 to prevent the radius from being EXACTLY half the shortest side,
  // which triggers an empty path bug in some Impeller versions during animation.
  final maxRadius = (inflatedRect.shortestSide / 2) - 0.1;
  final safeRadius = borderRadius > maxRadius ? maxRadius : borderRadius;

  // Create rounded rect path
  final path = Path()
    ..addRRect(RRect.fromRectAndRadius(
      inflatedRect,
      Radius.circular(safeRadius > 0 ? safeRadius : 0),
    ));

  // Apply jelly physics transform around the center
  final center = inflatedRect.center;
  final centeredTransform = Matrix4.identity()
    ..translate(center.dx, center.dy)
    ..multiply(transform)
    ..translate(-center.dx, -center.dy);

  final indicatorPath = path.transform(centeredTransform.storage);

  if (inverse) {
    return Path()
      ..fillType = PathFillType.evenOdd
      ..addRect(Rect.fromLTWH(0, 0, size.width, size.height))
      ..addPath(indicatorPath, Offset.zero);
  }

  return indicatorPath;
}