splash animation added.

pull/57/head
Sikander Saleem 1 month ago
parent 2584e6cc6e
commit 12cef74f16

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
{"nm":"Splash Launch 1","ddd":0,"h":927,"w":430,"meta":{"g":"LottieFiles Figma v92"},"layers":[{"ty":4,"nm":"Ellipse 54","sr":1,"st":0,"op":121.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[19.5,19.5],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[19.5,19.5],"t":60},{"s":[628.5,628.5],"t":120}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[216,464],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[216.5,464.5],"t":60},{"s":[225.5,473.5],"t":120}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[0],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[0],"t":60},{"s":[100],"t":120}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[{"c":true,"i":[[0,0],[10.493846153846153,0],[0,10.493846153846153],[-10.493846153846153,0],[0,-10.493846153846153]],"o":[[0,10.493846153846153],[-10.493846153846153,0],[0,-10.493846153846153],[10.493846153846153,0],[0,0]],"v":[[38,19],[19,38],[0,19],[19,0],[38,19]]}],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[{"c":true,"i":[[0,0],[10.493846153846153,0],[0,10.493846153846153],[-10.493846153846153,0],[0,-10.493846153846153]],"o":[[0,10.493846153846153],[-10.493846153846153,0],[0,-10.493846153846153],[10.493846153846153,0],[0,0]],"v":[[38,19],[19,38],[0,19],[19,0],[38,19]]}],"t":60},{"s":[{"c":true,"i":[[0,0],[341.5871678599841,0],[0,341.5871678599841],[-341.5871678599841,0],[0,-341.5871678599841]],"o":[[0,341.5871678599841],[-341.5871678599841,0],[0,-341.5871678599841],[341.5871678599841,0],[0,0]],"v":[[1237,618.5],[618.5,1237],[0,618.5],[618.5,0],[1237,618.5]]}],"t":120}]}},{"ty":"st","bm":0,"hd":false,"nm":"","lc":1,"lj":1,"ml":4,"o":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[20],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[20],"t":60},{"s":[100],"t":120}]},"w":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[1],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[1],"t":60},{"s":[20],"t":120}]},"c":{"a":0,"k":[0.9295,0.1098,0.1687]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":100}}],"ind":1},{"ty":4,"nm":"Group 8232","sr":1,"st":0,"op":121.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[155,404]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":0},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":60.06},{"s":[100],"t":120}]}},"shapes":[],"ind":2},{"ty":4,"nm":"Rectangle 17364","sr":1,"st":0,"op":121.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[200,326.5]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[-207.54,1178.76],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[565.46,-310.24],"t":60},{"s":[565.46,-310.24],"t":120.12}]},"r":{"a":0,"k":30},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[100],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[100],"t":60},{"s":[0],"t":120.12}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,-110.38],[0,0],[110.38,0],[0,0],[0,110.38],[0,0],[-110.38,0],[0,0]],"o":[[0,0],[0,110.38],[0,0],[-110.38,0],[0,0],[0,-110.38],[0,0],[110.38,0]],"v":[[400,200],[400,453],[200,653],[200,653],[0,453],[0,200],[200,0],[200,0]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[0.9295,0.1098,0.1687]},"r":1,"o":{"a":0,"k":100}}],"ind":3},{"ty":4,"nm":"Symptoms Checker Bg","sr":1,"st":0,"op":121.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[215,463.5]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[215,463.5]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[430,0],[430,927],[0,927],[0,0]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[1,1,1],"t":0},{"o":{"x":0.82,"y":-0.01},"i":{"x":0.58,"y":1},"s":[1,1,1],"t":60},{"s":[0.9295,0.1098,0.1687],"t":120}]},"r":1,"o":{"a":0,"k":100}}],"ind":4}],"v":"5.7.0","fr":60,"op":120.06,"ip":0,"assets":[]}

@ -161,6 +161,9 @@ class AppAnimations {
static const String register = '$lottieBasePath/register.json';
static const String checkmark = '$lottieBasePath/checkmark.json';
static const String loadingAnimation = '$lottieBasePath/Loader.json';
static const String onboarding_1 = '$lottieBasePath/onboarding_1.json';
static const String onboarding_2 = '$lottieBasePath/onboarding_2.json';
static const String errorAnimation = '$lottieBasePath/ErrorAnimation.json';
static const String warningAnimation = '$lottieBasePath/warningAnimation.json';
static const String splashLaunching = '$lottieBasePath/splash_launching.json';
}

