New gesture for free transformation

more precise and performant then combination of 3
This commit is contained in:
Pavel fljot 2012-03-06 01:22:42 +02:00
parent 5f28227c75
commit b922057845

View file

@ -0,0 +1,187 @@
package org.gestouch.gestures
{
import org.gestouch.core.GestureState;
import org.gestouch.core.Touch;
import org.gestouch.events.TransformGestureEvent;
import org.gestouch.utils.GestureUtils;
import flash.display.InteractiveObject;
import flash.geom.Point;
[Event(name="gestureTransform", type="org.gestouch.events.TransformGestureEvent")]
/**
* @author Pavel fljot
*/
public class TransformGesture extends Gesture
{
public var slop:Number = Gesture.DEFAULT_SLOP;
protected var _touch1:Touch;
protected var _touch2:Touch;
protected var _transformVector:Point;
public function TransformGesture(target:InteractiveObject = null)
{
super(target);
}
// --------------------------------------------------------------------------
//
// Public methods
//
// --------------------------------------------------------------------------
override public function reflect():Class
{
return TransformGesture;
}
override public function reset():void
{
_touch1 = null;
_touch2 = null;
super.reset();
}
// --------------------------------------------------------------------------
//
// Protected methods
//
// --------------------------------------------------------------------------
override protected function onTouchBegin(touch:Touch):void
{
if (touchesCount > 2)
{
//TODO: to ignore or to keep this touch somewhere?
ignoreTouch(touch);
return;
}
if (touchesCount == 1)
{
_touch1 = touch;
}
else
{
_touch2 = touch;
_transformVector = _touch2.location.subtract(_touch1.location);
}
updateLocation();
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
if (setState(GestureState.CHANGED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
}
}
override protected function onTouchMove(touch:Touch):void
{
var prevLocation:Point = _location.clone();
updateLocation();
var recognized:Boolean = true;
if (state == GestureState.POSSIBLE && slop > 0 && touch.locationOffset.length < slop)
{
recognized = false;
}
if (recognized)
{
var prevLocalLocation:Point;
var offsetX:Number = _location.x - prevLocation.x;
var offsetY:Number = _location.y - prevLocation.y;
var scale:Number = 1;
var rotation:Number = 0;
if (_touch2)
{
var currTransformVector:Point = _touch2.location.subtract(_touch1.location);
rotation = Math.atan2(currTransformVector.y, currTransformVector.x) - Math.atan2(_transformVector.y, _transformVector.x);
rotation *= GestureUtils.RADIANS_TO_DEGREES;
scale = currTransformVector.length / _transformVector.length;
_transformVector = _touch2.location.subtract(_touch1.location);
}
if (state == GestureState.POSSIBLE)
{
if (setState(GestureState.BEGAN) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
// Note that we dispatch previous location point which gives a way to perform
// accurate UI redraw. See examples project for more info.
prevLocalLocation = target.globalToLocal(prevLocation);
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.BEGAN,
prevLocation.x, prevLocation.y, prevLocalLocation.x, prevLocalLocation.y, scale, scale, rotation, offsetX, offsetY));
}
}
else
{
if (setState(GestureState.CHANGED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
// Note that we dispatch previous location point which gives a way to perform
// accurate UI redraw. See examples project for more info.
prevLocalLocation = target.globalToLocal(prevLocation);
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.CHANGED,
prevLocation.x, prevLocation.y, prevLocalLocation.x, prevLocalLocation.y, scale, scale, rotation, offsetX, offsetY));
}
}
}
}
override protected function onTouchEnd(touch:Touch):void
{
if (touchesCount == 0)
{
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
if (setState(GestureState.ENDED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
}
else if (state == GestureState.POSSIBLE)
{
setState(GestureState.FAILED);
}
}
else// == 1
{
if (touch == _touch1)
{
_touch1 = _touch2;
}
_touch2 = null;
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
updateLocation();
if (setState(GestureState.CHANGED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
}
}
}
}
}