Flutter, PaintingStyle.fill not working as expected

Issue

import 'package:flutter/material.dart';
import 'dart:math' as math;

class PaintHalfHexagon extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.fill;

    Path path = Path();

    path.moveTo(size.width * 0.1, size.height * 0.34);
    path.quadraticBezierTo(size.width * 0.1, size.height * 0.26,
        size.width * 0.3, size.height * 0.28);
    path.moveTo(size.width * 0.5, size.height * 0.34);
    path.quadraticBezierTo(size.width * 0.5, size.height * 0.26,
        size.width * 0.3, size.height * 0.28);
    path.moveTo(size.width * 0.1, size.height * 0.34);
    path.lineTo(size.width * 0.5, size.height * 0.34);

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // return oldDelegate._lineOnefraction != _lineOnefraction;
    return false;
  }
}

enter image description here

enter image description here

When I stroked it, the shape came out perfectly, and when I filled it to fill the color, it came out in a very strange shape.

PaintingStyle.fill
PaintingStyle.stroke

What`s the problem and how to solve this?

Solution

I assume you want to draw an object with the shape of the ‘stroke’ version, but filled like the ‘fill’ version. The problem is that calling moveTo breaks your current path and starts a new one at the coordinates you specify. Even if you draw your separate paths back together so that they look like they touch, as far as the engine is concerned they are not contiguous. Therefore, when you use PaintingStyle.fill it has no idea that it should fill that space in. The result in your example is that it closed the path of each bezier separately, and filled each bezier separately.

You can refactor to remove the moveTo calls, e.g.:

path.moveTo(size.width * 0.1, size.height * 0.34);
path.quadraticBezierTo(size.width * 0.1, size.height * 0.26,
    size.width * 0.3, size.height * 0.28);
path.quadraticBezierTo(size.width * 0.5, size.height * 0.26,
    size.width * 0.5, size.height * 0.34);
path.lineTo(size.width * 0.5, size.height * 0.34);

Answered By – PatrickMahomes

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *