Skip to content

Instantly share code, notes, and snippets.

@CoderNamedHendrick
Created July 19, 2023 03:30
Show Gist options
  • Save CoderNamedHendrick/944de37744ad4b9182734d1f20090881 to your computer and use it in GitHub Desktop.
Save CoderNamedHendrick/944de37744ad4b9182734d1f20090881 to your computer and use it in GitHub Desktop.
Animating button
class FineButton extends StatefulWidget {
const FineButton({super.key, this.onTap, this.label = 'label'});
final VoidCallback? onTap;
final String label;
@override
State<FineButton> createState() => _FineButtonState();
}
class _FineButtonState extends State<FineButton>
with SingleTickerProviderStateMixin {
static const _buttonShape = RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(32)));
static const _distance = 5.0;
static const _size = 48.0;
static final _progress = Tween<double>(begin: _distance, end: 0);
late final AnimationController controller;
late final Animation<double> _progressAnim;
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 700));
_progressAnim = _progress
.animate(CurvedAnimation(parent: controller, curve: Curves.ease));
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: _size,
width: double.infinity,
child: AnimatedBuilder(
animation: controller,
builder: (context, child) {
return Stack(
children: [
Positioned.fill(
left: _distance,
bottom: _distance,
child: Container(
height: 43,
width: double.infinity,
decoration: ShapeDecoration(
shape: _buttonShape,
color: Colors.green.shade300,
),
),
),
Positioned.fill(
top: _progressAnim.value,
right: _progressAnim.value,
bottom: 5 - _progressAnim.value,
left: 5 - _progressAnim.value,
child: Container(
width: double.infinity,
height: 43,
alignment: Alignment.center,
decoration: ShapeDecoration(
shape: _buttonShape,
color: Theme.of(context).colorScheme.primaryContainer,
),
child: Text(
widget.label,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Colors.white,
),
),
),
),
Positioned.fill(
top: 3,
right: 3,
child: InkWell(
onTap: widget.onTap,
onTapUp: (details) {
controller.reverse();
},
onTapDown: (details) {
controller.forward();
},
customBorder: _buttonShape,
splashColor: Colors.green.shade500,
),
),
],
);
},
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment