feat: add support for handling negative backCardOffset
This commit is contained in:
parent
efed38b755
commit
347c9fdcd5
|
|
@ -1,9 +1,8 @@
|
||||||
import 'dart:math';
|
import 'dart:math' as math;
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_card_swiper/flutter_card_swiper.dart';
|
import 'package:flutter_card_swiper/flutter_card_swiper.dart';
|
||||||
import 'package:flutter_card_swiper/src/extensions.dart';
|
|
||||||
|
|
||||||
class CardAnimation {
|
class CardAnimation {
|
||||||
CardAnimation({
|
CardAnimation({
|
||||||
|
|
@ -13,8 +12,7 @@ class CardAnimation {
|
||||||
required this.initialOffset,
|
required this.initialOffset,
|
||||||
this.isHorizontalSwipingEnabled = true,
|
this.isHorizontalSwipingEnabled = true,
|
||||||
this.isVerticalSwipingEnabled = true,
|
this.isVerticalSwipingEnabled = true,
|
||||||
}) : scale = initialScale,
|
}) : scale = initialScale;
|
||||||
difference = initialOffset;
|
|
||||||
|
|
||||||
final double maxAngle;
|
final double maxAngle;
|
||||||
final double initialScale;
|
final double initialScale;
|
||||||
|
|
@ -28,14 +26,14 @@ class CardAnimation {
|
||||||
double total = 0;
|
double total = 0;
|
||||||
double angle = 0;
|
double angle = 0;
|
||||||
double scale;
|
double scale;
|
||||||
Offset difference;
|
Offset difference = Offset.zero;
|
||||||
|
|
||||||
late Animation<double> _leftAnimation;
|
late Animation<double> _leftAnimation;
|
||||||
late Animation<double> _topAnimation;
|
late Animation<double> _topAnimation;
|
||||||
late Animation<double> _scaleAnimation;
|
late Animation<double> _scaleAnimation;
|
||||||
late Animation<Offset> _differenceAnimation;
|
late Animation<Offset> _differenceAnimation;
|
||||||
|
|
||||||
double get _maxAngleInRadian => maxAngle * (pi / 180);
|
double get _maxAngleInRadian => maxAngle * (math.pi / 180);
|
||||||
|
|
||||||
void sync() {
|
void sync() {
|
||||||
left = _leftAnimation.value;
|
left = _leftAnimation.value;
|
||||||
|
|
@ -51,7 +49,7 @@ class CardAnimation {
|
||||||
total = 0;
|
total = 0;
|
||||||
angle = 0;
|
angle = 0;
|
||||||
scale = initialScale;
|
scale = initialScale;
|
||||||
difference = initialOffset;
|
difference = Offset.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(double dx, double dy, bool inverseAngle) {
|
void update(double dx, double dy, bool inverseAngle) {
|
||||||
|
|
@ -68,27 +66,36 @@ class CardAnimation {
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateAngle(bool inverse) {
|
void updateAngle(bool inverse) {
|
||||||
if (angle.isBetween(-_maxAngleInRadian, _maxAngleInRadian)) {
|
angle = clampDouble(
|
||||||
angle = _maxAngleInRadian * left / 1000;
|
_maxAngleInRadian * left / 1000,
|
||||||
if (inverse) angle *= -1;
|
-_maxAngleInRadian,
|
||||||
}
|
_maxAngleInRadian,
|
||||||
|
);
|
||||||
|
if (inverse) angle *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateScale() {
|
void updateScale() {
|
||||||
scale = (total > 0)
|
scale = clampDouble(initialScale + (total.abs() / 5000), initialScale, 1.0);
|
||||||
? clampDouble(initialScale + (total / 5000), initialScale, 1.0)
|
|
||||||
: clampDouble(initialScale - (total / 5000), initialScale, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateDifference() {
|
void updateDifference() {
|
||||||
final discrepancy = (total > 0) ? total / 10 : -(total / 10);
|
final discrepancy = (total / 10).abs();
|
||||||
|
|
||||||
if (difference.dx.isBetween(0, initialOffset.dx)) {
|
var diffX = 0.0, diffY = 0.0;
|
||||||
difference = Offset(initialOffset.dx + discrepancy, difference.dy);
|
|
||||||
|
if (initialOffset.dx > 0) {
|
||||||
|
diffX = discrepancy;
|
||||||
|
} else if (initialOffset.dx < 0) {
|
||||||
|
diffX = -discrepancy;
|
||||||
}
|
}
|
||||||
if (difference.dy.isBetween(0, initialOffset.dy)) {
|
|
||||||
difference = Offset(difference.dx, initialOffset.dy + discrepancy);
|
if (initialOffset.dy < 0) {
|
||||||
|
diffY = -discrepancy;
|
||||||
|
} else if (initialOffset.dy > 0) {
|
||||||
|
diffY = discrepancy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
difference = Offset(diffX, diffY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void animate(BuildContext context, CardSwiperDirection direction) {
|
void animate(BuildContext context, CardSwiperDirection direction) {
|
||||||
|
|
@ -123,7 +130,7 @@ class CardAnimation {
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
_differenceAnimation = Tween<Offset>(
|
_differenceAnimation = Tween<Offset>(
|
||||||
begin: difference,
|
begin: difference,
|
||||||
end: Offset.zero,
|
end: initialOffset,
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
animationController.forward();
|
animationController.forward();
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +152,7 @@ class CardAnimation {
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
_differenceAnimation = Tween<Offset>(
|
_differenceAnimation = Tween<Offset>(
|
||||||
begin: difference,
|
begin: difference,
|
||||||
end: Offset.zero,
|
end: initialOffset,
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
animationController.forward();
|
animationController.forward();
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +172,7 @@ class CardAnimation {
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
_differenceAnimation = Tween<Offset>(
|
_differenceAnimation = Tween<Offset>(
|
||||||
begin: difference,
|
begin: difference,
|
||||||
end: initialOffset,
|
end: Offset.zero,
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
animationController.forward();
|
animationController.forward();
|
||||||
}
|
}
|
||||||
|
|
@ -201,7 +208,7 @@ class CardAnimation {
|
||||||
end: scale,
|
end: scale,
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
_differenceAnimation = Tween<Offset>(
|
_differenceAnimation = Tween<Offset>(
|
||||||
begin: Offset.zero,
|
begin: initialOffset,
|
||||||
end: difference,
|
end: difference,
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
animationController.forward();
|
animationController.forward();
|
||||||
|
|
@ -223,7 +230,7 @@ class CardAnimation {
|
||||||
end: scale,
|
end: scale,
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
_differenceAnimation = Tween<Offset>(
|
_differenceAnimation = Tween<Offset>(
|
||||||
begin: Offset.zero,
|
begin: initialOffset,
|
||||||
end: difference,
|
end: difference,
|
||||||
).animate(animationController);
|
).animate(animationController);
|
||||||
animationController.forward();
|
animationController.forward();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'dart:math';
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_card_swiper/src/card_animation.dart';
|
import 'package:flutter_card_swiper/src/card_animation.dart';
|
||||||
|
|
@ -157,10 +157,6 @@ class CardSwiper extends StatefulWidget {
|
||||||
initialIndex >= 0 && initialIndex < cardsCount,
|
initialIndex >= 0 && initialIndex < cardsCount,
|
||||||
'initialIndex must be between 0 and [cardsCount]',
|
'initialIndex must be between 0 and [cardsCount]',
|
||||||
),
|
),
|
||||||
assert(
|
|
||||||
backCardOffset >= Offset.zero,
|
|
||||||
'backCardOffset must be a positive value',
|
|
||||||
),
|
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -227,9 +223,7 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper>
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: List.generate(numberOfCardsOnScreen(), (index) {
|
children: List.generate(numberOfCardsOnScreen(), (index) {
|
||||||
if (index == 0) {
|
if (index == 0) return _frontItem(constraints);
|
||||||
return _frontItem(constraints);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _backItem(constraints, index);
|
return _backItem(constraints, index);
|
||||||
}).reversed.toList(),
|
}).reversed.toList(),
|
||||||
|
|
@ -287,15 +281,15 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _backItem(BoxConstraints constraints, int offset) {
|
Widget _backItem(BoxConstraints constraints, int index) {
|
||||||
return Positioned(
|
return Positioned(
|
||||||
top: _cardAnimation.difference.dy * offset,
|
top: (widget.backCardOffset.dy * index) - _cardAnimation.difference.dy,
|
||||||
left: _cardAnimation.difference.dx * offset,
|
left: (widget.backCardOffset.dx * index) - _cardAnimation.difference.dx,
|
||||||
child: Transform.scale(
|
child: Transform.scale(
|
||||||
scale: _cardAnimation.scale - ((1 - widget.scale) * (offset - 1)),
|
scale: _cardAnimation.scale - ((1 - widget.scale) * (index - 1)),
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: constraints,
|
constraints: constraints,
|
||||||
child: widget.cardBuilder(context, getValidIndexOffset(offset)!),
|
child: widget.cardBuilder(context, getValidIndexOffset(index)!),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -426,7 +420,7 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper>
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return min(
|
return math.min(
|
||||||
widget.numberOfCardsDisplayed,
|
widget.numberOfCardsDisplayed,
|
||||||
widget.cardsCount - _currentIndex!,
|
widget.cardsCount - _currentIndex!,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue