Flutter button with custom shape - (triangle)

You can do it by creating your own custom painter implementation.

Triangle Painter

class TrianglePainter extends CustomPainter {
  final Color strokeColor;
  final PaintingStyle paintingStyle;
  final double strokeWidth;

  TrianglePainter({this.strokeColor = Colors.black, this.strokeWidth = 3, this.paintingStyle = PaintingStyle.stroke});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = strokeColor
      ..strokeWidth = strokeWidth
      ..style = paintingStyle;

    canvas.drawPath(getTrianglePath(size.width, size.height), paint);
  }

  Path getTrianglePath(double x, double y) {
    return Path()
      ..moveTo(0, y)
      ..lineTo(x / 2, 0)
      ..lineTo(x, y)
      ..lineTo(0, y);
  }

  @override
  bool shouldRepaint(TrianglePainter oldDelegate) {
    return oldDelegate.strokeColor != strokeColor ||
        oldDelegate.paintingStyle != paintingStyle ||
        oldDelegate.strokeWidth != strokeWidth;
  }
}

USAGE

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RawMaterialButton(
          onPressed: () {},
          child: CustomPaint(
            painter: TrianglePainter(
              strokeColor: Colors.blue,
              strokeWidth: 10,
              paintingStyle: PaintingStyle.fill,
            ),
            child: Container(
              height: 180,
              width: 200,
            ),
          ),
        ),
      ),
    );
  }
}

Below is the code which you can refer.

class MyButton extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Offset centerPoint = Offset(100, 100);
    double radius = 60;
    double triangleA = 35;   // this the dimension of triangle's side
    double triangleR = triangleA / sqrt(3.0);   // this the distance between the center of triangle/circle to corner of triangle

    // I am drawing here circle, while you can draw your shape as per your convenience.
    canvas.drawCircle(
        centerPoint,
        radius,
        Paint()
          ..color = Colors.grey[700]
          ..style = PaintingStyle.fill);

    Path path = Path();

    double x1Point = centerPoint.dx + triangleR * cos(3 * pi / 2);
    double y1Point = centerPoint.dy + triangleR * sin(3 * pi / 2);
    path.moveTo(x1Point, y1Point);

    double x2Point = centerPoint.dx +
        triangleR * cos((3 * pi / 2) - Angle.fromDegrees(120).radians);
    double y2Point = centerPoint.dy +
        triangleR * sin((3 * pi / 2) - Angle.fromDegrees(120).radians);
    path.lineTo(x2Point, y2Point);

    double x3Point = centerPoint.dx +
        triangleR * cos((3 * pi / 2) + Angle.fromDegrees(120).radians);
    double y3Point = centerPoint.dy +
        triangleR * sin((3 * pi / 2) + Angle.fromDegrees(120).radians);
    path.lineTo(x3Point, y3Point);

    path.close();

    canvas.drawPath(
        path,
        Paint()
          ..color = Colors.deepOrange
          ..style = PaintingStyle.fill);

    canvas.save();
    canvas.restore();
  }
RawMaterialButton(
 child: CustomPaint(
   painter: MyButton(),
   child: GestureDetector(
     onTap: () {
        print('Here, you can handle button click event');
     },
   ),
 ),
 onPressed: () {
 },
)

create CustomClipper

class CustomTriangleClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    path.lineTo(size.width, 0);
    path.lineTo(size.width, size.height);
    path.lineTo(0, 0);
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return false;
  }
}

and then Usage :

ClipPath(
    clipper: CustomTriangleClipper(),
    child: Container(
      width: 50,
      height: 50,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.bottomLeft,
          end: Alignment.topRight,
          colors: [Color(0xffF25D50), Color(0xffF2BB77)],
        ),
      ),
    ),
  );

Tags:

Dart

Flutter