22222
This commit is contained in:
@@ -7,66 +7,75 @@ class AboutScreen extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: AppBackground(
|
||||
child: Column(
|
||||
children: [
|
||||
/// -------------------- SETTINGS BAR --------------------
|
||||
SettingsBar(
|
||||
selectedIndex: 0,
|
||||
onTap: (_) {},
|
||||
showBackButton: true,
|
||||
onBackTap: () => Navigator.pop(context),
|
||||
iconPaths: const [],
|
||||
),
|
||||
return Scaffold(
|
||||
body: AppBackground(
|
||||
child: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
/// -------------------- SETTINGS BAR --------------------
|
||||
SettingsBar(
|
||||
selectedIndex: 0,
|
||||
onTap: (_) {},
|
||||
showBackButton: true,
|
||||
onBackTap: () => Navigator.pop(context),
|
||||
iconPaths: const [],
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
/// -------------------- CENTER CONTENT --------------------
|
||||
///
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
"عن الشركة",
|
||||
style: TextStyle(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
/// -------------------- CENTER CONTENT --------------------
|
||||
///
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 24.0,
|
||||
vertical: 10,
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
"عن الشركة",
|
||||
style: TextStyle(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Container(
|
||||
width: 200,
|
||||
height: 1,
|
||||
color: Color(0x8732C599),
|
||||
),
|
||||
|
||||
const SizedBox(height: 14),
|
||||
|
||||
const Text(
|
||||
"نص",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: Colors.white70,
|
||||
Container(
|
||||
width: 200,
|
||||
height: 1,
|
||||
color: const Color(0x8732C599),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
const SizedBox(height: 14),
|
||||
|
||||
const Text(
|
||||
"شركة كودا ذ.م.م هي شركة عراقية رائدة تقدم حلولاً متميزة في البرمجيات المخصصة والتطبيقات وإدارة الخوادم والمواقع، ومنظومات الاتصال وخدمات الأمن السيبراني. تأسست عام 2008 ولديها عقود واتفاقيات عديدة مع مؤسسات حكومية عراقية والقطاع الخاص.\n\nوسعت الشركة شراكاتها مع وكالات عالمية مثل CODACS الأمريكية و Laipac الكندية و Teltonika اللتوانية وWolf Team الصينية وLibelium الإسبانية وOdoo العالمية وغيرها. مما أتاح لها تقديم أحدث التقنيات والمنتجات المبتكرة لعملائها.\n\nتوفر كودا حلولاً برمجية مخصصة للمؤسسات الكبيرة والدوائر الحكومية، مما يسهم في تبسيط الإجراءات وتقديم الخدمات للمواطنين بشكل إلكتروني وفعال.\n\nكما تقدم كودا مجموعة واسعة من المنتجات والخدمات الحديثة، بما في ذلك الشاشات الإعلانية، والبوابات الذكية، والمواقف الذكية، والأقفال، والمباني الذكية، وأجهزة الكشك (الخدمة الإلكترونية الذاتية)، وأجهزة محمولة تخصصية، وحساسات، وأجهزة نداء واستغاثة.\n\nبفضل هذه المنتجات والخدمات المبتكرة، تعزز كودا مكانتها الرائدة في السوق المحلي والإقليمي، وتساهم في تطوير التكنولوجيا وتعزيز جودة الحياة في العراق .",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: Colors.white70,
|
||||
height:
|
||||
1.5, // Added line height for better readability
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20), // Bottom padding
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'package:coda_project/screens/notifications_screen.dart';
|
||||
import 'package:coda_project/screens/user_settings_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import '../widgets/login_animation.dart';
|
||||
import '../widgets/settings_bar.dart';
|
||||
|
||||
class AttendanceScreen extends StatelessWidget {
|
||||
@@ -17,45 +16,43 @@ class AttendanceScreen extends StatelessWidget {
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Stack(
|
||||
children: [
|
||||
SizedBox(height: MediaQuery.of(context).size.height
|
||||
|
||||
),
|
||||
SizedBox(height: MediaQuery.of(context).size.height),
|
||||
|
||||
/// ------------------------------
|
||||
/// SETTINGS BAR (STATIC)
|
||||
/// ------------------------------
|
||||
SafeArea(
|
||||
child:SettingsBar(
|
||||
selectedIndex: 0,
|
||||
showBackButton: false,
|
||||
iconPaths: [
|
||||
'assets/images/user.svg',
|
||||
'assets/images/ball.svg',
|
||||
],
|
||||
onTap: (index) {
|
||||
if (index == 0) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => UserSettingsScreen(),
|
||||
),
|
||||
);
|
||||
} else if (index == 1) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => NotificationsScreen(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
child: SettingsBar(
|
||||
selectedIndex: 0,
|
||||
showBackButton: false,
|
||||
iconPaths: ['assets/images/user.svg', 'assets/images/ball.svg'],
|
||||
onTap: (index) {
|
||||
if (index == 0) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => UserSettingsScreen(),
|
||||
),
|
||||
);
|
||||
} else if (index == 1) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => NotificationsScreen(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
/// ------------------------------
|
||||
/// GREETING TEXT
|
||||
/// ------------------------------
|
||||
Positioned(
|
||||
top: screenHeight * 0.14, // moved down because settings bar now exists
|
||||
top:
|
||||
screenHeight *
|
||||
0.14, // moved down because settings bar now exists
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
@@ -65,9 +62,7 @@ class AttendanceScreen extends StatelessWidget {
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(color: Color(0x42000000), blurRadius: 6),
|
||||
],
|
||||
shadows: [Shadow(color: Color(0x42000000), blurRadius: 6)],
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -77,7 +72,9 @@ class AttendanceScreen extends StatelessWidget {
|
||||
/// MAIN CARD AREA
|
||||
/// ------------------------------
|
||||
Positioned(
|
||||
top: screenHeight * 0.2, // pushed down because of settings bar + greeting
|
||||
top:
|
||||
screenHeight *
|
||||
0.2, // pushed down because of settings bar + greeting
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
@@ -110,7 +107,7 @@ class AttendanceScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: screenHeight * 0.5,
|
||||
height: screenHeight * 0.5,
|
||||
width: screenWidth * 0.7,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0x92757575),
|
||||
@@ -139,13 +136,12 @@ class AttendanceScreen extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
child: _FingerButton(
|
||||
icon: "assets/images/login.svg",
|
||||
icon: "assets/images/faceLogin.svg",
|
||||
label: "تسجيل الدخول",
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => OvalCameraCapturePage(
|
||||
),
|
||||
builder: (_) => OvalCameraCapturePage(isLogin: true),
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -180,15 +176,12 @@ class AttendanceScreen extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
child: _FingerButton(
|
||||
icon: "assets/images/logout.svg",
|
||||
icon: "assets/images/faceLogout.svg",
|
||||
label: "تسجيل خروج",
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => LoginAnimationScreen(
|
||||
isLogin: false,
|
||||
isSuccess: true,
|
||||
),
|
||||
builder: (_) => OvalCameraCapturePage(isLogin: false),
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -258,7 +251,7 @@ class _FingerButton extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(icon, width: 62, height: 62),
|
||||
SvgPicture.asset(icon, width: 75, height: 75),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
label,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import 'package:camera/camera.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'dart:async';
|
||||
|
||||
class OvalCameraCapturePage extends StatefulWidget {
|
||||
const OvalCameraCapturePage({super.key});
|
||||
final bool isLogin;
|
||||
const OvalCameraCapturePage({super.key, this.isLogin = true});
|
||||
|
||||
@override
|
||||
State<OvalCameraCapturePage> createState() => _OvalCameraCapturePageState();
|
||||
@@ -12,6 +15,8 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
|
||||
CameraController? _cameraController;
|
||||
bool _isCameraInitialized = false;
|
||||
String? _errorMessage;
|
||||
bool _isSuccess = false;
|
||||
Timer? _timer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -27,7 +32,7 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
|
||||
|
||||
// Get available cameras
|
||||
final cameras = await availableCameras();
|
||||
|
||||
|
||||
// Check if cameras list is available
|
||||
if (cameras.isEmpty) {
|
||||
setState(() {
|
||||
@@ -64,16 +69,31 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
|
||||
);
|
||||
|
||||
await _cameraController!.initialize();
|
||||
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
|
||||
setState(() {
|
||||
_isCameraInitialized = true;
|
||||
_errorMessage = null;
|
||||
});
|
||||
|
||||
_timer = Timer(const Duration(seconds: 3), () {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isSuccess = true;
|
||||
});
|
||||
|
||||
// Auto-close after 2 seconds
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
|
||||
|
||||
setState(() {
|
||||
_errorMessage = "خطأ في تهيئة الكاميرا: $e";
|
||||
_isCameraInitialized = false;
|
||||
@@ -82,11 +102,10 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_cameraController?.dispose();
|
||||
_timer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -95,88 +114,151 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
|
||||
return Scaffold(
|
||||
backgroundColor: Color(0xff000000),
|
||||
|
||||
body: _errorMessage != null
|
||||
? Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.camera_alt_outlined,
|
||||
size: 64,
|
||||
color: Colors.white70,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
_errorMessage!,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
body:
|
||||
_errorMessage != null
|
||||
? Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.camera_alt_outlined,
|
||||
size: 64,
|
||||
color: Colors.white70,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
ElevatedButton(
|
||||
onPressed: _initializeCamera,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xffE8001A),
|
||||
foregroundColor: Colors.white,
|
||||
padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
_errorMessage!,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
child: Text("إعادة المحاولة"),
|
||||
),
|
||||
],
|
||||
SizedBox(height: 24),
|
||||
ElevatedButton(
|
||||
onPressed: _initializeCamera,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xffE8001A),
|
||||
foregroundColor: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
child: Text("إعادة المحاولة"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: _isCameraInitialized && _cameraController != null
|
||||
)
|
||||
: _isCameraInitialized && _cameraController != null
|
||||
? Stack(
|
||||
children: [
|
||||
SizedBox(height: MediaQuery.of(context).size.height ),
|
||||
// Camera Preview
|
||||
Positioned(
|
||||
child: Center(child: CameraPreview(_cameraController!)),
|
||||
),
|
||||
// Oval overlay with dimmed background
|
||||
Positioned.fill(
|
||||
child: CustomPaint(
|
||||
painter: _OvalOverlayPainter(),
|
||||
children: [
|
||||
SizedBox(height: MediaQuery.of(context).size.height),
|
||||
|
||||
// Camera Preview
|
||||
Positioned(
|
||||
child: Center(child: CameraPreview(_cameraController!)),
|
||||
),
|
||||
// Oval overlay with dimmed background
|
||||
Positioned.fill(
|
||||
child: CustomPaint(painter: _OvalOverlayPainter()),
|
||||
),
|
||||
|
||||
// Top Text
|
||||
Positioned(
|
||||
top: 100,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: Text(
|
||||
widget.isLogin ? "تسجيل الدخول" : "تسجيل خروج",
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily:
|
||||
'Cairo', // Assuming Cairo font based on Arabic text
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// // Capture button
|
||||
// Positioned(
|
||||
// bottom: 60,
|
||||
// left: 0,
|
||||
// right: 0,
|
||||
// child: Center(
|
||||
// child: GestureDetector(
|
||||
// onTap: (){},
|
||||
// child: Container(
|
||||
// width: 72,
|
||||
// height: 72,
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// color: Colors.white,
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: Colors.black26,
|
||||
// blurRadius: 8,
|
||||
// offset: Offset(0, 4),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: Icon(Icons.camera_alt, color: Color(0xffE8001A), size: 36),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
)
|
||||
: Center(child: CircularProgressIndicator(color: Color(0xffE8001A))),
|
||||
),
|
||||
|
||||
// Bottom Text and Logo
|
||||
Positioned(
|
||||
bottom: 80,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
_isSuccess
|
||||
? (widget.isLogin
|
||||
? "تم تسجيل دخولك بنجاح"
|
||||
: "تم تسجيل خروجك بنجاح")
|
||||
: (widget.isLogin
|
||||
? "يتم تسجيل الدخول ..."
|
||||
: "يتم تسجيل الخروج ..."),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
// Logo
|
||||
SizedBox(
|
||||
height: _isSuccess ? 80 : 60,
|
||||
width: _isSuccess ? 80 : 60,
|
||||
child: SvgPicture.asset(
|
||||
_isSuccess
|
||||
? 'assets/images/logSuccess.svg'
|
||||
: 'assets/images/logLoading.svg',
|
||||
// ignore: deprecated_member_use
|
||||
color: Colors.white,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// // Capture button
|
||||
// Positioned(
|
||||
// bottom: 60,
|
||||
// left: 0,
|
||||
// right: 0,
|
||||
// child: Center(
|
||||
// child: GestureDetector(
|
||||
// onTap: (){},
|
||||
// child: Container(
|
||||
// width: 72,
|
||||
// height: 72,
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// color: Colors.white,
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: Colors.black26,
|
||||
// blurRadius: 8,
|
||||
// offset: Offset(0, 4),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: Icon(Icons.camera_alt, color: Color(0xffE8001A), size: 36),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
)
|
||||
: Center(
|
||||
child: CircularProgressIndicator(color: Color(0xffE8001A)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -194,11 +276,16 @@ class _OvalOverlayPainter extends CustomPainter {
|
||||
);
|
||||
|
||||
// Create a path for the whole screen
|
||||
final screenPath = Path()..addRect(Rect.fromLTWH(0, 0, size.width, size.height));
|
||||
final screenPath =
|
||||
Path()..addRect(Rect.fromLTWH(0, 0, size.width, size.height));
|
||||
// Create a path for the oval
|
||||
final ovalPath = Path()..addOval(ovalRect);
|
||||
// Subtract the oval from the screen path
|
||||
final overlayPath = Path.combine(PathOperation.difference, screenPath, ovalPath);
|
||||
final overlayPath = Path.combine(
|
||||
PathOperation.difference,
|
||||
screenPath,
|
||||
ovalPath,
|
||||
);
|
||||
|
||||
// Draw the dimmed area outside the oval with gradient
|
||||
final gradient = LinearGradient(
|
||||
@@ -209,11 +296,12 @@ class _OvalOverlayPainter extends CustomPainter {
|
||||
Color.fromARGB(255, 0, 20, 15), // bottom deep green
|
||||
],
|
||||
);
|
||||
final paint = Paint()
|
||||
..shader = gradient.createShader(
|
||||
Rect.fromLTWH(0, 0, size.width, size.height),
|
||||
)
|
||||
..style = PaintingStyle.fill;
|
||||
final paint =
|
||||
Paint()
|
||||
..shader = gradient.createShader(
|
||||
Rect.fromLTWH(0, 0, size.width, size.height),
|
||||
)
|
||||
..style = PaintingStyle.fill;
|
||||
canvas.drawPath(overlayPath, paint);
|
||||
|
||||
// Draw glowing circles effect (like AppBackground) - drawn after overlay
|
||||
@@ -222,9 +310,10 @@ class _OvalOverlayPainter extends CustomPainter {
|
||||
final topCircleRadius = 150.0;
|
||||
// Draw multiple circles with different opacities for spread effect (spreadRadius: 160)
|
||||
for (int i = 0; i < 5; i++) {
|
||||
final spreadPaint = Paint()
|
||||
..color = Color.fromARGB(69 ~/ (i + 1), 62, 254, 190)
|
||||
..maskFilter = MaskFilter.blur(BlurStyle.normal, 140 - (i * 20));
|
||||
final spreadPaint =
|
||||
Paint()
|
||||
..color = Color.fromARGB(69 ~/ (i + 1), 62, 254, 190)
|
||||
..maskFilter = MaskFilter.blur(BlurStyle.normal, 140 - (i * 20));
|
||||
canvas.drawCircle(
|
||||
topCircleCenter,
|
||||
topCircleRadius + (i * 30),
|
||||
@@ -237,9 +326,10 @@ class _OvalOverlayPainter extends CustomPainter {
|
||||
final bottomCircleRadius = 160.0;
|
||||
// Draw multiple circles with different opacities for spread effect (spreadRadius: 60)
|
||||
for (int i = 0; i < 5; i++) {
|
||||
final spreadPaint = Paint()
|
||||
..color = Color.fromARGB(83 ~/ (i + 1), 62, 254, 190)
|
||||
..maskFilter = MaskFilter.blur(BlurStyle.normal, 180 - (i * 25));
|
||||
final spreadPaint =
|
||||
Paint()
|
||||
..color = Color.fromARGB(83 ~/ (i + 1), 62, 254, 190)
|
||||
..maskFilter = MaskFilter.blur(BlurStyle.normal, 180 - (i * 25));
|
||||
canvas.drawCircle(
|
||||
bottomCircleCenter,
|
||||
bottomCircleRadius + (i * 40),
|
||||
@@ -248,13 +338,14 @@ class _OvalOverlayPainter extends CustomPainter {
|
||||
}
|
||||
|
||||
// Draw oval border
|
||||
final borderPaint = Paint()
|
||||
..color = Colors.greenAccent
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 4;
|
||||
final borderPaint =
|
||||
Paint()
|
||||
..color = Colors.greenAccent
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 4;
|
||||
canvas.drawOval(ovalRect, borderPaint);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user