Last active
May 21, 2021 02:35
-
-
Save Schwusch/f426e015140afdbcef735b25bb77746c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
class BreathingWidget extends StatefulWidget { | |
final Widget child; | |
const BreathingWidget({Key key, @required this.child}) : super(key: key); | |
@override | |
_BreathingWidgetState createState() => _BreathingWidgetState(); | |
} | |
class _BreathingWidgetState extends State<BreathingWidget> | |
with TickerProviderStateMixin { | |
AnimationController _breathingController; | |
AnimationController _pulseController; | |
Animation _animation; | |
var _breathe = 0.0; | |
@override | |
void initState() { | |
super.initState(); | |
_breathingController = | |
AnimationController(vsync: this, duration: Duration(seconds: 1)); | |
_pulseController = AnimationController( | |
vsync: this, duration: Duration(milliseconds: 1500)); | |
_breathingController.addStatusListener((status) { | |
if (status == AnimationStatus.completed) { | |
_breathingController.reverse(); | |
} else if (status == AnimationStatus.dismissed) { | |
_breathingController.forward(); | |
} | |
}); | |
_animation = CurvedAnimation( | |
parent: _breathingController, | |
curve: Curves.fastOutSlowIn, | |
reverseCurve: Curves.fastOutSlowIn.flipped); | |
_breathingController.addListener(() => setState(() { | |
if (_breathingController.status == AnimationStatus.forward && | |
_animation.value > 0.3) { | |
if (_pulseController.status != AnimationStatus.forward) { | |
_pulseController.value = 0.0; | |
} | |
_pulseController.forward(); | |
} | |
_breathe = _animation.value; | |
})); | |
_breathingController.forward(); | |
} | |
@override | |
void dispose() { | |
super.dispose(); | |
_breathingController.dispose(); | |
_pulseController.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return CustomPaint( | |
painter: PulsePainter(Curves.easeOut.transform(_pulseController.value)), | |
child: Transform.scale( | |
scale: 0.95 + (0.1 * _breathe), | |
child: widget.child, | |
), | |
); | |
} | |
} | |
class PulsePainter extends CustomPainter { | |
final double scale; | |
PulsePainter(this.scale); | |
@override | |
void paint(Canvas canvas, Size size) { | |
var rect = | |
Offset.zero.translate(-(size.width * 2.5), -5 - (size.height * 2.5)) & | |
(size * 6); | |
var dynamicColor = Colors.blueGrey.withOpacity( | |
1.0 - (scale * 0.2 + 0.85).clamp(0.0, 1.0), | |
); | |
var gradient = RadialGradient( | |
colors: [ | |
Colors.transparent.withOpacity(0.0), | |
dynamicColor, | |
Colors.transparent.withOpacity(0.0), | |
dynamicColor, | |
Colors.transparent.withOpacity(0.0), | |
], | |
stops: [ | |
scale, | |
(scale + 0.05).clamp(0.0, 1.0), | |
(scale + 0.07).clamp(0.0, 1.0), | |
(scale + 0.10).clamp(0.0, 1.0), | |
(scale + 0.2).clamp(0.0, 1.0), | |
], | |
); | |
canvas.drawRect( | |
rect, | |
Paint() | |
..shader = gradient.createShader(rect) | |
..blendMode = BlendMode.srcATop); | |
} | |
@override | |
bool shouldRepaint(CustomPainter oldDelegate) => true; | |
} |
Author
Schwusch
commented
Jan 14, 2019
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment