diff --git a/CHANGELOG.md b/CHANGELOG.md index e17ba27..409a594 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## [5.0.0] +- Adds option to customize the back card offset. - **BREAKING CHANGE**: - `CardSwiperController` is no longer disposed by `CardSwiper`, but who created it must dispose it. diff --git a/example/lib/main.dart b/example/lib/main.dart index 3eab3de..371caf3 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -42,9 +42,10 @@ class _ExamplePageState extends State { child: CardSwiper( controller: controller, cardsCount: cards.length, - numberOfCardsDisplayed: 3, onSwipe: _onSwipe, onUndo: _onUndo, + numberOfCardsDisplayed: 3, + backCardOffset: const Offset(40, 40), padding: const EdgeInsets.all(24.0), cardBuilder: (context, index) => cards[index], ), diff --git a/lib/src/card_animation.dart b/lib/src/card_animation.dart index 0ed848c..6495a73 100644 --- a/lib/src/card_animation.dart +++ b/lib/src/card_animation.dart @@ -9,12 +9,15 @@ class CardAnimation { required this.animationController, required this.maxAngle, required this.initialScale, + required this.initialOffset, this.isHorizontalSwipingEnabled = true, this.isVerticalSwipingEnabled = true, - }) : scale = initialScale; + }) : scale = initialScale, + difference = initialOffset; final double maxAngle; final double initialScale; + final Offset initialOffset; final AnimationController animationController; final bool isHorizontalSwipingEnabled; final bool isVerticalSwipingEnabled; @@ -24,12 +27,12 @@ class CardAnimation { double total = 0; double angle = 0; double scale; - double difference = 40; + Offset difference; late Animation _leftAnimation; late Animation _topAnimation; late Animation _scaleAnimation; - late Animation _differenceAnimation; + late Animation _differenceAnimation; double get _maxAngleInRadian => maxAngle * (pi / 180); @@ -47,7 +50,7 @@ class CardAnimation { total = 0; angle = 0; scale = initialScale; - difference = 40; + difference = initialOffset; } void update(double dx, double dy, bool inverseAngle) { @@ -79,8 +82,13 @@ class CardAnimation { } void updateDifference() { - if (difference.isBetween(0, difference)) { - difference = (total > 0) ? 40 - (total / 10) : 40 + (total / 10); + final discrepancy = (total > 0) ? total / 10 : -(total / 10); + + if (difference.dx.isBetween(0, initialOffset.dx)) { + difference = Offset(initialOffset.dx + discrepancy, difference.dy); + } + if (difference.dy.isBetween(0, initialOffset.dy)) { + difference = Offset(difference.dx, initialOffset.dy + discrepancy); } } @@ -114,9 +122,9 @@ class CardAnimation { begin: scale, end: 1.0, ).animate(animationController); - _differenceAnimation = Tween( + _differenceAnimation = Tween( begin: difference, - end: 0, + end: Offset.zero, ).animate(animationController); animationController.forward(); } @@ -136,9 +144,9 @@ class CardAnimation { begin: scale, end: 1.0, ).animate(animationController); - _differenceAnimation = Tween( + _differenceAnimation = Tween( begin: difference, - end: 0, + end: Offset.zero, ).animate(animationController); animationController.forward(); } @@ -156,9 +164,9 @@ class CardAnimation { begin: scale, end: initialScale, ).animate(animationController); - _differenceAnimation = Tween( + _differenceAnimation = Tween( begin: difference, - end: 40, + end: initialOffset, ).animate(animationController); animationController.forward(); } @@ -193,8 +201,8 @@ class CardAnimation { begin: 1.0, end: scale, ).animate(animationController); - _differenceAnimation = Tween( - begin: 0, + _differenceAnimation = Tween( + begin: Offset.zero, end: difference, ).animate(animationController); animationController.forward(); @@ -215,8 +223,8 @@ class CardAnimation { begin: 1.0, end: scale, ).animate(animationController); - _differenceAnimation = Tween( - begin: 0, + _differenceAnimation = Tween( + begin: Offset.zero, end: difference, ).animate(animationController); animationController.forward(); diff --git a/lib/src/card_swiper.dart b/lib/src/card_swiper.dart index 6eed711..d61e56f 100644 --- a/lib/src/card_swiper.dart +++ b/lib/src/card_swiper.dart @@ -106,6 +106,11 @@ class CardSwiper extends StatefulWidget { /// on top of the stack. If the function returns `true`, the undo action is performed as expected. final CardSwiperOnUndo? onUndo; + /// The offset of the back card from the front card. + /// + /// Must be a positive value. Defaults to Offset(0, 40). + final Offset backCardOffset; + const CardSwiper({ Key? key, required this.cardBuilder, @@ -127,6 +132,7 @@ class CardSwiper extends StatefulWidget { this.isLoop = true, this.numberOfCardsDisplayed = 2, this.onUndo, + this.backCardOffset = const Offset(0, 40), }) : assert( maxAngle >= 0 && maxAngle <= 360, 'maxAngle must be between 0 and 360', @@ -151,6 +157,10 @@ class CardSwiper extends StatefulWidget { initialIndex >= 0 && initialIndex < cardsCount, 'initialIndex must be between 0 and [cardsCount]', ), + assert( + backCardOffset >= Offset.zero, + 'backCardOffset must be a positive value', + ), super(key: key); @override @@ -194,6 +204,7 @@ class _CardSwiperState extends State initialScale: widget.scale, isVerticalSwipingEnabled: widget.isVerticalSwipingEnabled, isHorizontalSwipingEnabled: widget.isHorizontalSwipingEnabled, + initialOffset: widget.backCardOffset, ); } @@ -280,8 +291,8 @@ class _CardSwiperState extends State Widget _secondItem(BoxConstraints constraints) { return Positioned( - top: _cardAnimation.difference, - left: 0, + top: _cardAnimation.difference.dy, + left: _cardAnimation.difference.dx, child: Transform.scale( scale: _cardAnimation.scale, child: ConstrainedBox( @@ -294,8 +305,8 @@ class _CardSwiperState extends State Widget _backItem(BoxConstraints constraints, int offset) { return Positioned( - top: 40, - left: 0, + top: widget.backCardOffset.dy, + left: widget.backCardOffset.dx, child: Transform.scale( scale: widget.scale, child: ConstrainedBox( diff --git a/pubspec.yaml b/pubspec.yaml index 470f6fd..a76d278 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_card_swiper description: This is a Tinder-like card swiper package. It allows you to swipe left, right, up, and down and define your own business logic for each direction. homepage: https://github.com/ricardodalarme/flutter_card_swiper issue_tracker: https://github.com/ricardodalarme/flutter_card_swiper/issues -version: 4.1.3 +version: 5.0.0 environment: sdk: ">=2.12.0 <3.0.0"