shadows
inside Container
widget.First: build the shape of the button
Here is the shape path
Path myCustomShapePath(Rect rect) {
var r1 = rect.height * 0.5;
var r2 = rect.height * 0.35;
var r3 = rect.height * 0.1;
var L = rect.left;
var R = rect.right;
var T = rect.top;
var B = rect.bottom;
return Path()
..moveTo(L, T + r2)
..arcTo(Rect.fromLTWH(L, T, r2, r2), pi, 0.5 * pi, false)
..lineTo(R - r2, T)
..arcTo(Rect.fromLTWH(R - r2, T, r2, r2), 1.5 * pi, 0.5 * pi, false)
..lineTo(R, B - r1 - 2 * r3)
..arcTo(Rect.fromLTWH(R - r3, B - r1 - 2 * r3, r3, r3), 0, 0.5 * pi, false)
..arcTo(Rect.fromLTWH(R - r1 - r3, B - r1 - r3, r1 * 2.5, r1 * 2.5),
1.5 * pi, -0.5 * pi, false)
..arcTo(Rect.fromLTWH(R - r1 - 2 * r3, B - r3, r3, r3), 0, 0.5 * pi, false)
..lineTo(R - r2, B)
..arcTo(Rect.fromLTWH(L, B - r2, r2, r2), 0.5 * pi, 0.5 * pi, false)
..close();
}
Because I want the custom shape for the button and avoid the shadow blur outside of the button, so I extend both ShapeBorder
and CustomClipper<Path>
with the same path:
CustomClipPath
class CustomClipPath extends CustomClipper<Path> {
@override
Path getClip(Size size) =>
myCustomShapePath(Rect.fromLTRB(0, 0, size.width, size.height));
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}
CustomShape
class CustomShape extends ShapeBorder {
@override
EdgeInsetsGeometry get dimensions => const EdgeInsets.only();
@override
Path getInnerPath(Rect rect, {TextDirection textDirection}) =>
getOuterPath(rect, textDirection: textDirection);
@override
Path getOuterPath(Rect rect, {TextDirection textDirection}) =>
myCustomShapePath(rect);
@override
void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {}
@override
ShapeBorder scale(double t) => null;
}
Second: use BoxShadow to draw the button
Use ClipPath
to clip the shadow blur and use shadows
inside Container's ShapeDecoration
to draw the 3D effect:
class MySolidButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ClipPath(
clipper: CustomClipPath(),
child: Container(
width: 200,
height: 100,
decoration: ShapeDecoration(
shape: CustomShape(),
shadows: [
BoxShadow(color: Colors.white),
BoxShadow(
color: Color(0xFF550091),
offset: Offset(0, 20),
blurRadius: 5,
spreadRadius: 10,
),
BoxShadow(
color: Color(0xFFA93EF0),
blurRadius: 10,
spreadRadius: -2,
),
],
),
child: FlatButton(
onPressed: () {},
),
),
);
}
}
Result
Update:
LayoutBuilder
child: Container(
width: 300,
height: 200,
child: LayoutBuilder(
builder: (context, constraint) {
// get constraint here 300 x 200
return Container(
decoration: ShapeDecoration(
shape: CustomShape(),
Tags:
#RoundedRectangleBorder