Untitled

 avatar
unknown
dart
a year ago
8.0 kB
6
Indexable
final bottomDis = 1.sh - 50.h - MediaQuery.of(Get.context!).padding.bottom.h;

final topDis = MediaQuery.of(Get.context!).padding.top.h + 38.h;

List<Offset> _positions = [
  //flight icon
  Offset(0, bottomDis),
  //flight deal tab
  Offset(15.w, topDis),
  //custom request tab
  Offset(0.5.sw, topDis),
  //saved icon
  Offset(0.2.sw, bottomDis),
  //my trip icon
  Offset(0.4.sw, bottomDis),
  //message icon
  Offset(0.6.sw, bottomDis),
  //profile icon
  Offset(0.8.sw, bottomDis),
];

List<Offset> _textPosition = [
  //flight icon
  Offset(0, bottomDis - 70),
  //flight deal tab
  Offset(15.w, 1.sh / 9 + 40.h),
  //custom request tab
  Offset(0.2.sw, 1.sh / 9 + 40.h),
  //saved icon
  Offset(30.w, bottomDis - 70.h),
  //my trip icon
  Offset(45.w, bottomDis - 70.h),
  //message icon
  Offset(60.w, bottomDis - 70.h),
  //profile icon
  Offset(75.w, bottomDis - 70.h),
];

List<Size> _sizes = [
  Size(0.2.sw, 50.h),
  Size(0.5.sw - 10.w, 40.h),
  Size(0.5.sw - 10.w, 40.h),
  Size(0.2.sw, 50.h),
  Size(0.2.sw, 50.h),
  Size(0.2.sw, 50.h),
  Size(0.2.sw, 50.h),
];

List<String> text = [
  "Explore all available flights with a tap on the Flights button.",
  "Flight deals provide an excellent way for travelers to save money on their private jet charter and are ideal for those who want to enjoy the luxury of a private jet while keeping costs down",
  "Custom Charter Request service allows users to request a bespoke charter flight that is tailored to their exact specifications, with the added support of a live AVIA representative to assist with any questions or concerns",
  "Keep track of your favorite flights with a tap on the Saved button.",
  "Keep track of all your trips with ease using the My Trips feature.",
  "Tap the Messages button to reach our dedicated support team.",
  "Manage your account details effortlessly with the Account button.",
];

class GuidelineScreen extends StatefulWidget {
  const GuidelineScreen({Key? key}) : super(key: key);

  @override
  State<GuidelineScreen> createState() => _GuidelineScreenState();
}

class _GuidelineScreenState extends State<GuidelineScreen>
    with SingleTickerProviderStateMixin {
  int step = 0;
  late AnimationController _controller;
  late Animation<Offset> _offsetAnimation;
  late Animation<Offset> _textOffsetAnimation;
  late Animation<Size> _sizeAnimation;
  @override
  void initState() {
    _controller = AnimationController(
      duration: const Duration(milliseconds: 500),
      vsync: this,
    );
    _offsetAnimation = Tween<Offset>(
      begin: Offset.zero,
      end: _positions[0],
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    ));
    _textOffsetAnimation = Tween<Offset>(
      begin: Offset.zero,
      end: _textPosition[0],
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    ));
    _sizeAnimation = Tween<Size>(
      begin: const Size(0, 0),
      end: _sizes[0],
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    ));
    _controller.addListener(() {
      setState(() {});
    });

    _controller.forward();
    super.initState();
  }

  void goToNext() {
    if (step == 6) {
      Navigator.pop(context);
    } else {
      step++;

      final currentPosition = _offsetAnimation.value;
      final currentSize = _sizeAnimation.value;
      final currentTextPosition = _textOffsetAnimation.value;

      _offsetAnimation = Tween<Offset>(
        begin: currentPosition,
        end: _positions[step],
      ).animate(CurvedAnimation(
        parent: _controller,
        curve: Curves.easeInOut,
      ));

      _textOffsetAnimation = Tween<Offset>(
        begin: currentTextPosition,
        end: _textPosition[step],
      ).animate(CurvedAnimation(
        parent: _controller,
        curve: Curves.easeInOut,
      ));

      _sizeAnimation = Tween<Size>(
        begin: currentSize,
        end: _sizes[step],
      ).animate(CurvedAnimation(
        parent: _controller,
        curve: Curves.easeInOut,
      ));

      _controller
        ..reset()
        ..forward();
    }
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: SizedBox(
        width: 1.sw,
        height: 1.sh,
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            return AnimatedBuilder(
              animation: _controller,
              builder: (BuildContext context, Widget? child) {
                return Stack(
                  children: [
                    SizedBox(
                      width: double.infinity,
                      height: double.infinity,
                      child: CustomPaint(
                        painter: FullScreenPainter(
                          ssize: _sizeAnimation.value,
                          offset: _offsetAnimation.value,
                        ),
                      ),
                    ),
                    Positioned(
                      right: 16.w,
                      bottom: constraints.maxHeight * 0.355,
                      child: SizedBox(
                        width: constraints.maxWidth * 0.3,
                        child: AppTextButton(
                          backgroundColor: AppColors.primary,
                          onPressed: goToNext,
                          child: Text(
                            step == 6 ? "Finish" : "Next",
                            style: const TextStyle(fontWeight: FontWeight.w500),
                          ),
                        ),
                      ),
                    ),
                    Positioned(
                      top: _textOffsetAnimation.value.dy,
                      left: _textOffsetAnimation.value.dx,
                      child: ConstrainedBox(
                        constraints: BoxConstraints(
                          maxWidth: constraints.maxWidth * 0.8,
                        ),
                        child: Container(
                          decoration: BoxDecoration(
                            color: isDarkMode(context)
                                ? AppColors.darkCardBackground
                                : Colors.white,
                            borderRadius: BorderRadius.circular(10),
                          ),
                          padding: const EdgeInsets.all(10),
                          child: Text(
                            text[step],
                            style: sfProTextMediumSize8.copyWith(
                                color: isDarkMode(context)
                                    ? Colors.white
                                    : AppColors.greyBlue189),
                          ),
                        ),
                      ),
                    ),
                  ],
                );
              },
            );
          },
        ),
      ),
    );
  }
}

class FullScreenPainter extends CustomPainter {
  final Size ssize;
  final Offset offset;

  FullScreenPainter({required this.ssize, required this.offset});
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint();
    paint.color = Colors.black.withOpacity(
      isDarkMode(Get.context!) ? 0.5 : 0.5,
    );
    canvas.drawPath(
      Path.combine(
        PathOperation.difference,
        Path()..addRect(Rect.fromLTWH(0, 0, size.width, size.height)),
        Path()
          ..addRRect(
              RRect.fromRectAndRadius(offset & ssize, Radius.circular(8.r)))
          ..close(),
      ),
      paint,
    );
  }

  @override
  bool shouldRepaint(FullScreenPainter oldDelegate) => false;
}
Editor is loading...
Leave a Comment