paint method

  1. @override
void paint(
  1. Canvas canvas,
  2. Size size,
  3. WorldToScreen worldToScreen,
  4. ScreenToWorld screenToWorld,
  5. double scale,
)
override

Called by the canvas to paint this item onto the screen.

The canvas and size are provided by the Flutter framework. Use worldToScreen to translate mathematical coordinates into on-screen pixels.

Implementation

@override
void paint(
  Canvas canvas,
  Size size,
  WorldToScreen worldToScreen,
  ScreenToWorld screenToWorld,
  double scale,
) {
  if (equation.trim().isEmpty) return;

  final shadowPaint = Paint()
    ..color = color.withOpacity(0.25)
    ..strokeWidth = lineWidth
    ..style = PaintingStyle.stroke
    ..strokeCap = StrokeCap.round
    ..strokeJoin = StrokeJoin.round
    ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 3.0);

  final basePaint = Paint()
    ..color = color
    ..strokeWidth = lineWidth
    ..style = PaintingStyle.stroke
    ..strokeCap = StrokeCap.round
    ..strokeJoin = StrokeJoin.round;

  try {
    final expressionParser = GrammarParser();
    final mathExpression = expressionParser.parse(equation);
    final contextModel = ContextModel();
    final functionPath = Path();
    bool isFirstPoint = true;

    for (double pixelX = 0; pixelX <= size.width; pixelX += 2) {
      final worldCoordinates = screenToWorld(pixelX, 0);
      contextModel.bindVariable(Variable('x'), Number(worldCoordinates.dx));
      final logicalY = mathExpression.evaluate(
          EvaluationType.REAL, contextModel) as double;
      final screenCoordinates = worldToScreen(worldCoordinates.dx, logicalY);

      if (screenCoordinates.dy.isInfinite ||
          screenCoordinates.dy.isNaN ||
          screenCoordinates.dy < -size.height * 2 ||
          screenCoordinates.dy > size.height * 3) {
        isFirstPoint = true;
        continue;
      }

      if (isFirstPoint) {
        functionPath.moveTo(pixelX, screenCoordinates.dy);
        isFirstPoint = false;
      } else {
        functionPath.lineTo(pixelX, screenCoordinates.dy);
      }
    }

    canvas.drawPath(functionPath.shift(const Offset(0, 2)), shadowPaint);
    canvas.drawPath(functionPath, basePaint);
  } catch (_) {}
}