💁

FlutterでCanvasを使って図形を作る

2024/06/23に公開

対象者

  • Flutterで図形を作ってみたい
  • Canvasを触ってみたい

これを使うみたい?
https://api.flutter.dev/flutter/rendering/CustomPainter-class.html

プロジェクトの説明

Flutterで、JavaScriptみたいに図形を書けるみたいです。Canvasかな。Jetpack Composeでもあるけどね。図形の作り方がさっぱりわからない😇

とりあえず動くものを作って覚えよう✨

丸の図形を作る

Canvasを使用して丸の図形を作る方法は以下の通りです:

  1. CustomPainterクラスを継承したクラスを作成します。このクラスでは、paintメソッドをオーバーライドして、描画ロジックを実装します。
  2. paintメソッド内で、CanvasオブジェクトのdrawCircleメソッドを使用して丸を描画します。drawCircleメソッドには、中心点の座標、半径、そしてPaintオブジェクトを指定します。
  3. Paintオブジェクトを使用して、丸の色やスタイル(塗りつぶしや枠線など)を設定します。
  4. 最後に、このカスタムペインターをCustomPaintウィジェットのpainterプロパティに設定して、ウィジェットツリーに追加します。
    以下は、中心が(100, 100)で半径が50の青い丸を描画する例です:
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyWidget(),
    );
  }
}

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('CustomPaint Example'),
      ),
      body: CustomPaint(
        painter: CirclePainter(),
      ),
    );
  }
}

class CirclePainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue // 丸の色
      ..style = PaintingStyle.fill; // 塗りつぶし

    // 丸を描画(中心点は(100, 100)、半径は50)
    canvas.drawCircle(Offset(100, 100), 50, paint);
  }

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

[こんな感じやで]

四角の図形を作る

四角の図形をCanvas上に描画するには、CustomPainterクラスを継承したクラス内でCanvasオブジェクトのdrawRectメソッドを使用します。以下の手順で四角形を描画することができます:

  1. CustomPainterクラスを継承したクラスを作成し、paintメソッドをオーバーライドします。
  2. paintメソッド内で、drawRectメソッドを使用して四角形を描画します。このメソッドには、四角形の位置とサイズを指定するRectオブジェクトと、四角形のスタイルを指定するPaintオブジェクトを渡します。
  3. Paintオブジェクトを使用して、四角形の色やスタイル(塗りつぶしや枠線など)を設定します。
  4. 最後に、このカスタムペインターをCustomPaintウィジェットのpainterプロパティに設定して、ウィジェットツリーに追加します。
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyWidget(),
    );
  }
}

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('CustomPaint Example'),
      ),
      body: CustomPaint(
        painter: RectanglePainter(),
      ),
    );
  }
}

class RectanglePainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.red // 四角形の色
      ..style = PaintingStyle.fill; // 塗りつぶし

    // 四角形を描画(左上の座標は(50, 50)、幅は150、高さは150)
    canvas.drawRect(Rect.fromLTWH(50, 50, 150, 150), paint);
  }

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

三角形を作る

三角形をCanvas上に描画するには、CustomPainterクラスを継承したクラス内でCanvasオブジェクトのdrawPathメソッドを使用します。以下の手順で三角形を描画することができます:

  1. CustomPainterクラスを継承したクラスを作成し、paintメソッドをオーバーライドします。
    paintメソッド内で、Pathオブジェクトを作成し、三角形の頂点をmoveToとlineToメソッドを使って定義します。
  2. PathオブジェクトをCanvasのdrawPathメソッドに渡して、三角形を描画します。このとき、三角形のスタイルを指定するPaintオブジェクトも一緒に渡します。
  3. Paintオブジェクトを使用して、三角形の色やスタイル(塗りつぶしや枠線など)を設定します。
  4. 最後に、このカスタムペインターをCustomPaintウィジェットのpainterプロパティに設定して、ウィジェットツリーに追加します。
    以下は、基底がウィジェットの中央に位置し、高さが100の三角形を描画する例です:
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyWidget(),
    );
  }
}

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('CustomPaint Example'),
      ),
      body: CustomPaint(
        size: const Size(200, 200),
        painter: TrianglePainter(),
      ),
    );
  }
}

class TrianglePainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.green // 三角形の色
      ..style = PaintingStyle.fill; // 塗りつぶし

    final path = Path();
    // 三角形の頂点を定義
    path.moveTo(size.width / 2, 0); // 上の頂点
    path.lineTo(0, size.height); // 左下の頂点
    path.lineTo(size.width, size.height); // 右下の頂点
    path.close(); // パスを閉じる

    canvas.drawPath(path, paint);
  }

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

菱形を作る

菱形をCanvas上に描画するには、CustomPainterクラスを継承したクラス内でCanvasオブジェクトのdrawPathメソッドを使用します。以下の手順で菱形を描画することができます:

  1. CustomPainterクラスを継承したクラスを作成し、paintメソッドをオーバーライドします。
  2. paintメソッド内で、Pathオブジェクトを作成し、菱形の頂点をmoveToとlineToメソッドを使って定義します。
  3. PathオブジェクトをCanvasのdrawPathメソッドに渡して、菱形を描画します。このとき、菱形のスタイルを指定するPaintオブジェクトも一緒に渡します。
  4. Paintオブジェクトを使用して、菱形の色やスタイル(塗りつぶしや枠線など)を設定します。
  5. 最後に、このカスタムペインターをCustomPaintウィジェットのpainterプロパティに設定して、ウィジェットツリーに追加します。
    以下は、中心がウィジェットの中央に位置し、縦横の長さが100の菱形を描画する例です:
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyWidget(),
    );
  }
}

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('CustomPaint Example'),
      ),
      body: CustomPaint(
        size: const Size(200, 200),
        painter: DiamondPainter(),
      ),
    );
  }
}

class DiamondPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.purple // 菱形の色
      ..style = PaintingStyle.fill; // 塗りつぶし

    final path = Path();
    // 菱形の頂点を定義
    path.moveTo(size.width / 2, 0); // 上の頂点
    path.lineTo(0, size.height / 2); // 左の頂点
    path.lineTo(size.width / 2, size.height); // 下の頂点
    path.lineTo(size.width, size.height / 2); // 右の頂点
    path.close(); // パスを閉じる

    canvas.drawPath(path, paint);
  }

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

感想

いかがでしたでしょうか。Flutterで図形を作るのをやってみました。コードは多くないけど、数学の知識が必要そうですね💦
AIに頼りましたが、なしでも作れるようになるのが目標ですね。頑張れば普段は、パッケージを使って作っているグラフも自作できるようになるかも知れません。

[こんな感じかな]

Discussion