181 lines
6.0 KiB
Dart
181 lines
6.0 KiB
Dart
import 'package:carousel_slider/carousel_controller.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:proxibuy/presentation/ui/theme/responsive.dart';
|
|
import 'package:proxibuy/presentation/ui/widgets/carousel/carousel_slider_widget.dart';
|
|
|
|
// TutorialOverlay
|
|
class ImageGallary extends ModalRoute<void> {
|
|
final List<String> urls;
|
|
final String initialUrl;
|
|
final CarouselSliderController carouselSliderController =
|
|
CarouselSliderController();
|
|
|
|
ImageGallary({required this.urls, required this.initialUrl});
|
|
|
|
@override
|
|
Duration get transitionDuration => Duration(milliseconds: 500);
|
|
|
|
@override
|
|
bool get opaque => false;
|
|
|
|
@override
|
|
bool get barrierDismissible => true;
|
|
|
|
@override
|
|
Color get barrierColor => Colors.black.withAlpha(210);
|
|
|
|
@override
|
|
String get barrierLabel => 'Images';
|
|
|
|
@override
|
|
bool get maintainState => true;
|
|
|
|
@override
|
|
Widget buildPage(
|
|
BuildContext context,
|
|
Animation<double> animation,
|
|
Animation<double> secondaryAnimation,
|
|
) {
|
|
return Material(
|
|
type: MaterialType.transparency,
|
|
child: SafeArea(
|
|
child: _buildOverlayContent(context),
|
|
),
|
|
);
|
|
}
|
|
|
|
late final ValueNotifier<String> initialImage = ValueNotifier(initialUrl);
|
|
Widget _buildOverlayContent(BuildContext context) {
|
|
double viewportFraction =
|
|
(1 / (urls.length * (MediaQuery.sizeOf(context).width / 1300)));
|
|
|
|
return Stack(
|
|
children: [
|
|
Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
ConstrainedBox(
|
|
constraints: BoxConstraints(
|
|
maxHeight: MediaQuery.sizeOf(context).height / 2),
|
|
child: ValueListenableBuilder(
|
|
valueListenable: initialImage,
|
|
builder: (context, value, child) {
|
|
return InteractiveViewer(
|
|
boundaryMargin: EdgeInsets.all(80),
|
|
minScale: 0.5,
|
|
maxScale: 4,
|
|
panEnabled: true,
|
|
child: AspectRatio(
|
|
aspectRatio:
|
|
Responsive(context).isMobile() ? 1 / 1 : 16 / 9,
|
|
child: Container(
|
|
margin: const EdgeInsets.all(32.0),
|
|
child: GestureDetector(
|
|
onHorizontalDragEnd: (details) {
|
|
if (details.primaryVelocity! < 0) {
|
|
// Swiped left
|
|
carouselSliderController.nextPage();
|
|
} else if (details.primaryVelocity! > 0) {
|
|
// Swiped right
|
|
carouselSliderController.previousPage();
|
|
}
|
|
},
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(8),
|
|
child: Image.network(
|
|
value,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
CarouselSliderWidget(
|
|
controller: carouselSliderController
|
|
..onReady.then(
|
|
(value) {
|
|
carouselSliderController
|
|
.jumpToPage(urls.indexOf(initialImage.value));
|
|
},
|
|
),
|
|
items: urls,
|
|
withInds: false,
|
|
autoPlay: false,
|
|
enableInfiniteScroll: false,
|
|
enlargeCenterPage: false,
|
|
viewportFraction: viewportFraction,
|
|
aspectRatio: 1 / 1,
|
|
height: 120,
|
|
onPageChanged: (index, reason) {
|
|
initialImage.value = urls[index];
|
|
},
|
|
onPageBuilder: (context, item, index) {
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.surface,
|
|
borderRadius: BorderRadius.only(
|
|
topLeft:
|
|
index == 0 ? Radius.circular(16) : Radius.zero,
|
|
bottomLeft:
|
|
index == 0 ? Radius.circular(16) : Radius.zero,
|
|
bottomRight: index == urls.length - 1
|
|
? Radius.circular(16)
|
|
: Radius.zero,
|
|
topRight: index == urls.length - 1
|
|
? Radius.circular(16)
|
|
: Radius.zero)),
|
|
padding: EdgeInsets.all(16),
|
|
child: InkWell(
|
|
onTap: () {
|
|
carouselSliderController.animateToPage(index);
|
|
},
|
|
child: SizedBox(
|
|
child: Image.network(
|
|
item,
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
Positioned(
|
|
top: 32,
|
|
left: 32,
|
|
child: InkWell(
|
|
onTap: () {
|
|
Navigator.pop(context);
|
|
},
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.surface,
|
|
borderRadius: BorderRadius.circular(8)),
|
|
padding: EdgeInsets.all(8),
|
|
child: Icon(Icons.arrow_back_ios_new_rounded),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
|
Animation<double> secondaryAnimation, Widget child) {
|
|
// You can add your own animations for the overlay content
|
|
return FadeTransition(
|
|
opacity: animation,
|
|
child: ScaleTransition(
|
|
scale: animation,
|
|
child: child,
|
|
),
|
|
);
|
|
}
|
|
}
|