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;
  String param;
  int playTime = 10;
  double tm;

  @override
  void initState() {
    super.initState();
    param = "beginning";
    _controller = AnimationController(
      duration: Duration(seconds: playTime),
      vsync: this,
    )..addListener(() => contrVal());
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  Future _startAnim() async {
    try {
      _controller.reset();
      await _controller.forward().orCancel;
      // await _controller.reverse().orCancel;
    } on TickerCanceled {
      print('welp we fucked');
    }
  }

  contrVal() {
    setState(() {
      tm = _controller.value;
      if (_controller.value >= 0.2) param = 'two seconds';
      if (_controller.value >= 0.5) param = "five seconds";
      if (_controller.value >= 1) param = "ten seconds";
    });
  }

  @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
                ),
                // Container(width: 100, height: 100, decoration: BoxDecoration(color: Colors.black)),
                MovingHole(
                  controller: _controller,
                  time: playTime,
                ),
              ],
            ),
          ),
          Container(
              alignment: Alignment.bottomCenter,
              child: Text(
                "$param",
                style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
              ))
        ],
      ),
    ));
  }
}

class MovingHole extends StatefulWidget {
  MovingHole({Key key, this.controller, this.time}) : super(key: key);

  final int time;
  final AnimationController controller;

  @override
  _MovingHoleState createState() => _MovingHoleState();
}

class _MovingHoleState extends State<MovingHole> {
  _MovingHoleState();
  AnimationController controller;
  List<Animation<double>> scale = [];
  List<Animation<Offset>> move = [];

  @override
  void initState() {
    super.initState();
    controller = widget.controller;
    scale
      ..add(Tween<double>(begin: 1.0, end: 0.5).animate(
        CurvedAnimation(
          parent: controller,
          curve: Interval(tu(0.5), tu(1.25), curve: Curves.easeOut),
        ),
      ))
      ..add(Tween<double>(begin: 0.5, end: 1.2).animate(
        CurvedAnimation(
          parent: controller,
          curve: Interval(
            tu(3.5),
            tu(4.0),
            curve: Curves.ease,
          ),
        ),
      ));
    move
      ..add(Tween<Offset>(begin: Offset(0, 20), end: Offset(-20, 100)).animate(CurvedAnimation(
        parent: controller,
        curve: Interval(
          tu(0.0),
          tu(0.5),
          curve: Curves.ease,
        ),
      )))
      ..add(Tween<Offset>(begin: Offset(50, 100), end: Offset(30, 20)).animate(CurvedAnimation(
        parent: controller,
        curve: Interval(
          0.9,
          1.0,
          curve: Curves.ease,
        ),
      )));
  }

  double tu(double value) {
    return value / widget.time;
  }

  @override
  Widget build(BuildContext context) {
    Matrix4 allMoves = Matrix4.identity();
    scale.forEach((item) {
      allMoves.scale(item.value);
    });
    move.forEach((item) {
      allMoves.translate(item.value.dx, item.value.dy);
    });
    return
        // AnimatedBuilder(
        //     animation: controller,
        //     builder: (BuildContext context, Widget child) {
        //       return
        //           // Container(
        //   child:
        Transform(
      alignment: Alignment.topLeft,
      transform: allMoves,
      child: Container(
          // width: 60.0,
          // height: 10.0,
          decoration: BoxDecoration(
        shape: BoxShape.rectangle,
        color: Colors.black,
        // border: Border.all(color: color, style: BorderStyle.solid, width: 4.0 - (2 * controller.value))
        // ),
      )),
    );
    // });
  }
}
// создать переменную, листенером слить текущее значение, на поляне в стеке вывести.
// сколько составляет 0.05 от 10 секунд
