diff --git a/lib/src/core/animation/animation_strategy.dart b/lib/src/core/animation/animation_strategy.dart index 7789642..05d9764 100644 --- a/lib/src/core/animation/animation_strategy.dart +++ b/lib/src/core/animation/animation_strategy.dart @@ -9,7 +9,7 @@ abstract class AnimationStrategy { DragStartDetails details, BuildContext context, SlideDirection direction); void handleDragUpdate(DragUpdateDetails details, BoxConstraints constraints, - SliderDrawerController controller); + SliderDrawerController controller, double sliderOpenSize); } class SliderAnimationStrategy implements AnimationStrategy { @@ -30,17 +30,33 @@ class SliderAnimationStrategy implements AnimationStrategy { @override void handleDragUpdate(DragUpdateDetails details, BoxConstraints constraints, - SliderDrawerController controller) { + SliderDrawerController controller, double sliderOpenSize) { if (controller.isHorizontalSlide) { - var position = - (details.globalPosition.dx).clamp(0.0, constraints.maxWidth) / - constraints.maxWidth; + var xOffsetSinceStart = details.globalPosition.dx - + (controller.globalStartOffset != null + ? controller.globalStartOffset!.dx + : 0); - if (controller.slideDirection == SlideDirection.rightToLeft) { - position = 1 - position; - } + double adjustedOffset; + double percent = 0.0; + if (controller.slideDirection == SlideDirection.leftToRight) { + // if drawer is open, dragging needs to go into the negative direction, + // so we shift the offset by sliderOpenSize to keep it normalized + adjustedOffset = controller.wasDrawerOpen + ? xOffsetSinceStart + sliderOpenSize + : xOffsetSinceStart; + + percent = (adjustedOffset).clamp(0.0, sliderOpenSize) / sliderOpenSize; + } else if (controller.slideDirection == SlideDirection.rightToLeft) { + // same here but in the other direction + adjustedOffset = controller.wasDrawerOpen + ? xOffsetSinceStart - sliderOpenSize + : xOffsetSinceStart; - controller.updatePosition(position); + percent = + (adjustedOffset).clamp(-sliderOpenSize, 0.0) / -sliderOpenSize; + } + controller.updatePosition(percent); } } diff --git a/lib/src/core/animation/slider_drawer_controller.dart b/lib/src/core/animation/slider_drawer_controller.dart index 6865409..2013479 100644 --- a/lib/src/core/animation/slider_drawer_controller.dart +++ b/lib/src/core/animation/slider_drawer_controller.dart @@ -7,6 +7,8 @@ class SliderDrawerController extends ChangeNotifier { final double threshold; bool _isDragging = false; + bool _wasDrawerOpen = false; + Offset? _globalStartOffset; double _percent = 0.0; SliderDrawerController({ @@ -19,6 +21,10 @@ class SliderDrawerController extends ChangeNotifier { bool get isDragging => _isDragging; + bool get wasDrawerOpen => _wasDrawerOpen; + + Offset? get globalStartOffset => _globalStartOffset; + bool get isDrawerOpen => animationController.isCompleted; bool get isHorizontalSlide => @@ -31,18 +37,25 @@ class SliderDrawerController extends ChangeNotifier { void closeSlider() => animationController.reverse(); - void startDragging() { + void startDragging(DragStartDetails details) { + _wasDrawerOpen = isDrawerOpen; _isDragging = true; + _globalStartOffset = details.globalPosition; notifyListeners(); } void stopDragging() { + if (!_isDragging) return; + + _globalStartOffset = null; _isDragging = false; _percent > threshold ? openSlider() : closeSlider(); notifyListeners(); } void updatePosition(double percent) { + if (!_isDragging) return; + _percent = percent; animationController.value = percent; notifyListeners(); diff --git a/lib/src/slider_drawer.dart b/lib/src/slider_drawer.dart index 335d89e..fcc469d 100644 --- a/lib/src/slider_drawer.dart +++ b/lib/src/slider_drawer.dart @@ -209,7 +209,7 @@ class SliderDrawerState extends State void _handleDragStart(DragStartDetails details) { if (_animationStrategy.shouldStartDrag( details, context, widget.slideDirection)) { - _controller.startDragging(); + _controller.startDragging(details); } } @@ -219,7 +219,7 @@ class SliderDrawerState extends State void _handleDragUpdate( DragUpdateDetails details, BoxConstraints constraints) { - _animationStrategy.handleDragUpdate(details, constraints, _controller); + _animationStrategy.handleDragUpdate(details, constraints, _controller, widget.sliderOpenSize); } @override