skip to Main Content

enter image description here

I’m making a folder-shaped container component in Flutter.

I am using the code below to create a folder-shaped container and give it a shadow effect. (I got some help from Stack Overflow.)

I want to give a natural shadow effect like the image above. The shadow effect I made is so ugly.

Below I’ll show you the shadow effect I made. I want it to be as natural as the shadow effect of the text field below it.

enter image description here

I tried various methods, but I can’t make natural shadows like the image above. I am so lacking.

help me.

Column(
                    children: [
                      SizedBox(
                        height: 50,
                      ),
                      ClipPath(
                        clipper: FolderShapeClipper(),
                        child: Card(
                          elevation: 0,
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(2)),
                          child: Container(
                            width: 274,
                            height: 188,
                            decoration: FolderShapeDecoration(
                              shadowColor: Color.fromRGBO(0, 0, 0, 0.2),
                              shadowBlurRadius: 5,
                              shadowOffset: Offset(-2, -2),
                            ),
                            child: Column(
                              mainAxisAlignment:
                                  MainAxisAlignment.spaceAround,
                              children: [
                                const SizedBox(
                                  height: 12,
                                ),
                                Padding(
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 24),
                                  child: Row(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceBetween,
                                    children: const [
                                      Text('test'),
                                      Icon(Icons.star),
                                    ],
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 24),
                                  child: Row(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceBetween,
                                    children: const [
                                      Text('count'),
                                      Text('10'),
                                    ],
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),

class FolderShapeClipper extends CustomClipper<Path> {
final a = 0.10;
final b = 0.25;
final c = 0.5;
@override
Path getClip(Size size) {
return Path()
  ..moveTo(size.width * a, 0)
  ..lineTo(0, size.height * b)
  ..lineTo(0, size.height)
  ..lineTo(size.width, size.height)
  ..lineTo(size.width, size.height * b)
  ..lineTo(size.width * c, size.height * b)
  ..lineTo(size.width * c, 0)
  ..lineTo(size.width * a, 0)
  ..close();
}

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

class FolderShapeDecoration extends BoxDecoration {
final Color shadowColor;
final double shadowBlurRadius;
final Offset shadowOffset;

FolderShapeDecoration({
required this.shadowColor,
required this.shadowBlurRadius,
required this.shadowOffset,
});

@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return _FolderShapeBoxPainter(
    shadowColor: shadowColor,
    shadowBlurRadius: shadowBlurRadius,
    shadowOffset: shadowOffset);
  }
 }

class _FolderShapeBoxPainter extends BoxPainter {
final Color shadowColor;
final double shadowBlurRadius;
final Offset shadowOffset;
final FolderShapeClipper clipper = FolderShapeClipper();

_FolderShapeBoxPainter({
required this.shadowColor,
required this.shadowBlurRadius,
required this.shadowOffset,
 });

@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
final size = configuration.size!;
final borderPath = clipper.getClip(size);

final shadowPaint = Paint()
  ..color = shadowColor
  ..maskFilter = MaskFilter.blur(BlurStyle.outer, shadowBlurRadius);

canvas.drawPath(borderPath.shift(offset + shadowOffset), shadowPaint);
 }
}

2

Answers


  1. You can also use Material widget it has elevation property that elevates Container or SizedBox etc… and it looks like it ha a shadow. But if you want to use shadow property you should change offset and blur radius values. But I really don’t know that which values are the most look like natural shadow.

    Login or Signup to reply.
  2. You can use the PhysicalModel widget https://api.flutter.dev/flutter/widgets/PhysicalModel-class.html or a DecoratedBox and then inside the BoxDecoration add a list of shadows.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search