Here is a quick example of using the build in TransformGestureEvent generated from Flash 10.1 for use on a multitouch supported device. I am going to keep this post short and explain the good and the bad, but a follow up post will use TouchEvents to generate custom gestures that will allow a flow from one gesture to another and also support for multiple gestures at once. You have two options when implementing multitouch in Flash, either through the TouchEvent itself, or through TransformGestureEvents that Flash generates from TouchEvents. The bad is you can have both. At this time, Flash only support one or the other due to the capture used to generate the gesture events internally in Flash. A monster downside to this approach is only one TransformGestureEvent is supported at a time. You will see that if you implement this component, you must release a gesture event, such as a touch to then go into a rotate. As stated above the next post will create custom gesture events in hopes of cloning the Microsoft Surface Collage in Flex. This is to give an basic intro into what it takes to make a simple Gesture based component – if you really want to have fun, download Google maps for flash and add a zoom in / zoom out on the Gesture Zoom Event. Its great that Flash supports gesture events out of the box and the hope is that it will develop as the community develops towards a more multitouch aware development pattern.
package com.justinimhoff.multitouch { import flash.events.MouseEvent; import flash.events.TransformGestureEvent; import flash.geom.Matrix; import flash.geom.Point; import flash.ui.Multitouch; import mx.controls.Image; public class GestureImage extends Image { private var offsetX:Number; private var offsetY:Number; public function GestureImage() { if(Multitouch.supportsGestureEvents){ this.addEventListener(MouseEvent.MOUSE_DOWN, startDragging); this.addEventListener(MouseEvent.MOUSE_UP, stopDragging); this.addEventListener(TransformGestureEvent.GESTURE_ROTATE, onGestureRotate); this.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onGesturePinch); } } private function startDragging(event:MouseEvent):void { setAsCurrentChild(); offsetX = event.stageX - this.x; offsetY = event.stageY - this.y; stage.addEventListener(MouseEvent.MOUSE_MOVE, moveImage); } private function stopDragging(event:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveImage); } private function moveImage(event:MouseEvent):void { this.x = event.stageX - offsetX; this.y = event.stageY - offsetY; event.updateAfterEvent(); } private function onGesturePinch(pinchEvent:TransformGestureEvent):void{ setAsCurrentChild(); var pinchMatrix:Matrix = this.transform.matrix; var pinchPoint:Point = pinchMatrix.transformPoint( new Point((this.width/2), (this.height/2))); pinchMatrix.translate(-pinchPoint.x, -pinchPoint.y); pinchMatrix.scale(pinchEvent.scaleX, pinchEvent.scaleY); pinchMatrix.translate(pinchPoint.x, pinchPoint.y); this.transform.matrix = pinchMatrix; } private function onGestureRotate(rotateEvent:TransformGestureEvent):void { setAsCurrentChild(); var rotateMatrix:Matrix = this.transform.matrix; var rotatePoint:Point = rotateMatrix.transformPoint( new Point((this.width/2), (this.height/2))); rotateMatrix.translate(-rotatePoint.x, -rotatePoint.y); rotateMatrix.rotate(rotateEvent.rotation*(Math.PI/180)); rotateMatrix.translate(rotatePoint.x, rotatePoint.y); this.transform.matrix = rotateMatrix ; } private function setAsCurrentChild():void{ this.parent.setChildIndex( this, this.parent.numChildren-1 ); } } }