情况
我编写了以下方法(在 actionscript 3 中,它是一个 flash 应用程序),它返回当前鼠标位置相对于给定元素位置所需的转换类型。
可以移动、缩放和旋转元素。如果这些转换中的任何一个适用于给定坐标,则此方法返回:
(不用担心,您不需要调试此方法,它可以工作 - 只需将其添加到此处,以便您了解我在做什么)
//returns whether the mouse is at a transforming position
private static function mouseAtTransformPosition(cX:Number, cY:Number, eX:Number, eY:Number, eW:Number, eH:Number, margin:Number):String
{
//initialize the transformation type
var transformType:String = null;
//set the transformation type depending on the given coordinates
if ((cX > eX) && (cX < eX + eW) && (cY > eY) && (cY < eY + eH))
{
transformType = "mover";
}
else if ((cX > eX) && (cX < eX + eW) && (cY <= eY) && (cY >= eY - margin))
{
transformType = "scalerUp";
}
else if ((cX >= eX + eW) && (cX <= eX + eW + margin) && (cY > eY) && (cY < eY + eH))
{
transformType = "scalerRight";
}
else if ((cX > eX) && (cX < eX + eW) && (cY >= eY + eH) && (cY <= eY + eH + margin))
{
transformType = "scalerDown";
}
else if ((cX <= eX) && (cX >= eX - margin) && (cY > eY) && (cY < eY + eH))
{
transformType = "scalerLeft";
}
else if ((cX >= eX - margin) && (cX <= eX) && (cY >= eY - margin) && (cY <= eY))
{
transformType = "scalerUpLeft";
}
else if ((cX >= eX + eW) && (eX <= eX + eW + margin) && (cY >= eY - margin) && (cY <= eY))
{
transformType = "scalerUpRight";
}
else if ((cX >= eX + eW) && (cX <= eX + eW + margin) && (cY >= eY + eH) && (cY <= eY + eH + margin))
{
transformType = "scalerDownRight";
}
else if ((cX >= eX - margin) && (cX <= eX) && (cY >= eY + eH) && (cY <= eY + eH + margin))
{
transformType = "scalerDownLeft";
}
else if ((cX >= eX - margin * 2) && (cX <= eX) && (cY >= eY - margin * 2) && (cY <= eY))
{
transformType = "rotatorTopLeft";
}
else if ((cX >= eX + eW) && (cX <= eX + eW + margin * 2) && (cY >= eY - margin * 2) && (cY <= eY))
{
transformType = "rotatorTopRight";
}
else if ((cX >= eX + eW) && (cX <= eX + eW + margin * 2) && (cY >= eY + eH) && (cY <= eY + eH + margin * 2))
{
transformType = "rotatorBottomRight";
}
else if ((cX >= eX - margin * 2) && (cX <= eX) && (cY >= eY + eH) && (cY <= eY + eH + margin * 2))
{
transformType = "rotatorBottomLeft";
}
//return the found transformation type
return transformType;
}
详细说明所需的所有参数:
cX: cursor X position
cY: cursor Y position
eX: element X position
eY: element Y position
eW: element width
eH: element height
margin: how far the cursor can be removed from an exact transformation location to still be applicable
如果没有适用的转换,它将返回 null。
问题
现在,我的功能似乎很好用。现在问题出现了,因为我正在向需要转换的元素引入旋转。
旋转元素时,角会移动到不同的位置。光标现在必须位于不同的位置才能根据情况获得相同的转换类型,就像我上面的方法一样(如果没有旋转):
cursor is...
inside the element -> move
at top of element -> scale up
at right of element -> scale right
at bottom of element -> scale down
at left of element -> scale left
at top left of element -> scale up-left
at top right of element -> scale up-right
at bottom left of element -> scale down-left
at bottom right of element -> scale down-right
further top left of element -> rotate right/left
further top right of element -> rotate right/left
further bottom right of element -> rotate right/left
further bottom left of element -> rotate right/left
问题
如果没有旋转,我的方法可以完美地做到这一点。但是,如何更改此功能以考虑旋转,例如角坐标的变化?
贾斯汀的更新
//checks whether mouse transforming is applicable
private static function checkMouseTransforming(cX:Number, cY:Number, render:Sprite):void
{
//temp disable rotation to get accurate width/height, x and y
var realRotation:Number = render.getChildAt(0).rotation;
render.getChildAt(0).rotation = 0;
var eX:Number = render.x;
var eY:Number = render.y;
var eW:Number = render.width;
var eH:Number = render.height;
var margin:uint = 10;
//restore real rotation
render.getChildAt(0).rotation = realRotation;
cX -= eX + eW / 2;
cY -= eY + eH / 2;
var theta:Number = render.getChildAt(0).rotation * Math.PI / 180;
var newcX:Number = Math.cos(theta) * cX - Math.sin(theta) * cY;
var newcY:Number = Math.sin(theta) * cX + Math.cos(theta) * cY;
newcX += eX + eW / 2;
newcY += eY + eH / 2;
var transformType:String = mouseAtTransformPosition(newcX, newcY, eX, eY, eW, eH, margin);
if (transformType)
{
//...
}
如您所见,旋转是从渲染对象的子对象设置和接收的。这是因为实际的对象是一个 positionWrapper 并且在这个包装器内部有一个 rotationWrapper (旋转设置为)并且在该包装器内部实际的可见元素仍然存在。位置包装的 x、y、宽度和高度始终等于可见显示对象的 x、y、宽度和高度,因此这不会引起问题。
现在,这些是结果:
- 没有旋转,一切都按预期工作
- 当我将鼠标悬停在视觉显示对象上时,旋转大约 45 圈:
- 底部中心:它返回“scalerLeft”,而它应该返回“scalerDown”
- 右中心:它返回scalerDown,而它应该返回scalerRight
- 顶部中心:它返回 scalerRight,而它应该返回 scalerUp
- 左中心:它返回scalerUp,而它应该返回scalerLeft(注意这里的偏移模式)
- 搬运工似乎很准确地返回
- 旋转器似乎返回到角落的直接底部,而不是它应该返回的位置
- bottomLeft 缩放器似乎在右下角返回,我认为这个相同的偏移量是问题所在,并且可能对于所有其他缩放器也是相同的
这是一个调试错误,但也许这会有所帮助。
Justin alt text http://feedpostal.com/transformBug.gif的更新 #2 偏移量/错误似乎越强,旋转越高。旋转为 0 时,不会出现此错误。
这对您或其他人有意义吗?提前致谢。