この回答には、機能の一部を再利用するために問題を抽象化するのに役立つ、私が書いた 2 つのクラス (興味深い) が含まれています。問題を理解することはそれほど重要ではありませんが、ここにも ToolBase を含めました。基本的に、MultiTouchTool.as は、TouchEvents をキャプチャし、オブジェクトでそれらを追跡するように設定されています。また、ユース ケースで知っておく必要があるいくつかの一般的なアクションに基づいていくつかのメソッドを呼び出します (このクラスを拡張し、必要なメソッドをオーバーライドするだけです)。フック)。
主要な要素は NavigatorTool.as にあり、オブジェクトの元の変換マトリックスを使用して変換を調整し、スケーリングを行ってから変換を再調整します。これにより、登録ポイントが効果的に移動しました。そのため、画像が左上にシフトされ、2 本の指の間の点が左上になり、画像が拡大縮小され、位置がリセットされます。スケーリングは段階的に行われるため、intialDistance を更新し続けます (名前が誤解を招く可能性があります)。
私の場合、Sprite である layerM というオブジェクトをスケーリングしていますが、どの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";
}
}
}
[NavigatorTool.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;
}
}
}
[ToolBase.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;
}
}
}