Skip to content

Instantly share code, notes, and snippets.

@fathidevs
Created April 18, 2022 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fathidevs/28751f3529d497727946aaea820a9967 to your computer and use it in GitHub Desktop.
Save fathidevs/28751f3529d497727946aaea820a9967 to your computer and use it in GitHub Desktop.
3d button
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: CustomButton(
label: "Click Me",
onPressed: () {},
elevation: 20.0,
),
),
),
);
}
}
class CustomButtonStyle {
final Color topFaceColor;
final Color bodyColor;
final BorderRadius borderRadius;
final Color labelColor;
const CustomButtonStyle(
{this.topFaceColor = Colors.white,
this.bodyColor = Colors.grey,
this.borderRadius = const BorderRadius.all(Radius.circular(0.0)),
this.labelColor = Colors.black});
static const defaultColor = CustomButtonStyle();
static const blue = CustomButtonStyle(
topFaceColor: Colors.blue,
bodyColor: Colors.blueGrey,
labelColor: Colors.white);
}
class CustomButton extends StatefulWidget {
final String label;
final Duration duration;
final CustomButtonStyle style;
final VoidCallback onPressed;
final double elevation;
const CustomButton(
{Key? key,
required this.label,
this.duration = const Duration(milliseconds: 60),
this.style = CustomButtonStyle.defaultColor,
this.elevation = 20.0,
required this.onPressed})
: super(key: key);
@override
State<CustomButton> createState() => _CustomButtonState();
}
class _CustomButtonState extends State<CustomButton> {
final double verticalPadd = 18.0;
final double horizontalPadd = 18.0;
bool isTapped = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapUp: (TapUpDetails details) => _tapUp(details),
onTapDown: (TapDownDetails details) => _tapDown(details),
onTapCancel: () => _tapCancel(),
child: Stack(
alignment: Alignment.center,
children: [_body(), _topFace()],
),
);
}
Widget _topFace() {
return AnimatedPadding(
duration: widget.duration,
curve: Curves.ease,
padding: EdgeInsets.only(bottom: isTapped ? 0.0 : widget.elevation),
child: Container(
decoration: BoxDecoration(
color: widget.style.topFaceColor,
borderRadius: widget.style.borderRadius),
child: Padding(
padding: EdgeInsets.symmetric(
vertical: verticalPadd, horizontal: horizontalPadd),
child: LimitedBox(
maxWidth: MediaQuery.maybeOf(context)!.size.width * .9,
child: Text(
widget.label,
style: TextStyle(color: widget.style.labelColor),
),
),
),
),
);
}
Widget _body() {
return Container(
decoration: BoxDecoration(
color: widget.style.bodyColor,
borderRadius: widget.style.borderRadius,
),
child: Padding(
padding: EdgeInsets.symmetric(
vertical: verticalPadd, horizontal: horizontalPadd - .1),
child: LimitedBox(
maxWidth: MediaQuery.maybeOf(context)!.size.width * .9,
child: Visibility(
visible: false,
maintainAnimation: true,
maintainSize: true,
maintainState: true,
child: Text(
widget.label,
style: TextStyle(color: widget.style.labelColor),
),
),
),
),
);
}
void _tapDown(TapDownDetails details) {
setState(() {
isTapped = true;
});
}
void _tapCancel() {
setState(() {
isTapped = false;
});
}
void _tapUp(TapUpDetails details) {
setState(() {
isTapped = false;
});
widget.onPressed();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment