4 changed files with 176 additions and 3 deletions
-
8lib/common_ui/resources/my_text_style.dart
-
40lib/features/intro/presentation/ui/intro_page.dart
-
129lib/features/intro/presentation/ui/widgets/intro_loading_widget.dart
-
2lib/features/level/presentation/ui/widgets/level_widget.dart
@ -1,10 +1,48 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; |
|||
import 'package:hadi_hoda_flutter/features/intro/presentation/ui/widgets/intro_loading_widget.dart'; |
|||
|
|||
class IntroPage extends StatelessWidget { |
|||
const IntroPage({super.key}); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return const Scaffold(); |
|||
return Scaffold( |
|||
body: Container( |
|||
height: context.heightScreen, |
|||
width: context.widthScreen, |
|||
decoration: BoxDecoration( |
|||
gradient: LinearGradient( |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
colors: [Color(0XFF00154C), Color(0XFF150532)], |
|||
), |
|||
image: DecorationImage( |
|||
image: AssetImage(MyAssets.pattern), |
|||
scale: 3, |
|||
repeat: ImageRepeat.repeat, |
|||
colorFilter: ColorFilter.mode( |
|||
Colors.white.withValues(alpha: 0.2), |
|||
BlendMode.srcIn, |
|||
), |
|||
), |
|||
), |
|||
child: Stack( |
|||
alignment: Alignment.center, |
|||
children: [_image(), _loading(context)], |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
MyImage _image() => MyImage(image: MyAssets.hadiHoda, size: 200); |
|||
|
|||
Positioned _loading(BuildContext context) { |
|||
return Positioned( |
|||
bottom: MediaQuery.viewPaddingOf(context).bottom, |
|||
child: IntroLoadingWidget(percent: 80), |
|||
); |
|||
} |
|||
} |
@ -0,0 +1,129 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; |
|||
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; |
|||
|
|||
|
|||
class IntroLoadingWidget extends StatelessWidget { |
|||
const IntroLoadingWidget({ |
|||
super.key, |
|||
this.percent, |
|||
}); |
|||
|
|||
final double? percent; |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return ClipPath( |
|||
clipper: BubbleClip(), |
|||
child: Container( |
|||
width: 300, |
|||
height: 60, |
|||
padding: EdgeInsets.symmetric( |
|||
vertical: MySpaces.s4, |
|||
horizontal: MySpaces.s2, |
|||
), |
|||
decoration: const BoxDecoration( |
|||
gradient: LinearGradient( |
|||
begin: Alignment(0, 1), // bottom |
|||
end: Alignment(0, -1), // top |
|||
colors: [ |
|||
Color(0xFFCADCFF), // #CADCFF |
|||
Colors.white, // #FFFFFF |
|||
], |
|||
), |
|||
), |
|||
child: Row( |
|||
children: [ |
|||
Expanded( |
|||
flex: 85, |
|||
child: ClipPath( |
|||
clipper: BubbleClip(), |
|||
child: AnimatedContainer( |
|||
duration: const Duration(milliseconds: 300), |
|||
padding: EdgeInsetsDirectional.only( |
|||
end: 260 - ((percent ?? 0) * 260 / 100), |
|||
), |
|||
decoration: BoxDecoration( |
|||
color: Color(0xFF1F59BD).withValues(alpha: 0.25), |
|||
), |
|||
child: ClipPath( |
|||
clipper: BubbleClip(), |
|||
child: Container( |
|||
decoration: BoxDecoration( |
|||
gradient: RadialGradient( |
|||
radius: 2, |
|||
colors: [ |
|||
Color(0xFFFFBD00), // #CADCFF |
|||
Color(0xFFFF772C), // #CADCFF |
|||
], |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
Expanded( |
|||
flex: 15, |
|||
child: Center( |
|||
child: Text( |
|||
'${percent?.toInt() ?? 0}%', |
|||
style: MyTextStyle.normal17.copyWith( |
|||
color: Color(0XFF6E83A8), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
|
|||
class BubbleClip extends CustomClipper<Path> { |
|||
@override |
|||
Path getClip(Size size) { |
|||
// Original SVG viewBox: 334 x 60 |
|||
const double w0 = 334.0; |
|||
const double h0 = 60.0; |
|||
final sx = size.width / w0; |
|||
final sy = size.height / h0; |
|||
|
|||
// SVG path: |
|||
// M9.82057 10.3597 |
|||
// C -1.70838 17.1589 -3.47995 44.4301 6.60447 53.1719 |
|||
// C 16.0075 61.291 305.076 61.9385 323.201 53.4956 |
|||
// C 341.326 45.0527 332.116 8.04571 324.829 5.7273 |
|||
// C 307.985 -2.06805 28.6539 -0.77294 9.82057 10.3597 |
|||
// Z |
|||
final p = Path() |
|||
..moveTo(9.82057 * sx, 10.3597 * sy) |
|||
..cubicTo( |
|||
-1.70838 * sx, 17.1589 * sy, |
|||
-3.47995 * sx, 44.4301 * sy, |
|||
6.60447 * sx, 53.1719 * sy, |
|||
) |
|||
..cubicTo( |
|||
16.0075 * sx, 61.291 * sy, |
|||
305.076 * sx, 61.9385 * sy, |
|||
323.201 * sx, 53.4956 * sy, |
|||
) |
|||
..cubicTo( |
|||
341.326 * sx, 45.0527 * sy, |
|||
332.116 * sx, 8.04571 * sy, |
|||
324.829 * sx, 5.7273 * sy, |
|||
) |
|||
..cubicTo( |
|||
307.985 * sx, -2.06805 * sy, |
|||
28.6539 * sx, -0.77294 * sy, |
|||
9.82057 * sx, 10.3597 * sy, |
|||
) |
|||
..close(); |
|||
|
|||
return p; |
|||
} |
|||
|
|||
@override |
|||
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false; |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue