TransformGestureEvent: Richtung einer Pan-Geste ermitteln

Das Thema Gestures und Multitouch im Flash Player 10.1 und AIR 2 hatte ich bereits vorgestellt. Heute möchte ich im Speziellen auf die „Pan”-Geste eingehen, also das Scrollen mit zwei Fingern (TransformGestureEvent.GESTURE_PAN). Landläufig könnte man es auch als „Wischen” mit 2 Fingern bezeichnen (manchmal auch Swipe, obwohl Adobe darunter die 3-Fingergeste versteht).

Die folgenden Beispielklassen zeigen, wie es möglich, zu erkennen, ob der Nutzer nach rechts, links, oben oder unten gewischt hat.

Dazu habe ich mir eine kleine Hilfsklasse gebaut. Sie wird als Event Handler benutzt und erfasst die Geste. Eine Geste hat 3 Phasen: GesturePhase.BEGIN, GesturePhase.UPDATE und GesturePhase.END. Die Update-Phase wird mehrmals ausgelöst, so ca. 15-20x bei einem „Wisch”.

Zählt man nun, wie oft der Offset zwischen den Events in x- und y-Richtung ungleich 0 ist, erkennt man, in welche Richtung die Finger sich bewegt haben. So bedeutet zum Beispiel offsetX:-1.234 und offsetY:0 eine horizontale Bewegung. Sie wird als „1x horizontal” gespeichert.

Letztendlich kann dann nach Beenden der Geste (GesturePhase.END) ausgewertet werden. Es kommt z.B. 20x horizontal und 3x vertikal als Ergebnis für ein Wischen, woraus man schließen kann, dass der Nutzer horizontal gemeint hat (und die 3x vertikal lediglich eine Ungenauigkeit sind).

Summiert man sich die ganzen Offsets, kann man am Vorzeichen der Summe nun die Richtung erkennen (bei horizontal ob links/rechts, bei vertikal ob oben/unten).

Demo-Klasse

Hier die Demo-Anwendung.

[as]
package
{
import flash.display.Sprite;
import flash.events.GesturePhase;
import flash.events.TransformGestureEvent;
import flash.text.TextField;

public class PanGestureDemo extends Sprite {

private var tf:TextField = new TextField();
private var panGestureDirection:PanGestureDirection = new PanGestureDirection();

public function PanGestureDemo(){
addChild(tf);
tf.x = 20;
tf.y = 20;
tf.width = 300;
tf.height = 50;

panGestureDirection.addEventListener(PanGestureDirectionEvent.LEFT, onLeft);
panGestureDirection.addEventListener(PanGestureDirectionEvent.RIGHT, onRight);
panGestureDirection.addEventListener(PanGestureDirectionEvent.UP, onUp);
panGestureDirection.addEventListener(PanGestureDirectionEvent.DOWN, onDown);

this.stage.addEventListener(TransformGestureEvent.GESTURE_PAN, panGestureDirection.onPanEvent);
}

private function onLeft(evt:PanGestureDirectionEvent):void {
tf.text = „on left“;
}

private function onRight(evt:PanGestureDirectionEvent):void {
tf.text = „on right“;
}

private function onUp(evt:PanGestureDirectionEvent):void {
tf.text = „on up“;
}

private function onDown(evt:PanGestureDirectionEvent):void {
tf.text = „on down“;
}
}
}
[/as]

Klasse zum Erkennen der Pan-Richtung

[as]
package
{
import flash.events.EventDispatcher;
import flash.events.GesturePhase;
import flash.events.TransformGestureEvent;

/**
* Detects the direction of the Pan gesture and dispatches a PanGestureDirectEvent
*
*/
public class PanGestureDirection extends EventDispatcher
{

// count horizontal and vertical gestures
private var countX:int = 0;
private var countY:int = 0;

// sum up the offsets of the pan event
private var sum_offsetX:int = 0;
private var sum_offsetY:int= 0;

public function PanGestureDirection() {
}

/**
* Use this function as event handler for the
* TransformGestureEvent of your object
*
* @param evt
*
*/
public function onPanEvent(evt:TransformGestureEvent):void {

if (evt.phase==GesturePhase.BEGIN) {
}

if (evt.phase==GesturePhase.UPDATE) {
onUpdate(evt.offsetX, evt.offsetY);

}
if (evt.phase==GesturePhase.END) {
dispatchResult();
}
}

/**
* On every update event store the value and count the used direction
* @param offsetX
* @param offsetY
*
*/
private function onUpdate(offsetX:int, offsetY:int):void {
if (offsetX != 0) {
sum_offsetX += offsetX;
countX += 1;

}
if (offsetY != 0) {
sum_offsetY += offsetY;
countY += 1;
}

}

/**
* Detect pan direction and dispatch event
*
*/
public function dispatchResult():void {

var eventType:String = „“;

if (countX > countY) {
// horizontal
if (sum_offsetX > 0) {
eventType = PanGestureDirectionEvent.RIGHT;
} else {
eventType = PanGestureDirectionEvent.LEFT;
}

} else {
// vertical
if (sum_offsetY > 0) {
eventType = PanGestureDirectionEvent.DOWN;
} else {
eventType = PanGestureDirectionEvent.UP;
}
}

reset();

var resultEvent:PanGestureDirectionEvent = new PanGestureDirectionEvent(eventType);
dispatchEvent (resultEvent);

}

/**
* Reset the variables
*
*/
private function reset():void {
sum_offsetX = 0;
sum_offsetY= 0;
countX = 0;
countY = 0;
}

}
}
[/as]

Event

[as]
package
{
import flash.events.Event;

public class PanGestureDirectionEvent extends Event
{

public static const UP:String = „panGestureUp“;
public static const DOWN:String = „panGestureDown“;
public static const RIGHT:String = „panGestureRight“;
public static const LEFT:String = „panGestureLeft“;

public function PanGestureDirectionEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}
[/as]

[ad]

2 Gedanken zu „TransformGestureEvent: Richtung einer Pan-Geste ermitteln“

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert