Magnus
Magnus

Reputation: 18790

How can I draw a pattern inside a path on a canvas in Flutter?

I want to draw crossing diagonal lines inside a path on a canvas in Flutter.

Right now I've sort of got it working by loading an image asset into a ui.Image and then using a CustomPainter with an ImageShader to draw it on the canvas. It works, but it requires that I create an image asset for each pair of line colors (it's not only red/black).

Future<ui.Image> _loadAssetImage(int number) {
  Completer<ui.Image> completer = new Completer<ui.Image>();

  AssetImage('assets/pngs/pattern_$number.png')
    .resolve(new ImageConfiguration())
    .addListener(ImageStreamListener((ImageInfo image, bool synchronousCall){
      ui.Image img;
      img = image.image;
      completer.complete(img);
    })
  );

  return completer.future;
}

ui.Image myImage = await _loadAssetImage(1); 

and then

          canvas.drawPath(path, Paint()
            ..shader = ImageShader(myImage, TileMode.repeated, TileMode.repeated, Matrix4.identity().scaled(0.2).storage)
            ..style = PaintingStyle.fill
          );

          canvas.drawPath(path, Paint()
            ..style = PaintingStyle.stroke
            ..strokeJoin= StrokeJoin.round
            ..strokeCap= StrokeCap.round
            ..color = Colors.black
            ..strokeWidth = 1
          );

However, I'm interested to know if there is a more efficient way to do this than loading and drawing asset images. It should be easy - after all it's really just repeating lines - but I can't figure out how to draw them and clip them to the path.

Any suggestions?

enter image description here

Upvotes: 2

Views: 3616

Answers (1)

Just clipping path and draw lines in path bounds:

        var b = path.getBounds();

        FCanvas.save();
        FCanvas.clipPath(path);

        for (int i = step; i < b.width; i = i + step)
          FCanvas.drawLine(Offset(b.left + i, b.top), Offset(b.left + i, b.bottom), getPenPaint());

        for (int i = step; i < b.height; i = i + step)
          FCanvas.drawLine(Offset(b.left, b.top + i), Offset(b.right, b.top + i), getPenPaint());


        FCanvas.restore();

Upvotes: 0

Related Questions