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.
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
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.
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.