iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🔺

Fun with Drawing Shapes using Flutter's CustomPaint

に公開

Introduction

When building apps with Flutter, you may sometimes want to create custom drawings.
In such cases, you can use CustomPaint to draw shapes freely.

CustomPaint can be used easily by following these steps:

  1. Add CustomPaint to the widget tree
  2. Provide size and painter to CustomPaint
  3. Implement the painter (created by extending CustomPainter)
  4. Implement paint() and shouldRepaint() in the CustomPainter

In paint(), you can draw freely on the canvas using functions like the following:

  • drawLine() to draw a line
  • drawRect() to draw a rectangle
  • drawCircle() to draw a circle
  • drawArc() to draw an arch
  • drawPath() to draw a path
  • drawImage() to draw a bitmap image
  • drawParagraph() to draw text

Here, let's actually try drawing some shapes using CustomPaint.

Circle

You can draw a simple circle with the following code.

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

class PaintTestPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CustomPaint(
          size: const Size(100, 100),
          painter: CirclePaint(),
        ),
      ),
    );
  }
}
class CirclePaint extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    print('Size(${size.width},${size.height})');// Size(100,100)
    final paint = Paint()..color = Colors.red;
    final center = Offset(size.width / 2, size.height / 2);
    final radius = min(size.width, size.height);
    canvas.drawCircle(center, radius, paint);
  }

  // No need to repaint
  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}


By specifying PaintingStyle.stroke in the style of paint(), you can draw a line instead of a fill, as shown below.

...
final paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 12;
...

Triangle

Next, let's draw an equilateral triangle.
By using drawPath(), you can draw on a given path as follows:

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

class PaintTestPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CustomPaint(
          size: const Size(100, 100),
          painter: TriPaint(),
        ),
      ),
    );
  }
}

class TriPaint extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final path = Path()
      ..moveTo(
        0,
        size.height,
      )
      ..lineTo(
        size.width / 2,
        size.height - size.width / 2 * sqrt(3),
      )
      ..lineTo(
        size.width,
        size.height,
      )
      ..lineTo(
        0,
        size.height,
      );

    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

References

CustomPaint class - widgets library - Dart API
Paths in Flutter: A Visual Guide. Flutter gives us a lot of standard… | by Muhammed Salih Guler | Flutter Community | Medium
How to Paint in Flutter. A simple guide for learning to use the… | by Suragch | Medium

Discussion