From 62afb82b7219ab006031cea06706bb9ada8279cc Mon Sep 17 00:00:00 2001 From: Ayan Das Date: Tue, 25 Apr 2023 11:30:49 +0530 Subject: [PATCH] practice 1: sunrise - completed --- lib/Screens/practice1.dart | 278 +++++++++++++++++++++++++++++++++++++ lib/main.dart | 3 + 2 files changed, 281 insertions(+) create mode 100644 lib/Screens/practice1.dart diff --git a/lib/Screens/practice1.dart b/lib/Screens/practice1.dart new file mode 100644 index 0000000..082e760 --- /dev/null +++ b/lib/Screens/practice1.dart @@ -0,0 +1,278 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first + +import 'package:flutter/material.dart'; + +class Practice1 extends StatefulWidget { + const Practice1({super.key}); + + @override + State createState() => _Practice1State(); +} + +class _Practice1State extends State with TickerProviderStateMixin { + late AnimationController _birdController; + late Animation _birdAnimation; + + late AnimationController _wave1Controller; + late AnimationController _wave2Controller; + late AnimationController _wave3Controller; + + late Animation _wave1Animation; + late Animation _wave2Animation; + late Animation _wave3Animation; + + @override + void initState() { + // Animation Controllers + _wave1Controller = + AnimationController(vsync: this, duration: const Duration(seconds: 1)); + _wave2Controller = + AnimationController(vsync: this, duration: const Duration(seconds: 2)); + _wave3Controller = + AnimationController(vsync: this, duration: const Duration(seconds: 3)); + + // Animations + _wave1Animation = + Tween(begin: 70, end: 90).animate(_wave1Controller); + _wave2Animation = + Tween(begin: 0, end: 10).animate(_wave2Controller); + _wave3Animation = + Tween(begin: 0, end: 10).animate(_wave3Controller); + + // Listeners + _wave1Controller.addStatusListener((status) { + if (status == AnimationStatus.completed) { + _wave1Controller.reverse(); + } + if (status == AnimationStatus.dismissed) { + _wave1Controller.forward(); + } + }); + + _wave2Controller.addStatusListener((status) { + if (status == AnimationStatus.completed) { + _wave2Controller.reverse(); + } + if (status == AnimationStatus.dismissed) { + _wave2Controller.forward(); + } + }); + + _wave3Controller.addStatusListener((status) { + if (status == AnimationStatus.completed) { + _wave3Controller.reverse(); + } + if (status == AnimationStatus.dismissed) { + _wave3Controller.forward(); + } + }); + + _birdController = AnimationController( + vsync: this, + duration: Duration(seconds: 1), + ); + + _birdAnimation = Tween(begin: 0, end: 10).animate(_birdController); + + _birdController.addStatusListener((status) { + if (status == AnimationStatus.completed) { + _birdController.reverse(); + } + if (status == AnimationStatus.dismissed) { + _birdController.forward(); + } + }); + + super.initState(); + } + + @override + void dispose() { + _birdController.dispose(); + _wave1Controller.dispose(); + _wave2Controller.dispose(); + _wave3Controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + _birdController.forward(); + _wave3Controller.forward(); + _wave2Controller.forward(); + _wave1Controller.forward(); + return TweenAnimationBuilder( + tween: ColorTween(begin: Colors.black, end: Colors.transparent), + duration: const Duration(seconds: 6), + builder: (context, value, child) => Container( + decoration: const BoxDecoration( + gradient: LinearGradient(colors: [ + Colors.yellowAccent, + Colors.orangeAccent, + Colors.orange + ], begin: Alignment.bottomCenter, end: Alignment.topCenter)), + child: Scaffold( + backgroundColor: value, + appBar: AppBar( + title: const Text("Sunrise"), + ), + body: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const SizedBox( + height: 50, + ), + Row( + children: [ + const SizedBox( + width: 115, + ), + AnimatedBuilder( + animation: _birdController, + builder: (context, child) => Transform.translate( + offset: Offset(0, -_birdAnimation.value), + child: const Bird()), + ), + const SizedBox( + width: 70, + ), + AnimatedBuilder( + animation: _birdController, + builder: (context, child) => Transform.translate( + offset: Offset(0, -_birdAnimation.value), + child: const Bird()), + ), + ], + ), + const Bird(), + Expanded(child: Container()), + Stack( + alignment: Alignment.bottomCenter, + children: [ + TweenAnimationBuilder( + tween: Tween(begin: 0, end: 70), + duration: const Duration(seconds: 6), + builder: (context, value, child) => Transform.translate( + offset: Offset(0, -value), child: const Sun())), + AnimatedBuilder( + animation: _wave3Controller, + builder: (context, child) => Transform.translate( + offset: Offset(0, -_wave3Animation.value), + child: ClipPath( + clipper: WaveClipper(waves: 4), + child: Container( + width: 400, + height: 150, + color: Colors.blue[100], + )), + ), + ), + AnimatedBuilder( + animation: _wave2Controller, + builder: (context, child) => Transform.translate( + offset: Offset(0, -_wave2Animation.value), + child: ClipPath( + clipper: WaveClipper(waves: 5), + child: Container( + width: 400, + height: 120, + color: Colors.lightBlueAccent, + ), + ), + ), + ), + AnimatedBuilder( + animation: _wave1Controller, + builder: (context, child) => ClipPath( + clipper: WaveClipper(waves: 6), + child: Container( + width: 400, + height: _wave1Animation.value, + color: Colors.blue, + ), + ), + ), + ], + ) + ], + ), + ), + ), + ); + } +} + +class BirdClipper extends CustomClipper { + @override + Path getClip(Size size) { + Path path = Path(); + path.moveTo(0, size.height / 2); + path.arcToPoint(Offset(size.width / 2, size.height / 2), + radius: Radius.circular(size.height / 4)); + path.arcToPoint(Offset(size.width, size.height / 2), + radius: Radius.circular(size.height / 4)); + path.arcToPoint(Offset(size.width / 2, size.height), + clockwise: false, radius: Radius.circular(size.height / 6)); + path.arcToPoint(Offset(0, size.height / 2), + clockwise: false, radius: Radius.circular(size.height / 6)); + path.close(); + return path; + } + + @override + bool shouldReclip(covariant CustomClipper oldClipper) => true; +} + +class WaveClipper extends CustomClipper { + final int waves; + WaveClipper({ + required this.waves, + }); + + @override + getClip(Size size) { + Path path = Path(); + path.moveTo(0, size.height / 5); + for (int i = 1; i < waves + 1; i++) { + path.arcToPoint(Offset(i * size.width / waves, size.height / waves), + radius: Radius.circular(size.height)); + } + path.lineTo(size.width, size.height); + path.lineTo(0, size.height); + path.close(); + return path; + } + + @override + bool shouldReclip(covariant CustomClipper oldClipper) => true; +} + +class Bird extends StatelessWidget { + const Bird({super.key}); + + @override + Widget build(BuildContext context) { + return ClipPath( + clipper: BirdClipper(), + child: Container(height: 20, width: 40, color: Colors.black), + ); + } +} + +class Sun extends StatelessWidget { + const Sun({super.key}); + + @override + Widget build(BuildContext context) { + return ClipPath( + child: Container( + height: 100, + width: 100, + decoration: BoxDecoration( + color: Colors.orange, + borderRadius: + BorderRadius.circular(MediaQuery.of(context).size.width / 2)), + ), + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 3e49df2..15407cc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,7 @@ import 'package:animations/Screens/lecture3.dart'; import 'package:animations/Screens/lecture4.dart'; import 'package:animations/Screens/lecture5.dart'; import 'package:animations/Screens/lecture6.dart'; +import 'package:animations/Screens/practice1.dart'; import 'package:flutter/material.dart'; import 'Screens/lecture1.dart'; @@ -41,6 +42,7 @@ class MyApp extends StatelessWidget { 'lec4/': (context) => const Lecture4(title: "Hero Animation"), 'lec5/': (context) => const Lecture5(title: "Implicit Animations"), 'lec6/': (context) => const Lecture6(title: "TweenAnimationBuilder"), + 'practice1/': (context) => const Practice1(), }, ); } @@ -79,6 +81,7 @@ class _MyHomePageState extends State { Link( link: 'lec6/', title: 'TweenAnimationBuilder, ClipPath, CustomClipper'), + Link(link: 'practice1/', title: "Practice 1") ], ), ),