【flutter】角が丸くくり抜かれたボックス( Inverted corner / reversed corner radius)を作る方法

ボックスというかボーダーというか、角が円でくり抜かれた図形を作る方法、メモ。

コピペで無理くり作ったので動くかどうか不明。使用の際は注意。

作り方

コード

完成図はこんな感じ。

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


class ComTemplateInvertedBorder extends StatelessWidget {
  final Color bg; //bg color
  final Color bordercolor; //border color
  final Widget child;

  ComTemplateInvertedBorder({
    this.bg = Colors.red,
    this.bordercolor= Colors.black,
    required this.child,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      child: ClipPath(
        clipper: const CustomCornerClipPath(),
        child: Container(
          padding: EdgeInsets.all(5),
          color: bordercolor,
          child: ClipPath(
            clipper: const CustomCornerClipPath(),
            child: Container(
              color: bg,
              child: Column(
                children: [
                  Text("Inverted Corner"),
                  Text("Inverted Corner"),
                  Text("Inverted Corner"),
                  Text("Inverted Corner"),
                  Text("Inverted Corner"),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class CustomCornerClipPath extends CustomClipper<Path> {
  final double cornerR;

  const CustomCornerClipPath({this.cornerR = 24.0});

  // const CustomCornerClipPath({this.cornerR = 16.0});

  @override
  Path getClip(Size size) => Path()
    //右上から始めることにする()
    ..lineTo(size.width, cornerR)
    ..lineTo(
      size.width,
      size.height - cornerR,
    )
    //右下の円
    ..arcToPoint(
      Offset(
        size.width - cornerR,
        size.height,
      ),
      radius: Radius.circular(cornerR),
      clockwise: false,
    )
    ..lineTo(cornerR, size.height)
    //左下の円
    ..arcToPoint(
      Offset(
        0,
        size.height - cornerR,
      ),
      radius: Radius.circular(cornerR),
      clockwise: false,
    )
    ..lineTo(0, cornerR)
    //左上
    ..arcToPoint(
      Offset(
        cornerR,
        0,
      ),
      radius: Radius.circular(cornerR),
      clockwise: false,
    )
    ..lineTo(size.width - cornerR, 0)
    ..arcToPoint(
      Offset(
        size.width,
        cornerR,
      ),
      radius: Radius.circular(cornerR),
      clockwise: false,
    );


  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

解説

①ある 親Conteiner をclippathでこの形にくり抜く。

②その子Containerを同じclipperを使い、同じ形で切り抜く(本当はちゃんとclipperを調整した方がきれいな形になるはず)。

③親コンテナにpaddingと背景色を設定する。そのpadding分がボーダーの太さ背景色がボーダーの色を構成する。

参考サイト
https://flutterhq.com/questions-and-answers/1450/it-is-possible-to-reverse-the-container-borderradius-in-flutter

How to make a container with inverted rounded corners in Flutter?
This is the way to make a container with rounded corners: Container(decoration: BoxDecoration(borderRadius: BorderRadius.circular(10),), But is there a way to...

コメント

タイトルとURLをコピーしました