drawToAnnotationCanvas method

void drawToAnnotationCanvas({
  1. required String type,
  2. required double x1,
  3. required double y1,
  4. required double x2,
  5. required double y2,
  6. required String color,
  7. required double thickness,
  8. List<Map<String, dynamic>>? freehandPoints,
})

Draw a shape to the annotation canvas.

This provides a way for Flutter's Screenboard to mirror its drawings to the HTML canvas that will be captured.

Implementation

void drawToAnnotationCanvas({
  required String type,
  required double x1,
  required double y1,
  required double x2,
  required double y2,
  required String color,
  required double thickness,
  List<Map<String, dynamic>>? freehandPoints,
}) {
  final ctx = _annotationCanvas?.context2D;
  if (ctx == null) return;

  ctx.strokeStyle = color.toJS;
  ctx.lineWidth = thickness;
  ctx.lineCap = 'round';
  ctx.lineJoin = 'round';

  switch (type) {
    case 'line':
      ctx.beginPath();
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y2);
      ctx.stroke();
      break;

    case 'freehand':
      if (freehandPoints != null && freehandPoints.isNotEmpty) {
        ctx.beginPath();
        final first = freehandPoints.first;
        ctx.moveTo(
          (first['x'] as num).toDouble(),
          (first['y'] as num).toDouble(),
        );
        for (final point in freehandPoints.skip(1)) {
          ctx.lineTo(
            (point['x'] as num).toDouble(),
            (point['y'] as num).toDouble(),
          );
        }
        ctx.stroke();
      }
      break;

    case 'rectangle':
      ctx.beginPath();
      ctx.rect(x1, y1, x2 - x1, y2 - y1);
      ctx.stroke();
      break;

    case 'circle':
      final centerX = (x1 + x2) / 2;
      final centerY = (y1 + y2) / 2;
      final radius = ((x2 - x1).abs() + (y2 - y1).abs()) / 4;
      ctx.beginPath();
      ctx.arc(centerX, centerY, radius, 0, 2 * 3.14159265359, false);
      ctx.stroke();
      break;

    case 'oval':
      final centerX = (x1 + x2) / 2;
      final centerY = (y1 + y2) / 2;
      final radiusX = (x2 - x1).abs() / 2;
      final radiusY = (y2 - y1).abs() / 2;
      ctx.beginPath();
      ctx.ellipse(
          centerX, centerY, radiusX, radiusY, 0, 0, 2 * 3.14159265359, false);
      ctx.stroke();
      break;

    case 'triangle':
      final midX = (x1 + x2) / 2;
      ctx.beginPath();
      ctx.moveTo(midX, y1);
      ctx.lineTo(x2, y2);
      ctx.lineTo(x1, y2);
      ctx.closePath();
      ctx.stroke();
      break;

    case 'square':
      final size = (x2 - x1).abs();
      ctx.beginPath();
      ctx.rect(x1, y1, size, size);
      ctx.stroke();
      break;

    case 'rhombus':
      final centerX = (x1 + x2) / 2;
      final centerY = (y1 + y2) / 2;
      ctx.beginPath();
      ctx.moveTo(centerX, y1);
      ctx.lineTo(x2, centerY);
      ctx.lineTo(centerX, y2);
      ctx.lineTo(x1, centerY);
      ctx.closePath();
      ctx.stroke();
      break;

    case 'parallelogram':
      final centerX = (x1 + x2) / 2;
      ctx.beginPath();
      ctx.moveTo(centerX, y1);
      ctx.lineTo(x2, y2);
      ctx.lineTo(centerX, y2);
      ctx.lineTo(x1, y1);
      ctx.closePath();
      ctx.stroke();
      break;

    case 'pentagon':
      _drawPolygon(ctx, 5, x1, y1, x2, y2);
      break;

    case 'hexagon':
      _drawPolygon(ctx, 6, x1, y1, x2, y2);
      break;

    case 'octagon':
      _drawPolygon(ctx, 8, x1, y1, x2, y2);
      break;

    default:
      // For any other shape type, don't draw anything
      break;
  }
}