The GestureEvent Class

0
154

A GestureEvent is the interpretation of multiple points as a recognizable pattern. The Flash platform offers three gesture classes: GestureEvent, TransformGestureEvent, and PressAndTapGestureEvent. Gestures cannot be detected in sequence. The user must finish the first gesture, lift her fingers, and then start the next gesture.

Here is how to set a listener for the event type you want to receive:

Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);

Gesture events have a phase property that is used to indicate the progress of the gesture. Its value is BEGIN when the finger is first pressed down; UPDATE while the finger is moving; and END when the finger leaves the screen. Another phase, ALL, is for events such as swipes or two-finger taps, which only return one phase.

A typical use for the phase property is to play one sound when the gesture begins and another sound when it ends:

import flash.ui.MultitouchInputMode;
import flash.events.GesturePhase;
import flash.events.TransformGestureEvent
function onZoom(event:TransformGestureEvent):void {
if (event.phase == GesturePhase.BEGIN) {
// play hello sound
} else if (event.phase == GesturePhase.END) {
// play good bye sound
}
}

Gesture events have other properties related to position, as well as some that are relevant to their particular type. One gesture event, TransformGestureEvent, has many types, which we will discuss in the following subsections.

The Zoom Gesture

The zoom gesture is also referred to as pinching. With this gesture, the user places two fingers on the object, increasing and decreasing the distance between the fingers to scale the object up and down in size (see Figure 7-1).

The zoom gesture

The following code creates a sprite and scales it according to the movement being performed:

import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.display.Sprite;
import flash.events.TransformGestureEvent;
var sprite:Sprite;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
sprite = new Sprite();
sprite.x = stage.stageWidth * 0.5;
sprite.y = stage.stageHeight * 0.5;
var g:Graphics = sprite.graphics;
g.beginFill(0xFF6600);
g.drawCircle(0, 0, 150);
g.endFill();
sprite.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
sprite.x = stage.stageWidth * 0.5;
sprite.y = stage.stageHeight * 0.5;
function onZoom(event:TransformGestureEvent):void {
sprite.scaleX *= event.scaleX;
sprite.scaleY *= event.scaleY;
}

The event.scaleX and event.scaleY values are used to calculate the relative distance between the two fingers.

The Rotate Gesture

You can rotate an object using two different gestures. With the first gesture, you place one finger on the object and move the second finger around it. With the second gesture, you spread the two fingers apart and rotate one clockwise and the other counterclockwise (see Figure 7-2). The latter seems to work better on small devices.

The rotate gesture

Here we use the drawing API to create a sprite with a rectangle shape:

import flash.display.Sprite;
import flash.events.TransformGestureEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
var sprite:Sprite;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
sprite = new Sprite();
sprite.x = stage.stageWidth * 0.5;
sprite.y = stage.stageHeight * 0.5;
var g:Graphics = sprite.graphics;
g.beginFill(0xFF6600);
g.drawRect(-150, -150, 300, 300);
g.endFill();
sprite.addEventListener(TransformGestureEvent.GESTURE_ROTATE, onRotate);
sprite.x = stage.stageWidth * 0.5;
sprite.y = stage.stageHeight * 0.5;
function onRotate(event:TransformGestureEvent):void {
event.currentTarget.rotation += event.rotation;
}

The event.rotation value is the cumulated rotation change relative to the position of the stage. Notice how I drew the rectangle so that it is centered in the middle of the sprite. The default position is top left, so offset your art to have its registration point in the center of the pixels.

The following code moves the child sprite to be offset by half its dimension:

someParent.x = 0;
someParent.y = 0;
someChild.x = – someChild.width * 0.5;
someChild.y = – someChild.height * 0.5;

Bitmaps are also offset according to the dimension of their bitmapData:

var bitmapData:BitmapData = new BitmapData();
var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.x = – bitmapData.width * 0.5;
bitmap.y = – bitmapData.height * 0.5;

The Pan Gesture

You use a pan gesture to reveal an object that is off-screen if it is larger than the screen. The use of two fingers is not immediately intuitive. This gesture seems to work best when using a light touch. Figure 7-3 shows an example.

The pan gesture

In this example, we are drawing a 1,000-pixel-long rectangle with a sine wave on it. The wave is so that you can see the sprite move when you pan:

Multitouch.inputMode = MultitouchInputMode.GESTURE;
var sprite:Sprite;
function createArt():void {
sprite = new Sprite();
addChild(sprite);
var g:Graphics = sprite.graphics;
g.beginFill(0xFFCCFF);
g.drawRect(0, 550, 1000, 200);
g.endFill();
g.lineStyle(3, 0xFF0000);
// 650 is an arbitrary pixel position
g.moveTo(2, 650);
// draw a sin wave
var xpos:Number = 0;
var ypos:Number = 0;
var angle:Number = 0;
for (var i:int = 0; i < 200; i++) {
xpos += 5;
ypos = Math.sin(angle)*100 + 650;
angle += 0.20;
sprite.graphics.lineTo (xpos, ypos);
}
stage.addEventListener(TransformGestureEvent.GESTURE_PAN, onPan);
}
function onPan(event:TransformGestureEvent):void {
// move the sprite along with the motion
sprite.x += event.offsetX;
}

offsetX is the horizontal magnitude of change since your finger made contact with the screen as it is moving across the screen.

The Swipe Gesture

A swipe gesture is often used as a way to dismiss an element as though you are pushing it off-screen. The direction of the swipe is defined by a single integer. Left to right and bottom to top returns ‒1. Right to left and bottom to top returns 1. Figure 7-4 shows an example of the swipe gesture.

The swipe gesture

The following code simulates the act of reading a book. Swiping from left to right brings you further in the book. Swiping in the other direction returns you to the beginning of the book:

import flash.events.TransformGestureEvent;
import flash.text.TextField;
import flash.text.TextFormat;
var pageText:TextField;
var counter:int = 1;
function createArt():void {
var textFormat:TextFormat = new TextFormat();
textFormat.size = 90;
textFormat.color = 0xFF6600;
// create a text field to display the page number
pageText = new TextField();
pageText.x = 100;
pageText.y = 200;
pageText.autoSize = TextFieldAutoSize.LEFT;
pageText.defaultTextFormat = textFormat;
pageText.text = “Page ” + counter;
addChild(pageText);
// create a listener for a swipe gesture
stage.addEventListener(TransformGestureEvent.GESTURE_SWIPE, onSwipe);
}
function onSwipe(event:TransformGestureEvent):void {
counter -= event.offsetX;
if (counter < 1) counter = 1;
pageText.text = “Page ” + counter;
}

The offsetX value is used to decrement or increment the page number of the book.

The Press and Tap Gesture

The press and tap gesture, PressAndTapGestureEvent, only has one type: GESTURE_PRESS_AND_TAP. This gesture is more complicated than the others, and users may not figure it out without instructions. Unlike the previous gestures, this gesture happens in two steps: first one finger is pressed and then another finger taps (see Figure 7-5). It is really two events synthesized as one.

The press and tap gestureThe following code creates an elegant UI for selecting a menu and then tapping to access its submenu, as a context menu:

import flash.events.PressAndTapGestureEvent;
stage.addEventListener(PressAndTapGestureEvent.GESTURE_PRESS_AND_TAP,
onPressAndTap);
function onPressAndTap(event:PressAndTapGestureEvent):void {
trace(event.tapLocalX);
trace(event.tapLocalY);
trace(event.tapStageX);
trace(event.tapStageY);
}

The Two-Finger Tap Gesture

GestureEvent only has one type, GESTURE_TWO_FINGER_TAP, and it is not supported by Android at the time of this writing. A tap is similar to a mouse click, but it requires making contact on a limited spatial area, with the two fingers close together, in a short time period. Figure 7-6 shows an example of a two-finger tap.

The two-finger tap gestureThe two-finger tap is a good gesture for a strong statement, as when you want the user to make a decision. You could use it, for instance, to pause and play a video:

import flash.events.PressAndTapGestureEvent;
sprite.addEventListener(GestureEvent.GESTURE_TWO_FINGER_TAP, onTwoFinger);
function onTwoFinger(event:GestureEvent):void {
// play or pause video
}