Last active
February 9, 2020 04:37
-
-
Save diegoveloper/3cbeb1fd325f88911bd9e5eb38b17849 to your computer and use it in GitHub Desktop.
This file contains hidden or 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'; | |
final Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue), | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Center( | |
child: MyWidget(), | |
), | |
), | |
); | |
} | |
} | |
class MyWidget extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Center( | |
child: SplitDiagonalWidget( | |
child: Image.network( | |
"https://imagenesgamers.canalrcn.com/ImgTodoGamers/dragon_ball_super_errores_portada.jpg")), | |
); | |
} | |
} | |
class SplitDiagonalWidget extends StatefulWidget { | |
final Widget child; | |
const SplitDiagonalWidget({ | |
Key key, | |
@required this.child, | |
}) : super(key: key); | |
@override | |
_SplitDiagonalWidgetState createState() => _SplitDiagonalWidgetState(); | |
} | |
class _SplitDiagonalWidgetState extends State<SplitDiagonalWidget> | |
with SingleTickerProviderStateMixin { | |
AnimationController _controller; | |
Animation<double> _animation; | |
double _childHeight; | |
GlobalKey _childKey = GlobalKey(); | |
Widget _buildSide({bool top = true}) { | |
return AnimatedBuilder( | |
animation: _animation, | |
builder: (_, child) => Transform.translate( | |
offset: Offset(0.0, !top ? 1 : -1) * _animation.value / 2, | |
child: child, | |
), | |
child: ClipPath( | |
child: widget.child, | |
clipper: SplitClipper(top: top), | |
), | |
); | |
} | |
void _onLayoutDone(_) { | |
_childHeight = _childKey.currentContext.size.height; | |
_animation = Tween<double>( | |
begin: 0.0, | |
end: _childHeight * 0.5, | |
).animate( | |
CurvedAnimation( | |
parent: _controller, | |
curve: Curves.decelerate, | |
), | |
); | |
setState(() {}); | |
} | |
@override | |
void initState() { | |
_controller = AnimationController( | |
vsync: this, | |
duration: Duration(seconds: 1), | |
); | |
WidgetsBinding.instance.addPostFrameCallback(_onLayoutDone); | |
super.initState(); | |
} | |
void _startAnimation() { | |
_controller.forward(from: 0.0).whenComplete(() => _controller.reverse()); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return GestureDetector( | |
onTap: _startAnimation, | |
key: _childKey, | |
child: Center( | |
child: SizedBox( | |
height: _childHeight != null ? _childHeight : 0.0, | |
width: MediaQuery.of(context).size.width, | |
child: _childHeight != null | |
? Stack( | |
fit: StackFit.expand, | |
children: [ | |
_buildSide(), | |
_buildSide(top: false), | |
], | |
) | |
: const SizedBox.shrink(), | |
), | |
), | |
); | |
} | |
} | |
class SplitClipper extends CustomClipper<Path> { | |
final bool top; | |
SplitClipper({this.top = false}); | |
@override | |
Path getClip(Size size) { | |
Path path = Path(); | |
path.moveTo(0.0, size.height * 0.75); | |
path.lineTo(size.width, size.height * 0.25); | |
if (!top) { | |
path.lineTo(size.width, size.height); | |
path.lineTo(0.0, size.height); | |
} else { | |
path.lineTo(size.width, 0.0); | |
path.lineTo(0.0, 0.0); | |
} | |
path.close(); | |
return path; | |
} | |
@override | |
bool shouldReclip(CustomClipper oldClipper) => false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment