Skip to content

Instantly share code, notes, and snippets.

@mingsai
Created January 4, 2021 22:09
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 mingsai/c73ddd3453b552ef5ded7d5174da9628 to your computer and use it in GitHub Desktop.
Save mingsai/c73ddd3453b552ef5ded7d5174da9628 to your computer and use it in GitHub Desktop.
Flutter splash animation test
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';
import 'package:gr_life/constants.dart';
class SplashPage extends StatefulWidget {
@override
SplashPageState createState() => new SplashPageState();
}
class SplashPageState extends State<SplashPage>
with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = new AnimationController(
duration: const Duration(milliseconds: 500), vsync: this);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
return new SplashAnimation(controller: _controller, context: context);
}
}
class SplashAnimation extends StatelessWidget {
SplashAnimation({Key key, this.controller, BuildContext context})
: opacity = new Tween<double>(
begin: 1.0,
end: 0.0,
)
.animate(
new CurvedAnimation(
parent: controller,
curve: new Interval(
0.0,
0.1,
curve: Curves.ease,
),
),
),
bluePosition = new RelativeRectTween(
begin: new RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0),
end: new RelativeRect.fromLTRB(-MediaQuery.of(context).size.width - 1,
-MediaQuery.of(context).size.height - 1, 0.0, 0.0),
)
.animate(
new CurvedAnimation(
parent: controller,
curve: new Interval(
0.0,
0.3,
curve: Curves.ease,
),
),
),
magentaPosition = new RelativeRectTween(
begin: new RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0),
end: new RelativeRect.fromLTRB(
0.0,
0.0,
-MediaQuery.of(context).size.width - 1,
-MediaQuery.of(context).size.height - 1),
)
.animate(
new CurvedAnimation(
parent: controller,
curve: new Interval(
0.0,
0.3,
curve: Curves.ease,
),
),
),
super(key: key);
final AnimationController controller;
final Animation<double> opacity;
final Animation<RelativeRect> bluePosition;
final Animation<RelativeRect> magentaPosition;
Future<Null> _playAnimation(BuildContext context) async {
try {
await controller.forward().orCancel;
// await controller.reverse().orCancel;
Navigator.pushNamed(context, '/somewhere');
} on TickerCanceled {
// the animation got canceled, probably because we were disposed
}
}
Widget _buildAnimation(BuildContext context, Widget child) {
return new Scaffold(
appBar: null,
body: new InkWell(
onTap: () {
_playAnimation(context);
},
child: new Stack(
children: <Widget>[
new PositionedTransition(
rect: bluePosition,
child: new ClipPath(
child: new Container(
color: GymRushColors.blue[300],
),
clipper: new DiagonalBlueClipper(),
)),
new PositionedTransition(
rect: magentaPosition,
child: new ClipPath(
child: new Container(
color: GymRushColors.magenta[100],
),
clipper: new DiagonalMagentaClipper())),
new LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return new Opacity(
opacity: opacity.value,
child: new Center(
child: new ClipPath(
child: new Text(
"G",
textAlign: TextAlign.center,
style: new TextStyle(
color: Colors.white,
fontFamily: "gr-font",
fontSize: constraints.maxWidth / 2,
),
),
clipper: new DiagonalGClipper(
constraints.maxWidth, constraints.maxHeight),
),
heightFactor:
1.5 * constraints.maxHeight / constraints.maxWidth,
));
}),
new LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return new Center(
child: new Padding(
child: new CircularProgressIndicator(
valueColor:
new AlwaysStoppedAnimation<Color>(Colors.white),
),
padding: new EdgeInsets.only(
top: constraints.maxHeight * 0.5)));
}),
],
)),
);
}
@override
Widget build(BuildContext context) {
return new AnimatedBuilder(
builder: _buildAnimation,
animation: controller,
);
}
}
class DiagonalBlueClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Path path = new Path();
path.lineTo(0.0, size.height);
path.lineTo(size.width, 0.0);
path.close();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
class DiagonalMagentaClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Path path = new Path();
path.moveTo(0.0, size.height);
path.lineTo(size.width, size.height);
path.lineTo(size.width, 0.0);
path.close();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
class DiagonalGClipper extends CustomClipper<Path> {
DiagonalGClipper(this.w, this.h);
final w;
final h;
@override
Path getClip(Size size) {
var p1y = 0.75 * h * size.height / w - size.height / 2;
var p1x = w - p1y * w / h - w / 4 - w / 2 + size.width;
var p4y = p1y + size.height / 3;
var p4x = w - p4y * w / h - w / 4 - w / 2 + size.width;
Path path = new Path();
path.lineTo(p1x, 0.0);
path.lineTo(p4x, size.height / 3);
path.lineTo(size.width, size.height / 3);
path.lineTo(size.width, size.height);
path.lineTo(0.0, size.height);
path.close();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment