Flutter how to draw semicircle (half circle)
Asked Answered
R

7

30

How can I draw semicircle like this?

enter image description here

Code:

class DrawHalfCircleClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final Path path = new Path();
    ...
    return path;
  }
  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return true;
  }
Ridgeling answered 1/9, 2019 at 18:21 Comment(0)
C
39

Create a StatelessWidget say MyArc which accepts a diameter.

import 'dart:math' as math;

class MyArc extends StatelessWidget {
  final double diameter;

  const MyArc({super.key, this.diameter = 200});

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: MyPainter(),
      size: Size(diameter, diameter),
    );
  }
}


// This is the Painter class
class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()..color = Colors.blue;
    canvas.drawArc(
      Rect.fromCenter(
        center: Offset(size.height / 2, size.width / 2),
        height: size.height,
        width: size.width,
      ),
      math.pi,
      math.pi,
      false,
      paint,
    );
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

Usage:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(),
    body: MyArc(diameter: 300),
  );
}
Causey answered 1/9, 2019 at 18:25 Comment(4)
how do we add a LinearGradient as a color to the paint class?Woodall
You need to use Shader on the Paint object.Causey
Any idea as to how I can flip this so that the rounded side is downwards ??Ingles
@Ingles In the third parameter of drawArc, use -math.pi.Causey
C
13
Container(
    decoration: const BoxDecoration(
      color: Colors.black,
      borderRadius: BorderRadius.only(
        bottomLeft: Radius.circular(100),
        bottomRight: Radius.circular(100),
      ),

With this code you can make a half circle.

Chokefull answered 15/9, 2021 at 2:28 Comment(4)
you MUST reformat your code before send it hereRidgeling
sorry i am new at thisChokefull
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Flanker
thank you thank youChokefull
F
5

create a class that extends from CustomClipper and use the arcToPoint method to draw the circle and use the ClipPath widget, here is the code to implement that

ClipPath(
      clipper: CustomClip(),
      child: Container(
        width: 200,
        height: 100,
        color: Colors.blue,
      ),
    ),
    class CustomClip extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        double radius = 100;
    
        Path path = Path();
        path
          ..moveTo(size.width / 2, 0)
          ..arcToPoint(Offset(size.width, size.height),
              radius: Radius.circular(radius))
          ..lineTo(0, size.height)
          ..arcToPoint(
            Offset(size.width / 2, 0),
            radius: Radius.circular(radius),
          )
          ..close();
    
        return path;
      }
    
      @override
      bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
        return true;
      }
    }
Franz answered 6/11, 2021 at 23:3 Comment(0)
I
3

with a simple implementation( not the best)

you can draw 2 container both have same width and height inside a row and provide a BoxDectoration for each container => BorderRadius as the following code, this is not the best implementation , it just works

Row(children: [

          Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.only(topRight: Radius.circular(200),),
            color: Colors.blue[300],
            ),
            width: 200,
            height: 200,
            ),
            Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.only(topLeft: Radius.circular(200),),
            color: Colors.blue[300],
            ),
            width: 200,
            height: 200,
            )

], ),

Infidelity answered 23/5, 2021 at 14:48 Comment(1)
make sure that the width = height = circular border radiusInfidelity
N
3

UPDATE: You only need a Container, EASY PEASY:

Container(
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.only(
                                bottomLeft: Radius.circular(100),
                                topLeft: Radius.circular(100)),
                            color: Colors.red,
                            shape: BoxShape.rectangle,
                          ),
                          height: 35,
                          width: 35,
                        ),

Here is a simple code using Stack. You can easily generate a semicircle using a rectangle and a circle. Reshape the containers with BoxDecoration(shape:)

Stack(
   children: [
        Align(
           alignment: Alignment.center,
           child: Container(
                height: 35,
                          width: 35,
                          decoration: BoxDecoration(
                            color: Colors.red,
                            shape: BoxShape.circle,
                          ),
                        ),
                      ),
                      Align(
                        alignment: Alignment.centerLeft,
                        child: Container(
                          decoration: BoxDecoration(
                            color: Colors.red,
                            shape: BoxShape.rectangle,
                          ),
                          height: 35,
                          width: 35,
                        ),
                      ),
                    ],
                  ),
Norvan answered 28/7, 2021 at 4:37 Comment(0)
R
2

Container(
          width: 100,
          height: 50,
          decoration: const BoxDecoration(
            border: Border(
              left: BorderSide(
                color: Colors.green,
                width: 20,
              ),
              right: BorderSide(
                color: Colors.green,
                width: 20,
              ),
              bottom: BorderSide(
                color: Colors.green,
                width: 20,
              ),
            ),
            borderRadius: BorderRadius.only(
              bottomLeft: Radius.circular(200),
              bottomRight: Radius.circular(200),
            ),
          ),
        ),
Residency answered 21/3 at 3:56 Comment(0)
O
0

This will work, you can change the dimensions, but make sure the height is half the borderRadius and the width is equal to the borderRadius.

Container(
height: 50,
         width:100,
    decoration: const BoxDecoration(
      color: Colors.black,
      borderRadius: BorderRadius.only(
        bottomLeft: Radius.circular(100),
        bottomRight: Radius.circular(100),
      ))),
Ous answered 24/8, 2022 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.