2

I need to DRAW a custom marker using canvas, so far I DREW a inverse Triangle shape. Do you have any idea to about how to DRAW a marker shape?

class DrawTriangle extends CustomPainter {

      Paint _paint;

      DrawTriangle() {
        _paint = Paint()
          ..color = Colors.green
          ..style = PaintingStyle.fill;
      }

      @override
      void paint(Canvas canvas, Size size) {
        var path = Path();
        path.moveTo(size.width, size.height);
        path.lineTo(size.width + 100, size.height - 100);
        path.lineTo(size.width - 100, size.height - 100);
        path.close();
        canvas.drawPath(path, _paint);
      }

      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return false;
      }
    }
    Future<Uint8List> getBytesFromCanvas(
          int width, int height, Color color) async {
        final PictureRecorder pictureRecorder = PictureRecorder();
        final Canvas canvas = Canvas(pictureRecorder);
        CustomPainter painter = DrawTriangle();
        painter.paint(canvas, Size(100.0,100.0));
        final img = await pictureRecorder.endRecording().toImage(width, height);
        final data = await img.toByteData(format: ImageByteFormat.png);
        return data.buffer.asUint8List();
      }

This above method creates inverse triangle and I need to create a marker shape.. How do I achieve this?

Balaji
  • 1,773
  • 1
  • 17
  • 30

2 Answers2

2

This isn't pixel perfect but it worked for me, (especially if the marker size isn't too big)

import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
      

Future<BitmapDescriptor> getMarkerFromCanvas(
      int customNum, double width, double height, Color color) async {
    final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
    final Canvas canvas = Canvas(pictureRecorder);
    final Paint paint = Paint()..color = color;
    final Radius radius = Radius.circular(width / 2);
    canvas.clipPath(Path()
      ..moveTo(0, height / 2.7)
      ..lineTo(width / 2, height.toDouble())
      ..lineTo(width.toDouble(), height / 2.7)
      ..arcToPoint(
        Offset(width.toDouble(), 0),
      )
      ..arcToPoint(const Offset(0, 0)));
    canvas.drawRRect(
        RRect.fromRectAndCorners(
          Rect.fromLTWH(0.0, 0.0, width.toDouble(), height.toDouble()),
          topLeft: radius,
          topRight: radius,
          bottomLeft: radius,
          bottomRight: radius,
        ),
        paint);

    final img = await pictureRecorder
        .endRecording()
        .toImage(width.toInt(), height.toInt());
    final data = await img.toByteData(format: ui.ImageByteFormat.png);
    return BitmapDescriptor.fromBytes(data!.buffer.asUint8List());
  }

You can call this function asynchronously, then setState and use the stored returned BitmapDescriptor directly in a GoogleMap marker i.e: Marker( icon: _theReturnedValue);

0

Why do you want to use custom painter you can also use images for the same task. I found this article for you. Hope I helped you.

Sirus
  • 141
  • 1
  • 10
  • for some reasons, I have to draw the marker. Can you please tell me how to draw a marker? if you know? Its just semi circle and a inverse triangle, but I don't know how to do.. I am trying – Balaji May 23 '20 at 14:47
  • I think it's an overkill to use CustomPainter for markers, but if you still want to use it you can make use of primitive shapes. Like circles for top part and triangle for buttom part. – Sirus May 23 '20 at 15:02