How to Detect Swipe Direction Between Left/Right and Up/Down

How to detect swipe direction between left/right and up/down

I wrote a simple class for this: it's well documented so I wont explain it here

public class OnSwipeListener extends GestureDetector.SimpleOnGestureListener {

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

// Grab two events located on the plane at e1=(x1, y1) and e2=(x2, y2)
// Let e1 be the initial event
// e2 can be located at 4 different positions, consider the following diagram
// (Assume that lines are separated by 90 degrees.)
//
//
// \ A /
// \ /
// D e1 B
// / \
// / C \
//
// So if (x2,y2) falls in region:
// A => it's an UP swipe
// B => it's a RIGHT swipe
// C => it's a DOWN swipe
// D => it's a LEFT swipe
//

float x1 = e1.getX();
float y1 = e1.getY();

float x2 = e2.getX();
float y2 = e2.getY();

Direction direction = getDirection(x1,y1,x2,y2);
return onSwipe(direction);
}

/** Override this method. The Direction enum will tell you how the user swiped. */
public boolean onSwipe(Direction direction){
return false;
}

/**
* Given two points in the plane p1=(x1, x2) and p2=(y1, y1), this method
* returns the direction that an arrow pointing from p1 to p2 would have.
* @param x1 the x position of the first point
* @param y1 the y position of the first point
* @param x2 the x position of the second point
* @param y2 the y position of the second point
* @return the direction
*/
public Direction getDirection(float x1, float y1, float x2, float y2){
double angle = getAngle(x1, y1, x2, y2);
return Direction.fromAngle(angle);
}

/**
*
* Finds the angle between two points in the plane (x1,y1) and (x2, y2)
* The angle is measured with 0/360 being the X-axis to the right, angles
* increase counter clockwise.
*
* @param x1 the x position of the first point
* @param y1 the y position of the first point
* @param x2 the x position of the second point
* @param y2 the y position of the second point
* @return the angle between two points
*/
public double getAngle(float x1, float y1, float x2, float y2) {

double rad = Math.atan2(y1-y2,x2-x1) + Math.PI;
return (rad*180/Math.PI + 180)%360;
}


public enum Direction{
up,
down,
left,
right;

/**
* Returns a direction given an angle.
* Directions are defined as follows:
*
* Up: [45, 135]
* Right: [0,45] and [315, 360]
* Down: [225, 315]
* Left: [135, 225]
*
* @param angle an angle from 0 to 360 - e
* @return the direction of an angle
*/
public static Direction fromAngle(double angle){
if(inRange(angle, 45, 135)){
return Direction.up;
}
else if(inRange(angle, 0,45) || inRange(angle, 315, 360)){
return Direction.right;
}
else if(inRange(angle, 225, 315)){
return Direction.down;
}
else{
return Direction.left;
}

}

/**
* @param angle an angle
* @param init the initial bound
* @param end the final bound
* @return returns true if the given angle is in the interval [init, end).
*/
private static boolean inRange(double angle, float init, float end){
return (angle >= init) && (angle < end);
}
}
}

To use simply extend the OnSwipeListener and override the onSwipe method

How to detect Swiping UP, DOWN, LEFT and RIGHT with SwiftUI on a View

Based on Benjamin's answer this is a swiftier way to handle the cases

.gesture(DragGesture(minimumDistance: 3.0, coordinateSpace: .local)
.onEnded { value in
print(value.translation)
switch(value.translation.width, value.translation.height) {
case (...0, -30...30): print("left swipe")
case (0..., -30...30): print("right swipe")
case (-100...100, ...0): print("up swipe")
case (-100...100, 0...): print("down swipe")
default: print("no clue")
}
}
)

Detect swipe direction on Jetpack Compose

Modifier.dragGestureFilter detects dragging in any direction. Pass an instance of DragObserver and override onDrag. Here you can detect the swipe direction based on the Offset. This object has x and y values, which are positive or negative based on the direction.

Here's what your code could look like:

Box(
Modifier.dragGestureFilter(
dragObserver = object : DragObserver() {
override fun onDrag(dragDistance: Offset): Offset {
val (x, y) = dragDistance
when {
x > 0 -> { /* right */ }
x < 0 -> { /* left */ }
}
when {
y > 0 -> { /* down */ }
y < 0 -> { /* up */ }
}
}
}
)
)

To actually move the object, you would have to apply Modifier.offset with values that are updated in onDrag.

Detect swipe gesture direction

I can spot some few problems in your code. It's not a good idea to compare Vector3 with == or !=. Approximate comparison is fine. You are using Input.GetMouseButtonDown on a mobile platform.

