Files
moving_hole/lib/main.dart
2021-01-08 22:09:37 +03:00

161 lines
4.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Scaffold(body: App()));
}
}
class App extends StatefulWidget {
@override
AppState createState() => AppState();
}
class AppState extends State<App> with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: 9),
vsync: this,
);
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
Future _startAnim() async {
try {
await _controller.forward().orCancel;
// await _controller.reverse().orCancel;
} on TickerCanceled {
print('welp we fucked');
}
}
@override
Widget build(BuildContext context) {
return Material(
child: GestureDetector(
onTap: () {
_startAnim();
},
child: Stack(
fit: StackFit.expand,
children: [
Image.network(
'https://wallpaperplay.com/walls/full/e/5/3/13586.jpg',
fit: BoxFit.cover,
),
ColorFiltered(
colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.8),
BlendMode.srcOut), // This one will create the magic
child: Stack(
fit: StackFit.expand,
children: [
Container(
decoration: BoxDecoration(
color: Colors.black,
backgroundBlendMode: BlendMode
.dstOut), // This one will handle background + difference out
),
MovingHole(controller: _controller)
],
),
),
],
),
));
}
}
class MovingHole extends StatelessWidget {
MovingHole({Key key, this.controller})
: width = TweenSequence(
<TweenSequenceItem<double>>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 100, end: 150)
.chain(CurveTween(curve: Curves.ease)),
weight: 33.0,
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 150, end: 200),
weight: 33.0,
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 200, end: 300)
.chain(CurveTween(curve: Curves.ease)),
weight: 33.0,
),
],
).animate(CurvedAnimation(
parent: controller, curve: Interval(0.0, 1, curve: Curves.linear))),
height = TweenSequence(
<TweenSequenceItem<double>>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 100, end: 150)
.chain(CurveTween(curve: Curves.ease)),
weight: 40.0,
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 150, end: 200),
weight: 20.0,
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 200, end: 300)
.chain(CurveTween(curve: Curves.ease)),
weight: 40.0,
),
],
).animate(CurvedAnimation(
parent: controller,
curve: Interval(0.0, 1, curve: Curves.fastOutSlowIn))),
radius = BorderRadiusTween(
begin: BorderRadius.circular(0.0),
end: BorderRadius.circular(100.0))
.animate(CurvedAnimation(
parent: controller,
curve: Interval(
0.0,
1,
curve: Curves.ease,
))),
alignment = AlignmentTween(
begin: Alignment.bottomCenter, end: Alignment.topCenter)
.animate(CurvedAnimation(
parent: controller,
curve: Interval(0.0, 1, curve: Curves.ease))),
super(key: key);
Animation<double> controller;
Animation<double> width;
Animation<double> height;
Animation<BorderRadius> radius;
Animation<Alignment> alignment;
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: controller,
builder: (BuildContext context, Widget child) {
return Container(
alignment: alignment.value,
child: Container(
width: width.value,
height: height.value,
decoration: BoxDecoration(
color: Colors.red, borderRadius: radius.value),
));
});
}
}