Creating a custom gesture based upon touchPoint data

Using raw touch data, we can define custom gestures to develop unique interactions used in our application. We do this by making calculations based upon data delivered through raw touch events.

How to do it...

In this example, we will create a diagonal swipe gesture that can have four separate values returned which let us know the direction of a diagonal swipe.

  1. First, import the following classes into your project:
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.TouchEvent;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.ui.Multitouch;
    import flash.ui.MultitouchInputMode;
    
  2. Declare a TextField and TextFormat object to allow visible text output upon the device:
    private var traceField:TextField;
    private var traceFormat:TextFormat;
    
  3. We will set up two additional objects to help track our gestures, a Shape called drawArea to draw out the gestures through the graphics API, and trackBeginObject, which is a simple object we can use to preserve our beginning touch coordinates to compare with the coordinates of our touch end:
    private var drawArea:Shape;
    private var trackBeginObject:Object;
    
  4. We will now set up our TextField, apply a TextFormat, and add it to the DisplayList. Here, we create a method to perform all of these actions for us:
    protected function setupTextField():void {
    traceFormat = new TextFormat();
    traceFormat.bold = true;
    traceFormat.font = "_sans";
    traceFormat.size = 32;
    traceFormat.align = "center";
    traceFormat.color = 0x333333;
    traceField = new TextField();
    traceField.defaultTextFormat = traceFormat;
    traceField.selectable = false;
    traceField.mouseEnabled = false;
    traceField.width = stage.stageWidth;
    traceField.height = stage.stageHeight;
    addChild(traceField);
    }
    
  5. Next, we will set up our Shape within which we will draw out gestures using the Graphics API:
    protected function setupDrawArea():void {
    drawArea = new Shape();
    addChild(drawArea);
    }
    
  6. Set the specific input mode for the multitouch APIs to support touch input by setting Multitouch.inputMode to the MultitouchInputMode.TOUCH_POINT constant. In this example, we will register a set of listeners to detect touch movement on the Stage. This will serve to provide visual feedback for our gesture tracking and also preserve our beginning touch coordinates to compare with the coordinates of our touch end.
  7. We will also initialize out tracking Object through this same method:
    protected function setupTouchEvents():void {
    Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
    trackBeginObject = new Object();
    stage.addEventListener(TouchEvent.TOUCH_BEGIN, touchBegin);
    stage.addEventListener(TouchEvent.TOUCH_MOVE, touchMove);
    stage.addEventListener(TouchEvent.TOUCH_END, touchEnd);
    }
    
  8. Construct a method called touchBegin to initialize the beginning of our gesture and preserve coordinate data for later comparison. We will make sure that the touchpoint being registered is the first touchpoint of what could be multiple by testing against the TouchEvent.isPrimaryTouchPoint boolean property.
    protected function touchBegin(e:TouchEvent):void {
    if(e.isPrimaryTouchPoint){
    drawArea.graphics.clear();
    drawArea.graphics.lineStyle(20, 0xFFFFFF, 0.8);
    trackBeginObject.x = e.stageX;
    trackBeginObject.y = e.stageY;
    drawArea.graphics.moveTo(e.stageX, e.stageY);
    }
    }
    
  9. Construct another method called touchMove to accept the touch movement data and draw out our visual feedback:
    protected function touchMove(e:TouchEvent):void {
    if(e.isPrimaryTouchPoint){
    drawArea.graphics.lineTo(e.stageX, e.stageY);
    }
    }
    
  10. Construct a final method called touchEnd to compare the end touch data coordinates with what we preserved at the beginning through our trackBeginObject and then determine what sort of gesture it is. In this case, we output the results as a String to a TextField, previously created:
    protected function touchEnd(e:TouchEvent):void {
    if(e.isPrimaryTouchPoint){
    if(e.stageX > trackBeginObject.x && e.stageY > trackBeginObject.y){
    traceField.text = "Diagonal Gesture: TL -> BR";
    }elseif(e.stageX < trackBeginObject.x && e.stageY > trackBeginObject.y){
    traceField.text = "Diagonal Gesture: TR -> BL";
    }elseif(e.stageX < trackBeginObject.x && e.stageY < trackBeginObject.y){
    traceField.text = "Diagonal Gesture: BR -> TL";
    }elseif(e.stageX > trackBeginObject.x && e.stageY < trackBeginObject.y){
    traceField.text = "Diagonal Gesture: BL -> TR";
    }
    }
    }
    
  11. The result will appear similar to the following:

Note

Illustrations provided by Gestureworks (www.gestureworks.com).

How it works...

As we have access to all of the raw touchpoint data, we can track the life cycle of a touch interaction from beginning to end with the help of regular ActionScript elements such as Object, Vector, or Array instances. Based upon the data tracked, such as coordinate position, touch pressure, and so forth, we can make calculations and determine whether or not the interaction qualifies as the gesture we are looking to track.

In the case of our preceding example, we are being fairly loose with our determination of a qualifying gesture. To be more stringent, we could also calculate the distance of different touch points and even track the time from touch begin to touch end to be sure the gesture is exactly what we are looking for, and therefor intentional by the user.

There's more...

There are actually quite a few gesture libraries that we can use as alternatives to those built into the Flash Player and AIR runtimes. Performing a quick web search should allow us access to these libraries, many of which are free open source software. The most popular 3rd party gesture library is Gesture Works, which can be downloaded from http://gestureworks.com/.