You need to use Input.touches to do this. Loop over it, store the beginning position in TouchPhase.Began and then the end position in TouchPhase.Ended. You can then use both variables to figure it which direction the finger went.

The code below detects swipe direction even when the finger is not yet released with the help of TouchPhase.Moved. You can disable that by enabling the detectSwipeOnlyAfterRelease boolean variable. You can also modify SWIPE_THRESHOLD for sensitivity.

public class SwipeDetector : MonoBehaviour
{
private Vector2 fingerDown;
private Vector2 fingerUp;
public bool detectSwipeOnlyAfterRelease = false;

public float SWIPE_THRESHOLD = 20f;

// Update is called once per frame
void Update()
{

foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
fingerUp = touch.position;
fingerDown = touch.position;
}

//Detects Swipe while finger is still moving
if (touch.phase == TouchPhase.Moved)
{
if (!detectSwipeOnlyAfterRelease)
{
fingerDown = touch.position;
checkSwipe();
}
}

//Detects swipe after finger is released
if (touch.phase == TouchPhase.Ended)
{
fingerDown = touch.position;
checkSwipe();
}
}
}

void checkSwipe()
{
//Check if Vertical swipe
if (verticalMove() > SWIPE_THRESHOLD && verticalMove() > horizontalValMove())
{
//Debug.Log("Vertical");
if (fingerDown.y - fingerUp.y > 0)//up swipe
{
OnSwipeUp();
}
else if (fingerDown.y - fingerUp.y < 0)//Down swipe
{
OnSwipeDown();
}
fingerUp = fingerDown;
}

//Check if Horizontal swipe
else if (horizontalValMove() > SWIPE_THRESHOLD && horizontalValMove() > verticalMove())
{
//Debug.Log("Horizontal");
if (fingerDown.x - fingerUp.x > 0)//Right swipe
{
OnSwipeRight();
}
else if (fingerDown.x - fingerUp.x < 0)//Left swipe
{
OnSwipeLeft();
}
fingerUp = fingerDown;
}

//No Movement at-all
else
{
//Debug.Log("No Swipe!");
}
}

float verticalMove()
{
return Mathf.Abs(fingerDown.y - fingerUp.y);
}

float horizontalValMove()
{
return Mathf.Abs(fingerDown.x - fingerUp.x);
}

//////////////////////////////////CALLBACK FUNCTIONS/////////////////////////////
void OnSwipeUp()
{
Debug.Log("Swipe UP");
}

void OnSwipeDown()
{
Debug.Log("Swipe Down");
}

void OnSwipeLeft()
{
Debug.Log("Swipe Left");
}

void OnSwipeRight()
{
Debug.Log("Swipe Right");
}
}

How to recognize swipe in all 4 directions

You need to have one UISwipeGestureRecognizer for each direction. It's a little weird because the UISwipeGestureRecognizer.direction property is an options-style bit mask, but each recognizer can only handle one direction. You can send them all to the same handler if you want, and sort it out there, or send them to different handlers. Here's one implementation:

override func viewDidLoad() {
super.viewDidLoad()

let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))
swipeRight.direction = .right
self.view.addGestureRecognizer(swipeRight)

let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))
swipeDown.direction = .down
self.view.addGestureRecognizer(swipeDown)
}

@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {

if let swipeGesture = gesture as? UISwipeGestureRecognizer {

switch swipeGesture.direction {
case .right:
print("Swiped right")
case .down:
print("Swiped down")
case .left:
print("Swiped left")
case .up:
print("Swiped up")
default:
break
}
}
}

Swift 3:

override func viewDidLoad() {
super.viewDidLoad()

let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
swipeRight.direction = UISwipeGestureRecognizerDirection.right
self.view.addGestureRecognizer(swipeRight)

let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
swipeDown.direction = UISwipeGestureRecognizerDirection.down
self.view.addGestureRecognizer(swipeDown)
}

func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizerDirection.right:
print("Swiped right")
case UISwipeGestureRecognizerDirection.down:
print("Swiped down")
case UISwipeGestureRecognizerDirection.left:
print("Swiped left")
case UISwipeGestureRecognizerDirection.up:
print("Swiped up")
default:
break
}
}
}

How to detect left and right swipes in flutter?

You can detect swipes using the onPanUpdate method from GestureDetector class.

GestureDetector(onPanUpdate: (details) {
if (details.delta.dx > 0)
print("Dragging in +X direction");
else
print("Dragging in -X direction");

if (details.delta.dy > 0)
print("Dragging in +Y direction");
else
print("Dragging in -Y direction");
});

Note: Do not use this method with the ones that you are already using (onVerticalDragDown) or onVerticalDragUpdate().



Related Topics



Leave a reply



Submit