Skip to content

Instantly share code, notes, and snippets.

@jbxbergdev
Last active December 7, 2023 11:09
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jbxbergdev/5238bb78b03a2a4e6f24e55f442d2b70 to your computer and use it in GitHub Desktop.
Save jbxbergdev/5238bb78b03a2a4e6f24e55f442d2b70 to your computer and use it in GitHub Desktop.
Creates a BitmapDescriptor from an IconData object to be used for google_maps_flutter map markers. Read the Medium article here: https://medium.com/@JBXBergDev/how-to-use-googlemap-markers-with-flutter-material-icons-38c4c975e928
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class MarkerGenerator {
final _markerSize;
double _circleStrokeWidth;
double _circleOffset;
double _outlineCircleWidth;
double _fillCircleWidth;
double _iconSize;
double _iconOffset;
MarkerGenerator(this._markerSize) {
// calculate marker dimensions
_circleStrokeWidth = _markerSize / 10.0;
_circleOffset = _markerSize / 2;
_outlineCircleWidth = _circleOffset - (_circleStrokeWidth / 2);
_fillCircleWidth = _markerSize / 2;
final outlineCircleInnerWidth = _markerSize - (2 * _circleStrokeWidth);
_iconSize = sqrt(pow(outlineCircleInnerWidth, 2) / 2);
final rectDiagonal = sqrt(2 * pow(_markerSize, 2));
final circleDistanceToCorners = (rectDiagonal - outlineCircleInnerWidth) / 2;
_iconOffset = sqrt(pow(circleDistanceToCorners, 2) / 2);
}
/// Creates a BitmapDescriptor from an IconData
Future<BitmapDescriptor> createBitmapDescriptorFromIconData(IconData iconData, Color iconColor, Color circleColor, Color backgroundColor) async {
final pictureRecorder = PictureRecorder();
final canvas = Canvas(pictureRecorder);
_paintCircleFill(canvas, backgroundColor);
_paintCircleStroke(canvas, circleColor);
_paintIcon(canvas, iconColor, iconData);
final picture = pictureRecorder.endRecording();
final image = await picture.toImage(_markerSize.round(), _markerSize.round());
final bytes = await image.toByteData(format: ImageByteFormat.png);
return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
}
/// Paints the icon background
void _paintCircleFill(Canvas canvas, Color color) {
final paint = Paint()
..style = PaintingStyle.fill
..color = color;
canvas.drawCircle(Offset(_circleOffset, _circleOffset), _fillCircleWidth, paint);
}
/// Paints a circle around the icon
void _paintCircleStroke(Canvas canvas, Color color) {
final paint = Paint()
..style = PaintingStyle.stroke
..color = color
..strokeWidth = _circleStrokeWidth;
canvas.drawCircle(Offset(_circleOffset, _circleOffset), _outlineCircleWidth, paint);
}
/// Paints the icon
void _paintIcon(Canvas canvas, Color color, IconData iconData) {
final textPainter = TextPainter(textDirection: TextDirection.ltr);
textPainter.text = TextSpan(
text: String.fromCharCode(iconData.codePoint),
style: TextStyle(
letterSpacing: 0.0,
fontSize: _iconSize,
fontFamily: iconData.fontFamily,
color: color,
)
);
textPainter.layout();
textPainter.paint(canvas, Offset(_iconOffset, _iconOffset));
}
}
@krisztianodor
Copy link

You are the best! 😃

@krisztianodor
Copy link

It's sad but we can't comment on specific gist lines...

You should also include the 'package' parameter to support other icon packages too - eg fontawesome icons.

So the _paintIcon method would look like this:

void _paintIcon(Canvas canvas, Color color, IconData iconData) {
    final textPainter = TextPainter(textDirection: TextDirection.ltr);
    textPainter.text = TextSpan(
        text: String.fromCharCode(iconData.codePoint),
        style: TextStyle(
          letterSpacing: 0.0,
          fontSize: _iconSize,
          fontFamily: iconData.fontFamily,
          package: iconData.fontPackage,
          color: color,
        ));
    textPainter.layout();
    textPainter.paint(canvas, Offset(_iconOffset, _iconOffset));
  }

@Sammius
Copy link

Sammius commented Oct 2, 2020

Cool!
Is it possible to print into the Canvas not only an Icon or Text but any arbitrary Widget?

@dm8tr
Copy link

dm8tr commented Nov 22, 2020

It's sad but we can't comment on specific gist lines...

You should also include the 'package' parameter to support other icon packages too - eg fontawesome icons.

So the _paintIcon method would look like this:

void _paintIcon(Canvas canvas, Color color, IconData iconData) {
    final textPainter = TextPainter(textDirection: TextDirection.ltr);
    textPainter.text = TextSpan(
        text: String.fromCharCode(iconData.codePoint),
        style: TextStyle(
          letterSpacing: 0.0,
          fontSize: _iconSize,
          fontFamily: iconData.fontFamily,
          package: iconData.fontPackage,
          color: color,
        ));
    textPainter.layout();
    textPainter.paint(canvas, Offset(_iconOffset, _iconOffset));
  }

You a hero 🙏🙏

@erdvillegas
Copy link

Can we do a plugin for this?, most of us we have found usefull 🥇

@Prodevking1
Copy link

thanks a lot bro !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment