update: improve onbaording looks
This commit is contained in:
parent
71c7e498b6
commit
cbcb250be3
|
@ -9,6 +9,6 @@ export 'package:rijig_mobile/features/auth/presentation/screen/inputpin_screen.d
|
||||||
export 'package:rijig_mobile/features/auth/presentation/screen/login_screen.dart';
|
export 'package:rijig_mobile/features/auth/presentation/screen/login_screen.dart';
|
||||||
export 'package:rijig_mobile/features/auth/presentation/screen/otp_screen.dart';
|
export 'package:rijig_mobile/features/auth/presentation/screen/otp_screen.dart';
|
||||||
export 'package:rijig_mobile/features/auth/presentation/screen/verifpin_screen.dart';
|
export 'package:rijig_mobile/features/auth/presentation/screen/verifpin_screen.dart';
|
||||||
export 'package:rijig_mobile/features/launch/onboardingpage_screen.dart';
|
export 'package:rijig_mobile/features/launch/screen/onboardingpage_screen.dart';
|
||||||
export 'package:rijig_mobile/features/launch/splash_screen.dart';
|
export 'package:rijig_mobile/features/launch/screen/splash_screen.dart';
|
||||||
export 'package:rijig_mobile/features/home/presentation/components/about_detail_comp.dart';
|
export 'package:rijig_mobile/features/home/presentation/components/about_detail_comp.dart';
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:carousel_slider/carousel_slider.dart';
|
import 'package:carousel_slider/carousel_slider.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:rijig_mobile/core/router.dart';
|
import 'package:rijig_mobile/core/router.dart';
|
||||||
|
import 'package:rijig_mobile/core/utils/guide.dart';
|
||||||
import 'package:rijig_mobile/features/home/presentation/viewmodel/about_vmod.dart';
|
import 'package:rijig_mobile/features/home/presentation/viewmodel/about_vmod.dart';
|
||||||
import 'package:rijig_mobile/features/requestpick/presentation/screen/requestpickup_screen.dart';
|
import 'package:rijig_mobile/features/requestpick/presentation/screen/requestpickup_screen.dart';
|
||||||
|
|
||||||
|
@ -83,11 +84,11 @@ class AboutComponentState extends State<AboutComponent> {
|
||||||
horizontal: 12,
|
horizontal: 12,
|
||||||
vertical: 6,
|
vertical: 6,
|
||||||
),
|
),
|
||||||
color: Colors.black.withOpacity(0.5),
|
color: blackNavyColor.withValues(alpha: 0.5),
|
||||||
child: Text(
|
child: Text(
|
||||||
imageData["title"],
|
imageData["title"],
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: whiteColor,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:rijig_mobile/features/launch/model/onboard_model.dart';
|
||||||
|
|
||||||
|
class OnboardingView extends StatelessWidget {
|
||||||
|
const OnboardingView({super.key, required this.data});
|
||||||
|
|
||||||
|
final OnboardingModel data;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: MediaQuery.of(context).size.width,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 40.0),
|
||||||
|
child: Image.network(data.imagePath, fit: BoxFit.contain),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(15),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
data.headline,
|
||||||
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 15.0),
|
||||||
|
child: Text(
|
||||||
|
data.description,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Gap(100),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import 'package:rijig_mobile/features/launch/model/onboard_model.dart';
|
||||||
|
|
||||||
|
class OnboardingData {
|
||||||
|
static List<OnboardingModel> items = [
|
||||||
|
OnboardingModel(
|
||||||
|
imagePath: "https://i.imgur.com/X2G11k0.png",
|
||||||
|
headline: 'Browse all the category',
|
||||||
|
description:
|
||||||
|
'In aliquip aute exercitation ut et nisi ut mollit. Deserunt dolor elit pariatur aute .',
|
||||||
|
),
|
||||||
|
OnboardingModel(
|
||||||
|
imagePath: "https://i.imgur.com/X2G11k0.png",
|
||||||
|
headline: 'Amazing Discounts & Offers',
|
||||||
|
description:
|
||||||
|
'In aliquip aute exercitation ut et nisi ut mollit. Deserunt dolor elit pariatur aute .',
|
||||||
|
),
|
||||||
|
OnboardingModel(
|
||||||
|
imagePath: "https://i.imgur.com/X2G11k0.png",
|
||||||
|
headline: 'Delivery in 30 Min',
|
||||||
|
description:
|
||||||
|
'In aliquip aute exercitation ut et nisi ut mollit. Deserunt dolor elit pariatur aute .',
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
class OnboardingModel {
|
||||||
|
String imagePath;
|
||||||
|
String headline;
|
||||||
|
String description;
|
||||||
|
OnboardingModel({
|
||||||
|
required this.imagePath,
|
||||||
|
required this.headline,
|
||||||
|
required this.description,
|
||||||
|
});
|
||||||
|
|
||||||
|
OnboardingModel copyWith({
|
||||||
|
String? imagePath,
|
||||||
|
String? headline,
|
||||||
|
String? description,
|
||||||
|
}) {
|
||||||
|
return OnboardingModel(
|
||||||
|
imagePath: imagePath ?? this.imagePath,
|
||||||
|
headline: headline ?? this.headline,
|
||||||
|
description: description ?? this.description,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'imagePath': imagePath,
|
||||||
|
'headline': headline,
|
||||||
|
'description': description,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory OnboardingModel.fromMap(Map<String, dynamic> map) {
|
||||||
|
return OnboardingModel(
|
||||||
|
imagePath: map['imagePath'] ?? '',
|
||||||
|
headline: map['headline'] ?? '',
|
||||||
|
description: map['description'] ?? '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toJson() => json.encode(toMap());
|
||||||
|
|
||||||
|
factory OnboardingModel.fromJson(String source) =>
|
||||||
|
OnboardingModel.fromMap(json.decode(source));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'OnboardingData(imagePath: $imagePath, headline: $headline, description: $description)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is OnboardingModel &&
|
||||||
|
other.imagePath == imagePath &&
|
||||||
|
other.headline == headline &&
|
||||||
|
other.description == description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
imagePath.hashCode ^ headline.hashCode ^ description.hashCode;
|
||||||
|
}
|
|
@ -1,137 +0,0 @@
|
||||||
import 'package:concentric_transition/concentric_transition.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:rijig_mobile/core/utils/guide.dart';
|
|
||||||
import 'package:rijig_mobile/core/router.dart';
|
|
||||||
|
|
||||||
final pages = [
|
|
||||||
const PageData(
|
|
||||||
icon: Icons.food_bank_outlined,
|
|
||||||
title: "Search for your favourite food",
|
|
||||||
bgColor: Color(0xff3b1791),
|
|
||||||
textColor: Colors.white,
|
|
||||||
),
|
|
||||||
const PageData(
|
|
||||||
icon: Icons.shopping_bag_outlined,
|
|
||||||
title: "Add it to cart",
|
|
||||||
bgColor: Color(0xfffab800),
|
|
||||||
textColor: Color(0xff3b1790),
|
|
||||||
),
|
|
||||||
const PageData(
|
|
||||||
icon: Icons.delivery_dining,
|
|
||||||
title: "Order and wait",
|
|
||||||
bgColor: Color(0xffffffff),
|
|
||||||
textColor: Color(0xff3b1790),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
class OnboardingPageScreen extends StatefulWidget {
|
|
||||||
const OnboardingPageScreen({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
OnboardingPageScreenState createState() => OnboardingPageScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class OnboardingPageScreenState extends State<OnboardingPageScreen> {
|
|
||||||
final PageController _controller = PageController();
|
|
||||||
int _currentIndex = 0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_controller.addListener(() {
|
|
||||||
setState(() {
|
|
||||||
_currentIndex = _controller.page!.round();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
|
||||||
return Scaffold(
|
|
||||||
body: ConcentricPageView(
|
|
||||||
colors: pages.map((p) => p.bgColor).toList(),
|
|
||||||
pageController: _controller,
|
|
||||||
radius: screenWidth * 0.1,
|
|
||||||
nextButtonBuilder: (context) {
|
|
||||||
if (_currentIndex == pages.length - 1) {
|
|
||||||
return InkWell(
|
|
||||||
onTap: () => router.go('/login'),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
"Go to Login",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: screenWidth * 0.04,
|
|
||||||
color: whiteColor,
|
|
||||||
),
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 3),
|
|
||||||
child: Icon(Icons.navigate_next, size: screenWidth * 0.08),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
itemCount: pages.length,
|
|
||||||
scaleFactor: 2,
|
|
||||||
duration: Duration(milliseconds: 500),
|
|
||||||
itemBuilder: (index) {
|
|
||||||
final page = pages[index];
|
|
||||||
return SafeArea(child: _Page(page: page, index: index));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PageData {
|
|
||||||
final String? title;
|
|
||||||
final IconData? icon;
|
|
||||||
final Color bgColor;
|
|
||||||
final Color textColor;
|
|
||||||
|
|
||||||
const PageData({
|
|
||||||
this.title,
|
|
||||||
this.icon,
|
|
||||||
this.bgColor = Colors.white,
|
|
||||||
this.textColor = Colors.black,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class _Page extends StatelessWidget {
|
|
||||||
final PageData page;
|
|
||||||
final int index;
|
|
||||||
|
|
||||||
const _Page({required this.page, required this.index});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final screenHeight = MediaQuery.of(context).size.height;
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
margin: const EdgeInsets.all(16.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: page.textColor,
|
|
||||||
),
|
|
||||||
child: Icon(page.icon, size: screenHeight * 0.1, color: page.bgColor),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
page.title ?? "",
|
|
||||||
style: TextStyle(
|
|
||||||
color: page.textColor,
|
|
||||||
fontSize: screenHeight * 0.035,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import 'package:concentric_transition/concentric_transition.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:rijig_mobile/core/router.dart';
|
||||||
|
import 'package:rijig_mobile/core/utils/guide.dart';
|
||||||
|
import 'package:rijig_mobile/features/launch/components/onboarding_comp.dart';
|
||||||
|
import 'package:rijig_mobile/features/launch/model/onboard_data.dart';
|
||||||
|
|
||||||
|
class OnboardingPageScreen extends StatefulWidget {
|
||||||
|
const OnboardingPageScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
OnboardingPageScreenState createState() => OnboardingPageScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class OnboardingPageScreenState extends State<OnboardingPageScreen> {
|
||||||
|
final PageController _controller = PageController();
|
||||||
|
int _currentIndex = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
_currentIndex = _controller.page!.round();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
body: ConcentricPageView(
|
||||||
|
colors: [
|
||||||
|
_currentIndex == 0 ? whiteColor : primaryColor,
|
||||||
|
_currentIndex == 1 ? whiteColor : primaryColor,
|
||||||
|
_currentIndex == 2 ? whiteColor : primaryColor,
|
||||||
|
],
|
||||||
|
pageController: _controller,
|
||||||
|
radius: screenWidth * 0.1,
|
||||||
|
nextButtonBuilder: (context) {
|
||||||
|
if (_currentIndex == OnboardingData.items.length - 1) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () => router.go('/login'),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
"Go to Login",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: screenWidth * 0.04,
|
||||||
|
color: whiteColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 3),
|
||||||
|
child: Icon(Icons.navigate_next, size: screenWidth * 0.08),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: OnboardingData.items.length,
|
||||||
|
scaleFactor: 2,
|
||||||
|
duration: Duration(milliseconds: 500),
|
||||||
|
itemBuilder: (index) {
|
||||||
|
final page = OnboardingData.items[index];
|
||||||
|
return SafeArea(child: OnboardingView(data: page));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,12 +6,13 @@ class PaymentItem extends StatelessWidget {
|
||||||
final IconData iconData;
|
final IconData iconData;
|
||||||
final String amount;
|
final String amount;
|
||||||
|
|
||||||
const PaymentItem(
|
const PaymentItem({
|
||||||
{super.key,
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
this.category,
|
this.category,
|
||||||
required this.iconData,
|
required this.iconData,
|
||||||
required this.amount});
|
required this.amount,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -19,20 +20,23 @@ class PaymentItem extends StatelessWidget {
|
||||||
height: 100,
|
height: 100,
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||||
color: const Color(0xFF2c3135),
|
color: const Color(0xFF2c3135),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.white.withOpacity(0.05),
|
color: Colors.white.withValues(alpha: 0.05),
|
||||||
offset: const Offset(-10, -10),
|
offset: const Offset(-10, -10),
|
||||||
spreadRadius: 0,
|
spreadRadius: 0,
|
||||||
blurRadius: 10),
|
blurRadius: 10,
|
||||||
BoxShadow(
|
),
|
||||||
color: Colors.black87.withOpacity(0.3),
|
BoxShadow(
|
||||||
offset: const Offset(10, 10),
|
color: Colors.black87.withValues(alpha: 0.3),
|
||||||
spreadRadius: 0,
|
offset: const Offset(10, 10),
|
||||||
blurRadius: 10)
|
spreadRadius: 0,
|
||||||
]),
|
blurRadius: 10,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
@ -43,46 +47,46 @@ class PaymentItem extends StatelessWidget {
|
||||||
outerShadow: true,
|
outerShadow: true,
|
||||||
backgroundColor: const Color(0xFF2c3135),
|
backgroundColor: const Color(0xFF2c3135),
|
||||||
shadowColor: Colors.black87,
|
shadowColor: Colors.black87,
|
||||||
highlightColor: Colors.white.withOpacity(0.05),
|
highlightColor: Colors.white.withValues(alpha: 0.05),
|
||||||
child: Icon(
|
child: Icon(iconData, size: 28, color: Colors.white),
|
||||||
iconData,
|
|
||||||
size: 28,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(width: 16),
|
||||||
width: 16,
|
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w600),
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
),
|
||||||
height: 4,
|
const SizedBox(height: 4),
|
||||||
),
|
(category == null)
|
||||||
(category == null)
|
? const SizedBox.shrink()
|
||||||
? const SizedBox.shrink()
|
: Text(
|
||||||
: Text(category!,
|
category!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.yellow.shade200.withOpacity(0.7),
|
color: Colors.yellow.shade200.withValues(alpha: 0.7),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w600))
|
fontWeight: FontWeight.w600,
|
||||||
],
|
),
|
||||||
)),
|
),
|
||||||
Text(amount,
|
],
|
||||||
style: const TextStyle(
|
),
|
||||||
color: Colors.white,
|
),
|
||||||
fontSize: 18,
|
Text(
|
||||||
fontWeight: FontWeight.w600))
|
amount,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -97,55 +101,65 @@ class NeumorphicCircle extends StatelessWidget {
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
|
|
||||||
const NeumorphicCircle(
|
const NeumorphicCircle({
|
||||||
{super.key,
|
super.key,
|
||||||
required this.innerShadow,
|
required this.innerShadow,
|
||||||
required this.outerShadow,
|
required this.outerShadow,
|
||||||
required this.highlightColor,
|
required this.highlightColor,
|
||||||
required this.shadowColor,
|
required this.shadowColor,
|
||||||
required this.backgroundColor,
|
required this.backgroundColor,
|
||||||
this.child});
|
this.child,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Stack(alignment: Alignment.center, children: [
|
return Stack(
|
||||||
Container(
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
boxShadow: (outerShadow)
|
boxShadow:
|
||||||
? [
|
(outerShadow)
|
||||||
|
? [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: highlightColor,
|
color: highlightColor,
|
||||||
offset: const Offset(-10, -10),
|
offset: const Offset(-10, -10),
|
||||||
blurRadius: 20,
|
blurRadius: 20,
|
||||||
spreadRadius: 0),
|
spreadRadius: 0,
|
||||||
|
),
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: shadowColor,
|
color: shadowColor,
|
||||||
offset: const Offset(10, 10),
|
offset: const Offset(10, 10),
|
||||||
blurRadius: 20,
|
blurRadius: 20,
|
||||||
spreadRadius: 0)
|
spreadRadius: 0,
|
||||||
|
),
|
||||||
]
|
]
|
||||||
: null)),
|
: null,
|
||||||
(innerShadow)
|
),
|
||||||
? ClipPath(
|
),
|
||||||
|
(innerShadow)
|
||||||
|
? ClipPath(
|
||||||
clipper: HighlightClipper(),
|
clipper: HighlightClipper(),
|
||||||
child: CircleInnerHighlight(
|
child: CircleInnerHighlight(
|
||||||
highlightColor: highlightColor,
|
highlightColor: highlightColor,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
))
|
),
|
||||||
: const SizedBox.shrink(),
|
)
|
||||||
(innerShadow)
|
: const SizedBox.shrink(),
|
||||||
? ClipPath(
|
(innerShadow)
|
||||||
|
? ClipPath(
|
||||||
clipper: ShadowClipper(),
|
clipper: ShadowClipper(),
|
||||||
child: CircleInnerShadow(
|
child: CircleInnerShadow(
|
||||||
shadowColor: shadowColor,
|
shadowColor: shadowColor,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
(child != null) ? child! : const SizedBox.shrink()
|
(child != null) ? child! : const SizedBox.shrink(),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,8 +167,11 @@ class CircleInnerShadow extends StatelessWidget {
|
||||||
final Color shadowColor;
|
final Color shadowColor;
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
|
|
||||||
const CircleInnerShadow(
|
const CircleInnerShadow({
|
||||||
{super.key, required this.shadowColor, required this.backgroundColor});
|
super.key,
|
||||||
|
required this.shadowColor,
|
||||||
|
required this.backgroundColor,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -162,10 +179,7 @@ class CircleInnerShadow extends StatelessWidget {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
gradient: RadialGradient(
|
gradient: RadialGradient(
|
||||||
colors: [
|
colors: [backgroundColor, shadowColor],
|
||||||
backgroundColor,
|
|
||||||
shadowColor,
|
|
||||||
],
|
|
||||||
center: const AlignmentDirectional(0.05, 0.05),
|
center: const AlignmentDirectional(0.05, 0.05),
|
||||||
focal: const AlignmentDirectional(0, 0),
|
focal: const AlignmentDirectional(0, 0),
|
||||||
radius: 0.5,
|
radius: 0.5,
|
||||||
|
@ -175,12 +189,14 @@ class CircleInnerShadow extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topLeft,
|
begin: Alignment.topLeft,
|
||||||
end: Alignment.bottomRight,
|
end: Alignment.bottomRight,
|
||||||
stops: const [0, 0.45],
|
stops: const [0, 0.45],
|
||||||
colors: [backgroundColor.withOpacity(0), backgroundColor])),
|
colors: [backgroundColor.withValues(alpha: 0), backgroundColor],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -190,8 +206,11 @@ class CircleInnerHighlight extends StatelessWidget {
|
||||||
final Color highlightColor;
|
final Color highlightColor;
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
|
|
||||||
const CircleInnerHighlight(
|
const CircleInnerHighlight({
|
||||||
{super.key, required this.highlightColor, required this.backgroundColor});
|
super.key,
|
||||||
|
required this.highlightColor,
|
||||||
|
required this.backgroundColor,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -199,10 +218,7 @@ class CircleInnerHighlight extends StatelessWidget {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
gradient: RadialGradient(
|
gradient: RadialGradient(
|
||||||
colors: [
|
colors: [backgroundColor, highlightColor],
|
||||||
backgroundColor,
|
|
||||||
highlightColor,
|
|
||||||
],
|
|
||||||
center: const AlignmentDirectional(-0.05, -0.05),
|
center: const AlignmentDirectional(-0.05, -0.05),
|
||||||
focal: const AlignmentDirectional(-0.05, -0.05),
|
focal: const AlignmentDirectional(-0.05, -0.05),
|
||||||
radius: 0.6,
|
radius: 0.6,
|
||||||
|
@ -212,12 +228,14 @@ class CircleInnerHighlight extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topLeft,
|
begin: Alignment.topLeft,
|
||||||
end: Alignment.bottomRight,
|
end: Alignment.bottomRight,
|
||||||
stops: const [0.55, 1],
|
stops: const [0.55, 1],
|
||||||
colors: [backgroundColor, backgroundColor.withOpacity(0)])),
|
colors: [backgroundColor, backgroundColor.withValues(alpha: 0)],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue