feat : new bottom sheet V2

This commit is contained in:
2025-04-28 17:06:21 +03:30
parent e9b065062a
commit caa3884242

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_core/data/utils.dart';
import 'logic.dart'; import 'logic.dart';
@@ -14,39 +15,34 @@ class RootPage extends GetView<RootLogic> {
// سایر محتواها (مثلا صفحات اصلی) // سایر محتواها (مثلا صفحات اصلی)
Align( Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: Column( child: Container(
children: [ height: 90,
const Spacer(), color: AppColor.blueNormal,
Container( clipBehavior: Clip.none,
height: 100, padding: const EdgeInsets.all(10),
padding: const EdgeInsets.symmetric(vertical: 10), child: Stack(
decoration: const BoxDecoration( clipBehavior: Clip.none,
color: AppColor.blueNormal, alignment: Alignment.center,
borderRadius: BorderRadius.vertical( children: [
top: Radius.circular(40), Positioned(
), top: -43,
), child: Container(
child: SingleChildScrollView( width: 110,
clipBehavior: Clip.none, height: 110,
scrollDirection: Axis.horizontal, clipBehavior: Clip.none,
physics: const BouncingScrollPhysics(), decoration: ShapeDecoration(
padding: const EdgeInsets.symmetric(horizontal: 10), color:Colors.white,
child: Row(
children: List.generate( shape: RoundedRectangleBorder(
50, borderRadius: BorderRadius.circular(200),
(index) => ObxValue((data) { side: BorderSide(width: 2, color: Colors.white),
return BottomNavigation1ItemTST( ),
icon: Assets.vecMapSvg,
label: 'item$index',
isSelected: controller.currentIndex.value == index,
onTap: () => controller.changePage(index),
);
}, controller.currentIndex),
), ),
), ),
), ),
), WavePageView(),
], ],
),
), ),
), ),
], ],
@@ -117,5 +113,280 @@ class BottomNavigation1ItemTST extends StatelessWidget {
} }
} }
class ScrollWithCenterScaling extends StatefulWidget {
const ScrollWithCenterScaling({super.key});
@override
State<ScrollWithCenterScaling> createState() =>
_ScrollWithCenterScalingState();
}
class _ScrollWithCenterScalingState extends State<ScrollWithCenterScaling> {
final PageController _pageController = PageController(viewportFraction: 0.3);
double currentPage = 0.0;
@override
void initState() {
super.initState();
_pageController.addListener(() {
setState(() {
currentPage = _pageController.page ?? 0.0;
});
});
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
double _calculateScale(int index) {
final double distance = (currentPage - index).abs();
if (distance >= 1) {
return 0.7;
} else {
return 1.3;
}
}
bool _isSelected(int index) {
return (currentPage - index).abs() < 0.5; // دقیق وسط بودن رو بگیره
}
@override
Widget build(BuildContext context) {
return PageView.builder(
controller: _pageController,
itemCount: 50,
clipBehavior: Clip.none,
physics: const BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final scale = _calculateScale(index);
final selected = _isSelected(index);
return Transform.scale(
scale: scale,
child: AnimatedPadding(
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
padding: EdgeInsets.only(bottom: selected ? 20 : 0),
child: InkWell(
onTap: () {},
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.map, color: Colors.white),
const SizedBox(height: 8),
Text(
'Label $index',
style: TextStyle(
color: Colors.white,
fontSize: selected ? 18 : 0,
fontWeight:
selected ? FontWeight.bold : FontWeight.normal,
),
),
],
),
),
),
);
},
);
}
}
class ScrollWithCenterRotation2 extends StatefulWidget {
const ScrollWithCenterRotation2({super.key});
@override
State<ScrollWithCenterRotation2> createState() =>
_ScrollWithCenterRotationState2();
}
class _ScrollWithCenterRotationState2 extends State<ScrollWithCenterRotation2> {
final PageController _pageController = PageController(viewportFraction: 0.3);
double currentPage = 0.0;
@override
void initState() {
super.initState();
_pageController.addListener(() {
setState(() {
currentPage = _pageController.page ?? 0.0;
});
});
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
double _calculateScale(int index) {
final double distance = (currentPage - index).abs();
if (distance >= 1) {
return 0.7;
} else {
return 1.2;
}
}
double _calculateRotationY(int index) {
return (currentPage - index) * 0.5;
}
bool _isSelected(int index) {
return (currentPage - index).abs() < 0.5;
}
@override
Widget build(BuildContext context) {
return PageView.builder(
controller: _pageController,
itemCount: 50,
clipBehavior: Clip.none,
physics: const BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final scale = _calculateScale(index);
final rotationY = _calculateRotationY(index);
final selected = _isSelected(index);
return AnimatedContainer(
clipBehavior: Clip.none,
height: 80,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
margin: EdgeInsets.only(
bottom: selected ? 90 : 20, // وسطی بالاتر میاد
),
child: Transform(
transform:
Matrix4.identity()
..scale(scale)
..setEntry(3, 2, 0.001),
alignment: Alignment.center,
child: InkWell(
onTap: () {},
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: selected ? 70 : 60,
height: selected ? 70 : 60,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
boxShadow:
selected
? [
BoxShadow(
color: Colors.amber,
blurRadius: 20,
spreadRadius: 5,
),
]
: [],
),
alignment: Alignment.center,
child: Icon(
Icons.map,
color: Colors.white,
size: selected ? 32 : 24,
),
),
const SizedBox(height: 8),
Text(
'Label $index',
style: TextStyle(
color: Colors.white,
fontSize: selected ? 18 : 14,
fontWeight:
selected ? FontWeight.bold : FontWeight.normal,
),
),
],
),
),
),
);
},
);
}
}
class WavePageView extends StatefulWidget {
@override
_WavePageViewState createState() => _WavePageViewState();
}
class _WavePageViewState extends State<WavePageView> {
final PageController _controller = PageController(viewportFraction: 0.3);
@override
void dispose() {
_controller.dispose();
super.dispose();
}
double _calculateScale(double currentPage,int index) {
final double distance = (currentPage - index).abs();
if (distance >= 1) {
return 0.7;
} else {
return 1.7;
}
}
@override
Widget build(BuildContext context) {
return PageView.builder(
controller: _controller,
clipBehavior: Clip.none,
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
double value = 0.0;
final scale = _calculateScale(_controller.page??0,index);
value = index - (_controller.page ?? 0);
value = (value).clamp(-1, 1);
eLog("index = $index \n value = $value");
double offset = value * 30;
if (value.abs() < 0.1 || value.abs() > 0.1) {
offset = -5 * (1 - value.abs() * 5);
}
return Transform.scale(
scale: scale,
child: Transform.translate(
offset: Offset(0, offset),
child: Column(
children: [
Icon(Icons.map, color: value.toInt() == 0 ? AppColor.greenNormal:Colors.white, size: 32),
Visibility(
visible: value.toInt() == 0,
child: Text(
'بازرسی',
style: AppFonts.yekan10.copyWith(color: AppColor.greenNormal)
),
),
],
),
),
);
},
);
},
);
}
}