@ -6,9 +6,12 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart';
import 'package:hmg_patient_app_new/splash_animation_screen.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
// import 'package:hmg_patient_app_new/presentation/authantication/login.dart';
@ -16,6 +19,7 @@ import 'package:hmg_patient_app_new/presentation/home/landing_page.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart';
import 'core/cache_consts.dart';
@ -30,6 +34,8 @@ class SplashPage extends StatefulWidget {
class _SplashScreenState extends State<SplashPage> {
late AuthenticationViewModel authVm;
bool isNewDesign = false;
Future<void> initializeStuff() async {
Timer(
Duration(milliseconds: 500),
@ -41,12 +47,17 @@ class _SplashScreenState extends State<SplashPage> {
await authVm.getServicePrivilege();
Timer(Duration(seconds: 2, milliseconds: 500), () async {
LocalNotification.init(onNotificationClick: (payload) {});
if (isNewDesign) {
Navigator.of(context).pushReplacement(FadePage(page: SplashAnimationScreen()));
} else {
Navigator.of(context).pushReplacement(
FadePage(
page: LandingNavigation(),
// page: LoginScreen(),
),
);
}
});
var zoom = ZoomVideoSdk();
InitConfig initConfig = InitConfig(
@ -85,7 +96,9 @@ class _SplashScreenState extends State<SplashPage> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.whiteColor,
body: Stack(
body: isNewDesign
? Lottie.asset(AppAnimations.loadingAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.fill).center
: Stack(
alignment: Alignment.center,
children: [
Padding(

@ -0,0 +1,382 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:lottie/lottie.dart';
class SplashAnimationScreen extends StatefulWidget {
final Widget? routeWidget;
SplashAnimationScreen({super.key, this.routeWidget});
@override
_SplashAnimationScreenState createState() {
return _SplashAnimationScreenState();
}
}
class _SplashAnimationScreenState extends State<SplashAnimationScreen> with SingleTickerProviderStateMixin {
late final AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
_controller.addListener(() {
if (_controller.status == AnimationStatus.completed) {
Navigator.of(context).pushReplacement(FadePage(page: widget.routeWidget ?? LoginScreen()));
}
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.whiteColor,
body: Stack(
children: [
Lottie.asset(AppAnimations.splashLaunching, controller: _controller, onLoaded: (composition) {
_controller
..duration = composition.duration
..forward(); // Start the animation
}, repeat: false, reverse: false, frameRate: FrameRate(60), fit: BoxFit.fill)
.center,
],
),
);
}
}
// todo: do-not remove this code,as animation need to test on multiple screen sizes
class AnimatedScreen extends StatefulWidget {
const AnimatedScreen({super.key});
@override
State<AnimatedScreen> createState() => _AnimatedScreenState();
}
class _AnimatedScreenState extends State<AnimatedScreen> with TickerProviderStateMixin {
late AnimationController _moveController;
late Animation<Offset> _positionAnimation;
late AnimationController _expandController;
late Animation<double> _expandAnimation;
bool isRipple = false;
late final AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
_controller.addListener(() {
if (_controller.status == AnimationStatus.completed) {
Navigator.of(context).pushReplacement(
FadePage(
page: LoginScreen(),
),
);
}
});
// Step 1: Move circle from bottom-left to top-right
_moveController = AnimationController(vsync: this, duration: const Duration(seconds: 1));
_positionAnimation = Tween<Offset>(
begin: const Offset(-1, 1),
end: const Offset(1, -1),
).animate(
CurvedAnimation(parent: _moveController, curve: const Cubic(0.82, -0.01, 0.58, 1)),
);
// Step 2: Expand white circle from center
_expandController = AnimationController(vsync: this, duration: const Duration(milliseconds: 1000));
_expandAnimation = Tween<double>(
begin: 0.0,
end: 4.0,
).animate(CurvedAnimation(parent: _expandController, curve: Curves.easeOut));
// Trigger the animations in sequence
_moveController.forward().whenComplete(() {
setState(() {
isRipple = true;
});
_expandController.forward().whenComplete(() {
setState(() {
isRipple = false;
});
});
});
}
@override
void dispose() {
_controller.dispose();
_moveController.dispose();
_expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: AppColors.whiteColor,
body: Stack(
children: [
// Moving rotated ellipse
Lottie.asset(AppAnimations.splashLaunching, controller: _controller, onLoaded: (composition) {
_controller
..duration = composition.duration
..forward(); // Start the animation
}, repeat: false, reverse: false, frameRate: FrameRate(60), fit: BoxFit.fill)
.center,
// Lottie.asset(AppAnimations.loadingAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.fill).center,
//
// AnimatedContainer(
// duration: Duration(milliseconds: 500),
// width: screenSize.width,
// height: screenSize.height,
// color: isRipple ? AppColors.primaryRedColor : AppColors.whiteColor,
// ),
//
// AnimatedBuilder(
// animation: _moveController,
// builder: (context, child) {
// final pos = _positionAnimation.value;
// return Positioned(
// left: (screenSize.width * .75) * (pos.dx),
// top: (screenSize.height * 0.75) * (pos.dy),
// child: Transform.rotate(
// angle: -120 * 3.1415927 / 150, // convert degrees to radians
// child: Container(
// width: 400,
// height: 653,
// decoration: BoxDecoration(
// color: Color(0xffED1C2B),
// borderRadius: BorderRadius.circular(330),
// ),
// ),
// ),
// );
// },
// ),
// // Expanding white circle
// AnimatedBuilder(
// animation: _expandController,
// builder: (context, child) {
// return Center(
// child: Transform.scale(
// scale: _expandAnimation.value,
// child: Opacity(
// opacity: 1.0, //- _expandAnimation.value.clamp(0.0, 1.0),
// child: Container(
// decoration: const BoxDecoration(
// color: Colors.white,
// shape: BoxShape.circle,
// // border: Border.fromBorderSide(BorderSide(
// // width: 0,
// // color: Color(0xffED1C2B),
// // )
// )),
// ),
// // ),
// ),
// );
// },
// ),
// AnimatedBuilder(
// animation: _expandController,
// builder: (context, child) {
// final screenSize = MediaQuery.of(context).size;
// final maxDiameter =
// (screenSize.width > screenSize.height ? screenSize.width : screenSize.height) * 2;
//
// return Center(
// child: Transform.scale(
// scale: _expandAnimation.value * maxDiameter / 100, // scale up to fill screen
// child: Opacity(
// opacity: (1.0 - _expandAnimation.value).clamp(0.0, 1.0),
// child: Container(
// decoration: const BoxDecoration(
// color: Colors.white,
// shape: BoxShape.circle,
// ),
// ),
// ),
// ),
// );
// },
// ),
],
),
);
}
}
class MoveObjectDemo extends StatefulWidget {
const MoveObjectDemo({super.key});
@override
State<MoveObjectDemo> createState() => _MoveObjectDemoState();
}
class _MoveObjectDemoState extends State<MoveObjectDemo> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Alignment> _alignmentAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_alignmentAnimation = AlignmentTween(
begin: Alignment(-2.0, 2.5),
end: Alignment(2.5, -2),
).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));
_controller.forward(); // start animation
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: AnimatedBuilder(
animation: _alignmentAnimation,
builder: (context, child) {
return Align(
alignment: _alignmentAnimation.value,
child: Transform.rotate(
angle: -120 * 3.1415927 / 180,
child: Container(
width: 200,
height: 375,
decoration: BoxDecoration(
color: const Color(0xffED1C2B),
borderRadius: BorderRadius.circular(330),
),
),
),
// Transform.rotate(
// angle: -120 * 3.1415927 / 180, // convert to radians
// child: Container(
// width: 400,
// height: 653,
// decoration: BoxDecoration(
// color: const Color(0xffED1C2B),
// borderRadius: BorderRadius.circular(330),
// ),
// ),
// ),
);
},
),
);
}
}
class MoveOnClickDemo extends StatefulWidget {
const MoveOnClickDemo({super.key});
@override
State<MoveOnClickDemo> createState() => _MoveOnClickDemoState();
}
class _MoveOnClickDemoState extends State<MoveOnClickDemo> with TickerProviderStateMixin {
late AnimationController _controller;
late Animation<Alignment> _alignmentAnimation;
@override
void initState() {
super.initState();
init();
}
init() {
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1000), // Figma duration
);
_alignmentAnimation = AlignmentTween(
// begin: Alignment(-10.0, 5),
// end: Alignment(5, -2),
begin: Alignment.bottomLeft,
end: Alignment.topRight,
).animate(CurvedAnimation(
parent: _controller,
curve: const Cubic(0.82, -0.01, 0.58, 1), // Figma cubic-bezier
));
_animate();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _animate() {
if (_controller.isCompleted) {
_controller.reverse();
} else {
_controller.forward();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: _animate, // trigger on click
onDoubleTap: () {
_controller.dispose();
init();
},
child: AnimatedBuilder(
animation: _alignmentAnimation,
builder: (context, child) {
print(_alignmentAnimation.value);
return Align(
alignment: _alignmentAnimation.value,
child: Transform.rotate(
angle: -120 * 3.1415927 / 145, // -120 deg
child: Container(
width: 100,
height: 150,
decoration: BoxDecoration(
color: const Color(0xffED1C2B),
borderRadius: BorderRadius.circular(330),
),
),
),
);
},
),
),
);
}
}
Loading…
Cancel
Save