Search code examples
flutterflutter-animation

How to make a Custom Carousell flutter


Found this on cool carousell UI on dribble

I really wanted to make something like this but don't know where to start

Any Ideas would be greatly appreciated

Thanks!!

fafa


Solution

  • It can be done easily with cuasual package, or you can also achieve it by using PageView.

    Here is an example:

    • PageView: show 1 page and see the previous/next page by setting viewportFraction
    • AnimatedBuilder: listen to the change of page offset
    • Transform: scale, rotate and translation the position of next, previous page

    code:

    import 'package:flutter/material.dart';
    import 'dart:math' as math;
    
    const viewportFraction = 0.7;
    
    class MyPageView extends StatefulWidget {
      const MyPageView({
        required this.children,
        Key? key,
      }) : super(key: key);
    
      final List<Widget> children;
    
      factory MyPageView.images(List<ImageProvider> imageProviders) {
        return MyPageView(
          children: [
            for (final image in imageProviders)
              ClipRRect(
                borderRadius: BorderRadius.circular(16),
                child: Image(
                  image: image,
                  fit: BoxFit.cover,
                ),
              ),
          ],
        );
      }
    
      @override
      State<MyPageView> createState() => _MyPageViewState();
    }
    
    class _MyPageViewState extends State<MyPageView> {
      final pageController = PageController(viewportFraction: viewportFraction);
    
      @override
      Widget build(BuildContext context) {
        return LayoutBuilder(
          builder: (context, constraint) {
            final maxWidth = constraint.maxWidth;
            return PageView.builder(
              allowImplicitScrolling: true,
              controller: pageController,
              itemCount: widget.children.length,
              itemBuilder: (_, index) {
                final child = widget.children[index];
                return AnimatedBuilder(
                  animation: pageController,
                  builder: (_, __) {
                    final ratioX = pageController.offset / maxWidth / viewportFraction - index;
    
                    return Transform.rotate(
                      angle: math.pi * -0.05 * ratioX,
                      child: Transform.translate(
                        offset: Offset(ratioX * 10, ratioX.abs() * 70),
                        child: Transform.scale(
                          scale: 0.8,
                          child: child,
                        ),
                      ),
                    );
                  },
                );
              },
            );
          },
        );
      }
    
      @override
      void dispose() {
        pageController.dispose();
        super.dispose();
      }
    }
    

    And here is the example result:

    MyPageView.images(
      List.generate(
        50,
         (index) => NetworkImage('https://picsum.photos/seed/$index/400/600'),
        ),
      )
    

    enter image description here