Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

created swap movement detector with direction #34

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: Bug Report
about: Report unexpected behavior
title: ''
labels: bug
assignees: ''

---

**Unexpected behavior :x:**
<!-- Explain in as few sentences as possible what the unexpected behavior is. -->

**Expected behavior :heavy_check_mark:**
<!-- Describe clearly what you expected to happen. -->

**Reproducing :computer_mouse:**
<!-- Detail the process for recreating the bug and include the simplest possible code example that can be ran to reproduce the bug. -->

1. Execute `flutter run` on the code sample <!-- (see "Code sample" section below) -->
2. ... <!-- describe steps to demonstrate bug -->
3. ... <!-- for example "Swipe right and see crash" -->

<details>
<summary>Code sample</summary>
<!-- Copy and paste the complete code sample between the following two lines of backticks. -->

```dart
```

</details>

**Screenshots (optional) :camera_flash:**
<!-- If this is a visual bug, provide screenshot(s) here. -->

**Potential fixes (optional) :wrench:**
<!-- Add any potential ideas for fixing the unexpected behavior. -->
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: Feature Request
about: Suggest an improvement
title: ''
labels: enhancement
assignees: ''

---

**Complete the following checklist before opening this issue :heavy_check_mark:**
<!-- - [x] This is an example of how to check the following boxes -->
- [ ] This improvement has not been suggested already
- [ ] This suggestion is not a solution to a bug
- [ ] I've read the [contributing guidelines](https://github.com/jushutch/swiping_card_deck/blob/36a0424f0069453043b6e67b3be076e03cfafa42/CONTRIBUTING.md)

**The Idea :bulb:**
<!-- Describe the idea/suggestion in as few words as possible -->

**Use Case :briefcase:**
<!-- Describe how this improvement would be useful. Include an example of why users or developers would want this feature and how they might use it. -->

**Implementation** (optional) :wrench:
<!-- Describe the details of this improvement and include any potential implementation ideas. This field is REQUIRED if you plan on working on this improvement by yourself. Refer to the contributing guidelines for more information on how to contribute code. -->
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Question
about: Ask a general question
title: ''
labels: question
assignees: ''

---

<!-- Ask any questions about how to use the widget or about the project in general. There are no stupid questions, just be sure to follow the code of conduct and write your questions as clearly and concisely as possible. -->

**Before posting your question** :heavy_check_mark:
<!-- [x] An example of how to fill checkboxes on GitHub -->
- [ ] I acknowledge that I've read the [Code of Conduct](https://github.com/jushutch/swiping_card_deck/blob/ab3b8f224ea8f9eda6a925d98752fa30ba1b386e/CODE_OF_CONDUCT.md)

**Question :grey_question:**
<!-- Please try to limit this issue to one question if possible. If you have multiple related questions, separate them using a bulleted list. -->
23 changes: 23 additions & 0 deletions .github/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 14

# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7

# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels:
- awaiting response

# Label to use when marking an issue as stale
staleLabel: stale

# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because there has not been a response in 14 days. It will be closed if no further activity occurs in the next 7 days. If the previous discussion resolved your issue, please close the issue. Thank you again for contributing! :smile:

# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
This issue has been awaiting a response for 21 days and will now be automatically closed. If this is an error, leave a comment explaining why this is an error. Thank you for your patience and understanding! :raised_hands:

# Limit to only `issues` or `pulls`
only: issues
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.0.0-dev.0

- Add cardDeck and cardsSwiped parameters to onSwipe callback functions

## 1.2.0

