I'm trying to add elevation on the custom path by using Material's elevation but looks like is not doing anything, I've tried other method but got elevation on whole material (rectangular).
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.pink[300],
body: Column(
children: <Widget>[
TopContainer(),
],
));
}
}
class TopContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ClipPath(
clipper: ImageClipper(),
child: Material(
elevation: 15.0,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'https://images.pexels.com/photos/3309467/pexels-photo-3309467.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
),
),
),
constraints: BoxConstraints.expand(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.5,
),
),
));
}
}
class ImageClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
var path = Path();
path.lineTo(0.0, size.height);
var firstControlPoint = Offset(size.width * 0.35, size.height * 0.75);
var firstEndPoint = Offset(size.width * 0.65, size.height * 0.85);
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
firstEndPoint.dx, firstEndPoint.dy);
///////////////////////////////////////////////
var secondControlPoint = Offset(size.width * 0.85, size.height * 0.90);
var secondEndPoint = Offset(size.width, size.height * 0.75);
path.quadraticBezierTo(secondControlPoint.dx, secondControlPoint.dy,
secondEndPoint.dx, secondEndPoint.dy);
// path.lineTo(size.width, size.height * 0.9);
path.lineTo(size.width, 0.0);
path.close();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return false;
}
}
I'm trying to add elevation on the custom path by using Material's elevation but looks like is not doing anything, I've tried other method but got elevation on whole material (rectangular).

use that custom ShapeBorder
class WaveShapeBorder extends ShapeBorder {
@override EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
@override ui.Path getInnerPath(ui.Rect rect, {ui.TextDirection textDirection}) => null;
@override
ui.Path getOuterPath(ui.Rect rect, {ui.TextDirection textDirection}) {
var ctrl1 = FractionalOffset(0.35, 0.75).withinRect(rect);
var end1 = FractionalOffset(0.65, 0.85).withinRect(rect);
var ctrl2 = FractionalOffset(0.85, 0.90).withinRect(rect);
var end2 = FractionalOffset(1.0, 0.75).withinRect(rect);
return Path()
..moveTo(rect.topLeft.dx, rect.topLeft.dy)
..lineTo(rect.bottomLeft.dx, rect.bottomLeft.dy)
..quadraticBezierTo(ctrl1.dx, ctrl1.dy, end1.dx, end1.dy)
..quadraticBezierTo(ctrl2.dx, ctrl2.dy, end2.dx, end2.dy)
..lineTo(rect.topRight.dx, rect.topRight.dy)
..close();
}
@override void paint(ui.Canvas canvas, ui.Rect rect, {ui.TextDirection textDirection}) {}
@override ShapeBorder scale(double t) => this;
}
and this sample code for testing:
class WaveShapeBorderTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.teal, Colors.green],
begin: Alignment.topRight,
end: Alignment.centerLeft,
),
),
child: Stack(
children: [
Material(
elevation: 6,
shape: WaveShapeBorder(),
clipBehavior: Clip.antiAlias,
child: Image.asset('images/someImage.png'),
),
],
),
);
}
}
of course you have a freedom on how you use it but the main idea is to use Material.shape and Material.clipBehavior properties
this is a final result:

EDIT and if you think your shadow is too "light" you can add one additional Container with custom shadows:
class WaveShapeBorderTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.teal, Colors.green],
begin: Alignment.topRight,
end: Alignment.centerLeft,
),
),
child: Stack(
children: [
Container(
decoration: ShapeDecoration(
shape: WaveShapeBorder(),
shadows: [
BoxShadow(color: Colors.black, blurRadius: 16, offset: Offset(2, 2), spreadRadius: 8),
]
),
child: Material(
clipBehavior: Clip.antiAlias,
shape: WaveShapeBorder(),
child: Image.asset('images/someImage.png',),
),
),
Icon(Icons.photo, size: 64,),
],
),
);
}
}
and you will see this:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With