1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Flutter】ShapeBorder継承でカスタマイズデザイン(応用編)

Posted at

※本記事は下記のZenn本にまとめました。

目標

下記のような映画チケットを描くことです。

カスタマイズ描画基本はCustomPaintの継承して描画しますが、今回はShapeBorderを継承してdecorationのshapeで装飾したいと思います。

ShapeBorder継承

5つの抽象メソッドがあります。

import 'package:flutter/material.dart';

class TicketBorder extends ShapeBorder{
  @override
  // TODO: implement dimensions
  EdgeInsetsGeometry get dimensions => throw UnimplementedError();

  @override
  Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
    // TODO: implement getInnerPath
    throw UnimplementedError();
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    // TODO: implement getOuterPath
    throw UnimplementedError();
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
    // TODO: implement paint
  }

  @override
  ShapeBorder scale(double t) {
    // TODO: implement scale
    throw UnimplementedError();
  }
  
}

枠線を描く

pain関数のパラメーターにcanvasとrect持っているため、装飾対象のcanvas操作やrect情報を取得できます。それを利用してチケットの白い枠線を作りたいと思います。

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
    var paint = Paint()
      ..color = Colors.white
      ..strokeWidth = 2.0
      ..style = PaintingStyle.stroke;
    var w = rect.width;
    var h = rect.height;
    canvas.drawRect(Rect.fromPoints(const Offset(40, 25), Offset(w - 40, h - 25)), paint);
  }

borderの枠を設けないと、エラーになるから、矩形を作っておきます。

 @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    Path path = Path();
    // 矩形枠
    path.addRect(rect);
    return path;
  }

穴を切り取る

    // 左上
    path.lineTo(40, 0);
    path.arcToPoint(
      const Offset(0, 40),
      radius: const Radius.circular(40),
    );
    path.fillType = PathFillType.evenOdd;

ギザギザを作る

    double radius = 4;
    int holeCount = (h - 80) ~/ (radius * 2);
    for (int i = 0; i < holeCount; i++) {
      if (i % 2 == 0) {
        path.addArc(
          Rect.fromCircle(center: Offset(0, 44 + i * radius * 2), radius: radius),
          pi / 2,
          pi,
        );
      } else {
        path.addArc(
          Rect.fromCircle(center: Offset(0, 44 + i * radius * 2), radius: radius),
          -pi / 2,
          pi,
        );
      }
    }

雑ですが、これでチケットの模様を作りました。
ソースは下記のGithubをご参考ください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?