weyforth - 09 June 2008 01:38 PM
I’m using the dynamic registration class
I tried this solution after I read this post, but I had many problems. I suppose that you use this class DYNAMIC MOVIECLIP REGISTRATION WITH AS3
In Flex the scaleX2 and scaleY2 doesn’t work, but I found a fix. If any is trying to use DynamicMovieClip in Flex, this is my fix:
public function setProperty2(prop:String, n:Number):void
{
var a:Point = this.parent.globalToLocal(this.localToGlobal(rp));
this[prop] = n;
// La propiedad de rotación pertenece a DisplayObject y hace el render
// de inmediato, mientras que las propiedades scaleX y scaleY pertenecen
// a UIComponent y el render no se hace de inmediato
if (prop == "rotation") finishSetProperty(a);
else callLater(finishSetProperty, [a]);
}
private function finishSetProperty(a:Point):void
{
var b:Point = this.parent.globalToLocal(this.localToGlobal(rp));
this.x -= b.x - a.x;
this.y -= b.y - a.y;
}
I had other problems whit DynamicMovieClip, so I tried another solution and use matrix transformations. I rewrite the RotateScale class and extends Multitouchable. There is the important part of the code of RotateScale, so others can implement my solution. The function doTransform has the code that translate, rotate and scale around an internal point:
public override function handleDownEvent(id:int, mx:Number, my:Number,
targetObj:Object):void
{
var curPt1:Point, curPt2:Point;
// Si solo hay un blob en el control, se pasa al estado dragging, para
// indicar que el control se va a mover
if (blobs.length == 1)
{
state = "dragging";
blob1 = blobs[0];
// La posición de los blob están definidas con respecto al origen del
// control y se deben convertir a las coordenadas del control padre
curPt1 = this.localToParent( new Point(blob1.x, blob1.y) );
blob1.oldX = curPt1.x;
blob1.oldY = curPt1.y;
// Si hay dos blob en el control, se pasa al estado rotatescale, para
// indicar que el control se va a rotar y escalar
}
else if(blobs.length == 2)
{
state = "rotatescale";
blob1 = blobs[0];
curPt1 = this.localToParent( new Point(blob1.x, blob1.y) );
blob1.oldX = curPt1.x;
blob1.oldY = curPt1.y;
blob2 = blobs[1];
curPt2 = this.localToParent( new Point(blob2.x, blob2.y) );
blob2.oldX = curPt2.x;
blob2.oldY = curPt2.y;
}
}
public override function handleMoveEvent(id:int, mx:Number, my:Number,
targetObj:Object):void
{
var dx:Number = 0;
var dy:Number = 0;
var da:Number = 0;
var ds:Number = 1;
if (state == "dragging")
{
if(this._moveEnabled)
{
var tuioObj:TUIOObject = TUIO.getObjectById(blob1.id);
if (!tuioObj)
{
handleBlobRemoved(blob1.id);
return;
}
var curPt:Point = parent.globalToLocal(new Point(tuioObj.x, tuioObj.y));
dx = curPt.x - blob1.oldX;
dy = curPt.y - blob1.oldY;
blob1.oldX = curPt.x;
blob1.oldY = curPt.y;
this.doTransform(dx, dy, 0, 1);
}
}
else if (state == "rotatescale")
{
var tuioObj1:TUIOObject = TUIO.getObjectById(blob1.id);
if (!tuioObj1)
{
handleBlobRemoved(blob1.id);
return;
}
var curPt1:Point = parent.globalToLocal(new Point(tuioObj1.x, tuioObj1.y));
var tuioObj2:TUIOObject = TUIO.getObjectById(blob2.id);
if (!tuioObj2)
{
handleBlobRemoved(blob2.id);
return
}
var curPt2:Point = parent.globalToLocal(new Point(tuioObj2.x, tuioObj2.y));
// Halla el centro entre los dos blob en coordenadas locales del
// componente padre
var curCenter:Point = Point.interpolate(curPt1, curPt2, 0.5);
// Obtiene el punto de registro sobre el que se hará la rotación y
// el escalado y lo convierte a coordenadas locales para asignarlo
var regPt:Point = this.globalToLocal(this.parent.localToGlobal(curCenter));
this.setRegistration(regPt.x, regPt.y);
if (this._moveEnabled)
{
// Obtiene el centro anterior en coordenadas del componente padre
var oldPt1:Point = new Point(blob1.oldX, blob1.oldY);
var oldPt2:Point = new Point(blob2.oldX, blob2.oldY);
var oldCenter:Point = Point.interpolate(oldPt1, oldPt2, 0.5);
dx = curCenter.x - oldCenter.x;
dy = curCenter.y - oldCenter.y;
}
if (this._rotateEnabled)
{
// Halla una línea con origen en la posición 0,0 del componente padre y
// paralela a la línea formada por la posición anterior de los blob
var oldLine:Point = oldPt1;
oldLine = oldLine.subtract(oldPt2);
var oldAngle:Number = getAngleTrig(oldLine.x, oldLine.y);
// Halla una línea con origen en la posición 0,0 del componente padre y
// paralela a la línea formada por la posición actual de los blob
var curLine:Point = curPt1;
curLine = curLine.subtract(curPt2);
var curAngle:Number = getAngleTrig(curLine.x, curLine.y);
da = curAngle - oldAngle;
}
if (this._scaleEnabled)
{
// Halla la distancia entre las posiciones de los blob anteriores
// y los blob actuales para determinar la escala
var oldLenght:Number = Point.distance(oldPt1, oldPt2);
var curLenght:Number = Point.distance(curPt1, curPt2);
ds = curLenght / oldLenght;
}
this.doTransform(dx, dy, da, ds);
// Los puntos actuales se convierten en las coordenadas viejas
// para el siguiente ciclo
blob1.oldX = curPt1.x;
blob1.oldY = curPt1.y;
blob2.oldX = curPt2.x;
blob2.oldY = curPt2.y;
}
}
public function doTransform(dx:Number, dy:Number, da:Number, ds:Number):void
{
var matrix:Matrix = new Matrix();
// Configura la matriz de transformación y la concatena con la matriz del
// componente.
matrix.translate(-this._x2, -this._y2);
matrix.rotate(da * Math.PI / 180);
matrix.scale(ds, ds);
matrix.translate(this._x2, this._y2);
matrix.concat(this.transform.matrix);
matrix.translate(dx, dy);
this.transform.matrix = matrix;
}
public function setRegistration(x:Number, y:Number):void
{
this._x2 = x;
this._y2 = y;
}
private function localToParent(pt:Point):Point
{
return parent.globalToLocal(this.localToGlobal(pt));
}