这个答案包括我编写的两个类(感兴趣的),它们有助于抽象问题以重用某些功能。我在这里也包括了 ToolBase,尽管理解这个问题并不重要。基本上 MultiTouchTool.as 设置为捕获 TouchEvents 并在对象中跟踪它们,它还根据我的用例需要了解的一些常见操作调用一些方法(我只是扩展这个类并覆盖我想要的方法挂钩)。
然后关键元素在 NavigatorTool.as 中,它使用对象原始变换矩阵并调整平移,然后进行缩放,然后重新调整平移。这有效地移动了注册点。所以图像向上和向左移动,所以两个手指之间的点现在位于左上角,然后图像被缩放并重置它的位置。由于缩放是以增量方式发生的,因此我不断更新 intialDistance(名称可能具有误导性)。
在我的例子中,我正在缩放一个名为 layerM 的对象,它是一个 Sprite,但任何DisplayObject都可以工作。
[MultiTouchTool.as]
package com.shaunhusain.fingerPainting.tools
{
import flash.display.Stage;
import flash.events.TouchEvent;
import flash.geom.Point;
public class MultiTouchTool extends ToolBase implements ITool
{
protected var pointsTracked:Number = 0;
protected var ptsTracked:Object;
public function MultiTouchTool(stage:Stage)
{
super(stage);
ptsTracked = {};
}
public function takeAction(event:TouchEvent=null):void
{
switch(event.type)
{
case TouchEvent.TOUCH_BEGIN:
ptsTracked[event.touchPointID] = new Point(event.stageX, event.stageY);
pointsTracked++;
if(pointsTracked>1)
secondFingerDown();
break;
case TouchEvent.TOUCH_MOVE:
switch(pointsTracked)
{
case 1:
oneFingerMoving(event);
break;
case 2:
twoFingersMoving(event);
break;
}
ptsTracked[event.touchPointID] = new Point(event.stageX, event.stageY);
break;
case TouchEvent.TOUCH_END:
case TouchEvent.TOUCH_ROLL_OUT:
switch(pointsTracked)
{
case 1:
oneFingerEnd();
break;
case 2:
twoFingerEnd();
break;
}
ptsTracked[event.touchPointID] = null;
pointsTracked--;
if(pointsTracked<0)
pointsTracked = 0;
break;
}
}
protected function oneFingerEnd():void
{
trace("default handler for one finger end, not overridden");
}
protected function twoFingerEnd():void
{
trace("default handler for two finger end, not overridden");
}
protected function oneFingerMoving(event:TouchEvent):void
{
trace("default handler for one finger moving, not overridden");
}
protected function twoFingersMoving(event:TouchEvent):void
{
trace("default handler for two fingers moving, not overridden");
}
protected function secondFingerDown():void
{
trace("default handler for second finger down, not overridden");
}
public function toString():String
{
return "Multi-Touch tool";
}
}
}
[导航工具.as]
package com.shaunhusain.fingerPainting.tools
{
import flash.display.Stage;
import flash.events.TouchEvent;
import flash.geom.Matrix;
import flash.geom.Point;
/**
* Allows the layer manager to be panned and zoomed on, other tools are
* responsible for taking into account the current zoom and pan position
* when modifying the layers.
*/
public class NavigationTool extends MultiTouchTool implements ITool
{
private var initialDistance:Number;
private var newDistance:Number;
private var layerLocal:Point;
//--------------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------------
public function NavigationTool(stage:Stage)
{
super(stage);
}
override public function toString():String
{
return "Navigation";
}
//--------------------------------------------------------------------------------
// Overrides
//--------------------------------------------------------------------------------
override protected function oneFingerMoving(event:TouchEvent):void
{
var currentTouchPrevPos:Point = ptsTracked[event.touchPointID];
var offset:Point = new Point(event.stageX-currentTouchPrevPos.x,event.stageY-currentTouchPrevPos.y);
layerM.x += offset.x;
layerM.y += offset.y;
}
override protected function twoFingersMoving(event:TouchEvent):void
{
if(isNaN(initialDistance))
{
initialDistance = Point.distance(ptsTracked[0],ptsTracked[1]);
layerLocal = new Point((ptsTracked[0].x+ptsTracked[1].x)/2,(ptsTracked[0].y+ptsTracked[1].y)/2);
}
else
{
newDistance = Point.distance(ptsTracked[0],ptsTracked[1]);
var matrix:Matrix = layerM.transform.concatenatedMatrix.clone();
matrix.tx -= layerLocal.x;
matrix.ty -= layerLocal.y;
matrix.scale(newDistance/initialDistance,newDistance/initialDistance);
matrix.tx += layerLocal.x;
matrix.ty += layerLocal.y;
layerM.transform.matrix = matrix;
initialDistance = newDistance;
}
}
override protected function twoFingerEnd():void
{
initialDistance = NaN;
}
}
}
[工具库.as]
package com.shaunhusain.fingerPainting.tools
{
import com.shaunhusain.fingerPainting.view.managers.LayerManager;
import com.shaunhusain.fingerPainting.view.managers.SecondaryPanelManager;
import com.shaunhusain.fingerPainting.managers.UndoManager;
import com.shaunhusain.fingerPainting.model.PaintModel;
import flash.display.Stage;
/**
* Base class for tools to give them all easy access to the Singletons and
* the Stage.
*/
public class ToolBase
{
//--------------------------------------------------------------------------------
// Variables
//--------------------------------------------------------------------------------
protected var model:PaintModel = PaintModel.getInstance();
protected var undoManager:UndoManager = UndoManager.getIntance();
protected var secondaryPanelManager:SecondaryPanelManager = SecondaryPanelManager.getIntance();
protected var layerM:LayerManager = LayerManager.getIntance();
protected var stage:Stage;
//--------------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------------
public function ToolBase(stage:Stage)
{
this.stage = stage;
}
}
}