- Create generic SwipingDeck for swiping through other widgets
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ SwipingCardDeck(
),
],
onDeckEmpty: () => debugPrint("Card deck empty"),
onLeftSwipe: (Card card) => debugPrint("Swiped left!"),
onRightSwipe: (Card card) => debugPrint("Swiped right!"),
onLeftSwipe: (Card card, List<Card> cardDeck, int cardsSwiped) => debugPrint("Swiped left!"),
onRightSwipe: (Card card, List<Card> cardDeck, int cardsSwiped) => debugPrint("Swiped right!"),
swipeThreshold: MediaQuery.of(context).size.width / 4,
minimumVelocity: 1000,
cardWidth: 200,
Expand Down
6 changes: 4 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ class ExamplePage extends StatelessWidget {
final SwipingCardDeck deck = SwipingCardDeck(
cardDeck: getCardDeck(),
onDeckEmpty: () => debugPrint("Card deck empty"),
onLeftSwipe: (Card card) => debugPrint("Swiped left!"),
onRightSwipe: (Card card) => debugPrint("Swiped right!"),
onLeftSwipe: (Card card, List<Card> cardDeck, int cardsSwiped) =>
debugPrint("Swiped left!"),
onRightSwipe: (Card card, List<Card> cardDeck, int cardsSwiped) =>
debugPrint("Swiped right!"),
cardWidth: 200,
swipeThreshold: MediaQuery.of(context).size.width / 3,
minimumVelocity: 1000,
Expand Down
92 changes: 61 additions & 31 deletions lib/src/swiping_gesture_detector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';


//ignore: must_be_immutable
class SwipingGestureDetector<T> extends StatefulWidget {
SwipingGestureDetector({
Expand All @@ -10,6 +11,7 @@ class SwipingGestureDetector<T> extends StatefulWidget {
required this.swipeLeft,
required this.swipeRight,
required this.cardWidth,
this.onMovement,
this.minimumVelocity = 1000,
this.rotationFactor = .8 / 3.14,
this.swipeAnimationDuration = const Duration(milliseconds: 500),
Expand All @@ -18,6 +20,7 @@ class SwipingGestureDetector<T> extends StatefulWidget {

final List<T> cardDeck;
final Function() swipeLeft, swipeRight;
final Function? onMovement;
final double minimumVelocity;
final double rotationFactor;
final double swipeThreshold;
Expand All @@ -38,7 +41,7 @@ class _SwipingGestureDetector extends State<SwipingGestureDetector>
bool animationActive = false;
late final AnimationController springController;
late Animation<Alignment> spring;

int threshold = 10;
@override
void initState() {
super.initState();
Expand Down Expand Up @@ -73,35 +76,57 @@ class _SwipingGestureDetector extends State<SwipingGestureDetector>
@override
Widget build(BuildContext context) {
final Size screenSize = MediaQuery.of(context).size;
return GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
setState(() {
widget.dragAlignment += Alignment(details.delta.dx, details.delta.dy);
});
},
onPanStart: (DragStartDetails details) async {
if (animationActive) {
springController.stop();
}
},
onPanEnd: (DragEndDetails details) async {
double vx = details.velocity.pixelsPerSecond.dx;
if (vx >= widget.minimumVelocity ||
widget.dragAlignment.x >= widget.swipeThreshold) {
await widget.swipeRight();
} else if (vx <= -widget.minimumVelocity ||
widget.dragAlignment.x <= -widget.swipeThreshold) {
await widget.swipeLeft();
} else {
animateBackToDeck(details.velocity.pixelsPerSecond, screenSize);
}
setState(() {
widget.dragAlignment = Alignment.center;
});
},
child: Stack(
alignment: Alignment.center,
children: topTwoCards(),
return SafeArea(
child: GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
// Identify the movement of the swipe and update the listener accordingly.
late SwipeDirection direction;
double x = widget.dragAlignment.x;
if(x.isNegative){
if(-widget.swipeThreshold > x){
direction = SwipeDirection.left;
}else{
direction = SwipeDirection.none;
}
}else{
if(widget.swipeThreshold < x){
direction = SwipeDirection.right;
}else{
direction = SwipeDirection.none;
}
}

widget.onMovement!(direction);

var left =
setState(() {
widget.dragAlignment += Alignment(details.delta.dx, details.delta.dy);
});
},
onPanStart: (DragStartDetails details) async {
if (animationActive) {
springController.stop();
}
},
onPanEnd: (DragEndDetails details) async {
double vx = details.velocity.pixelsPerSecond.dx;
if (vx >= widget.minimumVelocity ||
widget.dragAlignment.x >= widget.swipeThreshold) {
await widget.swipeRight();
} else if (vx <= -widget.minimumVelocity ||
widget.dragAlignment.x <= -widget.swipeThreshold) {
await widget.swipeLeft();
} else {
animateBackToDeck(details.velocity.pixelsPerSecond, screenSize);
}
setState(() {
widget.dragAlignment = Alignment.center;
});
},
child: Stack(
alignment: Alignment.center,
children: topTwoCards(),
),
),
);
}
Expand All @@ -112,7 +137,7 @@ class _SwipingGestureDetector extends State<SwipingGestureDetector>
const SizedBox(
height: 0,
width: 0,
)
),
];
}
List<Widget> cardDeck = [];
Expand Down Expand Up @@ -170,3 +195,8 @@ class _SwipingGestureDetector extends State<SwipingGestureDetector>
animationActive = false;
}
}


enum SwipeDirection{
none, left, right;
}
23 changes: 14 additions & 9 deletions lib/swiping_card_deck.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ typedef SwipingCardDeck = SwipingDeck<Card>;
class SwipingDeck<T extends Widget> extends StatelessWidget {
SwipingDeck(
{Key? key,
required this.cardDeck,
required this.onLeftSwipe,
required this.onRightSwipe,
required this.onDeckEmpty,
required this.cardWidth,
this.minimumVelocity = 1000,
this.rotationFactor = .8 / 3.14,
this.swipeThreshold,
this.swipeAnimationDuration = const Duration(milliseconds: 500)})
required this.cardDeck,
required this.onLeftSwipe,
required this.onRightSwipe,
required this.onDeckEmpty,
required this.cardWidth,
this.minimumVelocity = 1000,
this.rotationFactor = .8 / 3.14,
this.onMovement,
this.swipeThreshold,
this.swipeAnimationDuration = const Duration(milliseconds: 500)})
: super(key: key) {
cardDeck = cardDeck.reversed.toList();
}
Expand Down Expand Up @@ -58,6 +59,9 @@ class SwipingDeck<T extends Widget> extends StatelessWidget {
/// The [SwipingGestureDetector] used to control swipe animations.
late final SwipingGestureDetector swipeDetector;

/// The listener [Function] function for swipe movement and direction.
late final Function? onMovement;

/// The [Size] of the screen.
late final Size screenSize;

Expand All @@ -72,6 +76,7 @@ class SwipingDeck<T extends Widget> extends StatelessWidget {
cardDeck: cardDeck,
swipeLeft: swipeLeft,
swipeRight: swipeRight,
onMovement: onMovement,
swipeThreshold: swipeThreshold ?? screenSize.width / 4,
cardWidth: cardWidth,
rotationFactor: rotationFactor,
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: swiping_card_deck
description: A widget for swiping through a deck of cards with gestures or buttons.
version: 1.2.0
version: 2.0.0-dev.0
repository: https://github.com/jushutch/swiping_card_deck

environment:
Expand Down
Loading