paintBackground method

void paintBackground(
  1. Offset offset,
  2. PaintingContext context
)

Implementation

void paintBackground(Offset offset, PaintingContext context) {
  var rect = offset & size;
  final width = size.width;
  final height = size.height;
  pointerWidth = width < pointerWidth ? width : pointerWidth;
  pointerHeight = height < pointerHeight ? height : pointerHeight;
  if (pointerWidth < peakRadius) {
    peakRadius = pointerWidth;
  }
  final arc = math.atan(pointerHeight / pointerWidth * 2);
  final double halfArcWidth = math.sin(arc) * peakRadius;
  final double l = peakRadius / math.cos(arc);
  var pointerStartX = width * pointerBias - pointerWidth / 2;
  var pointerEndX = width * pointerBias + pointerWidth / 2;
  var minRadius = math.min(width - pointerWidth, height - pointerHeight) / 2;
  if (borderRadius > minRadius) {
    borderRadius = minRadius;
  }
  Radius radius = Radius.circular(borderRadius);
  startPadding = startPadding > borderRadius ? startPadding : borderRadius;
  endPadding = endPadding > borderRadius ? endPadding : borderRadius;
  if (pointerStartX < startPadding) {
    pointerStartX = startPadding;
    pointerEndX = startPadding + pointerWidth;
  } else if (pointerEndX > width - endPadding) {
    pointerStartX = width - endPadding - pointerWidth;
    pointerEndX = width - endPadding;
  }
  var arcY = math.tan(arc) * halfArcWidth;
  arcY = pointerHeight < arcY ? pointerHeight : arcY;
  Path path = Path();
  if (isUpward) {
    path.moveTo(pointerStartX, pointerHeight);
    path.lineTo(pointerStartX + pointerWidth / 2 - halfArcWidth, arcY);
    // path.relativeConicTo(halfArcWidth, -arcY, halfArcWidth * 2, 0, 1);
    path.arcTo(
        Rect.fromCircle(
            center: Offset(pointerStartX + pointerWidth / 2, l),
            radius: peakRadius),
        -math.pi / 2 - arc,
        arc * 2,
        false);
    path.lineTo(pointerEndX, pointerHeight);
    path.lineTo(width - borderRadius, pointerHeight);
    path.arcToPoint(Offset(width, pointerHeight + borderRadius),
        radius: radius);
    path.lineTo(width, height - borderRadius);
    path.arcToPoint(Offset(width - borderRadius, height), radius: radius);
    path.lineTo(borderRadius, height);
    path.arcToPoint(Offset(0, height - borderRadius), radius: radius);
    path.lineTo(0, pointerHeight + borderRadius);
    path.arcToPoint(Offset(borderRadius, pointerHeight), radius: radius);
    path.close();
  } else {
    final bottom = height - pointerHeight;
    path.moveTo(pointerStartX, 0);
    path.lineTo(width - borderRadius, 0);
    path.arcToPoint(Offset(width, borderRadius), radius: radius);
    path.lineTo(width, bottom - borderRadius);
    path.arcToPoint(Offset(width - borderRadius, bottom), radius: radius);
    path.lineTo(pointerEndX, bottom);
    path.lineTo(pointerEndX - pointerWidth / 2 + halfArcWidth, height - arcY);
    path.arcTo(
        Rect.fromCircle(
            center: Offset(pointerEndX - pointerWidth / 2, height - l),
            radius: peakRadius),
        math.pi / 2 - arc,
        arc * 2,
        false);
    path.lineTo(pointerStartX, bottom);
    path.lineTo(borderRadius, bottom);
    path.arcToPoint(Offset(0, bottom - borderRadius), radius: radius);
    path.lineTo(0, borderRadius);
    path.arcToPoint(Offset(borderRadius, 0), radius: radius);
    path.close();
  }
  path = path.shift(offset);
  final innerPath = Path();
  innerPath.addPath(path, Offset.zero);
  var inflateRect = rect.inflate(strokeWidth / 2);
  if (filter != null) {
    context.pushClipPath(
      needsCompositing,
      const Offset(0, 0),
      inflateRect,
      path,
      (PaintingContext innerContext, Offset innerOffset) {
        innerContext.pushLayer(
            BackdropFilterLayer(
              filter: filter,
              blendMode: blendMode,
            ),
            (PaintingContext innerContext, Offset innerOffset) {},
            innerOffset);
      },
    );
  }
  Canvas canvas = context.canvas;
  canvas.saveLayer(inflateRect, painter);
  canvas.drawPath(innerPath, backgroundPainter);
  canvas.drawPath(path, paintBorderPainter);
  canvas.restore();
}