paint method

void paint({
  1. required RenderBox parentBox,
  2. required Canvas canvas,
  3. required Offset center,
  4. required double scale,
  5. required TextPainter labelPainter,
  6. required double textScaleFactor,
  7. required Size sizeWithOverflow,
  8. IndicatorStyle? style,
})

Implementation

void paint({
  required RenderBox parentBox,
  required Canvas canvas,
  required Offset center,
  required double scale,
  required TextPainter labelPainter,
  required double textScaleFactor,
  required Size sizeWithOverflow,
  IndicatorStyle? style,
}) {
  if (scale == 0.0) {
    return;
  }
  assert(!sizeWithOverflow.isEmpty);

  bool reverse = style?.reverse ?? false;

  final double rectangleWidth =
      _upperRectangleWidth(labelPainter, scale, textScaleFactor);
  final double horizontalShift = (reverse ? -1 : 1) *
      getHorizontalShift(
        parentBox: parentBox,
        center: center,
        labelPainter: labelPainter,
        textScaleFactor: textScaleFactor,
        sizeWithOverflow: sizeWithOverflow,
        scale: scale,
      );
  // 三角箭头高度
  final _triangleHeight = indicator.triangleHeight;
  // 计算rect区域高度(label文本高度 + label上下padding)
  final double rectHeight = labelPainter.height + indicator.labelPadding;
  // 定义 rect区域坐标
  final Rect upperRect = Rect.fromLTWH(
    -rectangleWidth / 2 + horizontalShift,
    -_triangleHeight - rectHeight,
    rectangleWidth,
    rectHeight,
  );

  final Path trianglePath = Path()
    ..lineTo(-_triangleHeight, -_triangleHeight)
    ..lineTo(_triangleHeight, -_triangleHeight)
    ..close();
  final Paint fillPaint = Paint()
    ..color = style?.backgroundColor ?? Colors.white;
  final RRect upperRRect = RRect.fromRectAndRadius(
      upperRect, Radius.circular(indicator.rectRadius));
  trianglePath.addRRect(upperRRect);

  double radians = style?.angle ?? 0;

  canvas.save();
  // 旋转indicator
  canvas.translate(center.dx, center.dy);
  canvas.rotate(radians);
  canvas.translate(-center.dx, -center.dy);

  // 根据thumb位置来平移
  // offsetY表示三角箭头和slider的距离
  canvas.translate(center.dx, center.dy - indicator.offsetY);
  canvas.scale(scale, scale);

  // 阴影绘制
  Color? shadowColor = style?.shadowColor;
  if (shadowColor != null) {
    double elevation = style?.elevation ?? _elevation;
    canvas.drawShadow(trianglePath, shadowColor, elevation, true);
  }

  Color? strokeColor = style?.strokeColor;
  if (strokeColor != null) {
    final Paint strokePaint = Paint()
      ..color = strokeColor
      ..strokeWidth = 1.0
      ..style = PaintingStyle.stroke;
    canvas.drawPath(trianglePath, strokePaint);
  }
  canvas.drawPath(trianglePath, fillPaint);

  // The label text is centered within the value indicator.
  // 整个提示框高度
  final double bottomTipToUpperRectTranslateY =
      -indicator.triangleHeight - upperRect.height;
  canvas.translate(0, bottomTipToUpperRectTranslateY);
  final Offset targetOffset = Offset(horizontalShift, upperRect.height / 2);
  final Offset currentOffset =
      Offset(labelPainter.width / 2, labelPainter.height / 2);
  final Offset labelOffset = targetOffset - currentOffset;

  // 旋转内容
  if (reverse) {
    canvas.translate(targetOffset.dx, targetOffset.dy);
    canvas.rotate(math.pi);
    canvas.translate(-targetOffset.dx, -targetOffset.dy);
  }

  labelPainter.paint(canvas, labelOffset);

  canvas.restore();
}