问题
i have a darkBlueRect
rectangle sprite and a copy of the same sprite with a larger scale and a lighter color - lightBlueRect
.
i'm attempting to shift the location of the lightBlueRect
according to the mouse.x
location when the mouse is moving over the darkBlueRect
. this way if the mouse is on the right of the darkBlueRect
than the location of the scaled up lightBlueRect
will be on the opposite side and shifted towards the left proportionate to the mouse position and scale. in addition, the lightBlueRect
must appear "locked" to the darkBlueRect
so lightBlueRect.x
must never be more than darkBlueRect.x
and lightBlueRect.x + lightBlueRect.width
must never be less than darkBlueRect.x + darkBlueRect.width
.
the image below depicts 3 states of what i'm attempting to accomplish:
- State A:
mouse.x
is overdarkBlueRect.x = 1
and both sprites are aligned to the left. - State B:
mouse.x
is in the middle ofdarkBlueRect
and both sprites are aligned to the middle. - State C:
mouse.x
is on the last pixel ofdarkBlueRect
and both sprites are aligned to the right.
for this example, the darkBlueRect.width
is equal to 170
and the lightBlueRect.width
is equal to 320
, or a scale of 1.89
.
each time the mouse changes it's x
position over darkBlueRect
the following is called. however, while my current code works for the most part, it's not exactly correct. when the mouse.x
is over darkBlueRect.x = 1
, as shown in State A, the lightBlueRect.x
is not property aligned with darkBlueRect
and appears less than darkBlueRect.x
.
var scale:Number = 1.89;
lightBlueRect.x = darkBlueRect.x - Math.round((mouse.x * scale) / darkBlueRect.width * (lightBlueRect.width - darkBlueRect.width));
what equation can i use so that no matter the scale of the lightBlueRect
it's first position (mouse over first pixel) and last position (mouse over last pixel) will result in the 2 sprites being aligned as well as property proportionate positioning in between?
[EDIT] the coordinates of the darkBlueRect is {0, 0}, so when the lightBlueRect moves towards the left it is moving into the negative. i could have simply written my code (what doesn't work) like this instead:
var scale:Number = 1.89;
lightBlueRect.x = 0 - Math.round((mouse.x * scale) / darkBlueRect.width * (lightBlueRect.width - darkBlueRect.width));
[EDIT 2] when the display objects are small, the problem is difficult to notice. however, when they are large the problem becomes move obvious. the problem, here, being that the objects on the left side are misaligned.
also the problem is probably exasperated by the fact that both the lightBlueRect
and darkBlueRect
are scalable. darkBlueRect
is scaled down and lightBlueRect
is scaled up.
here is a link to the test displaying the problem. mousing over the shape quickly will obviously result in inaccurate alignment since it's based on frame rate speed, but this is not my concern. still, when you slowly mouse over the shape it will not align correctly on the left side when the mouse is over the first pixel of darkBlueRect
: http://www.geoffreymattie.com/test/test.html
[SWF(width = "1000", height = "600", backgroundColor = "0xCCCCCC")]
import flash.display.Sprite;
import flash.events.MouseEvent;
var downScale:Number = 0.48;
var upScale:Number = 2.64;
var darkBlueRect:Sprite = createSprite();
darkBlueRect.scaleX = darkBlueRect.scaleY = downScale;
darkBlueRect.x = stage.stageWidth / 2 - darkBlueRect.width / 2;
darkBlueRect.y = stage.stageHeight / 2 - darkBlueRect.height / 2;
addChild(darkBlueRect);
var lightBlueRect:Sprite = createSprite();
lightBlueRect.scaleX = lightBlueRect.scaleY = upScale;
lightBlueRect.y = stage.stageHeight / 2 - lightBlueRect.height / 2;
lightBlueRect.x = stage.stageWidth;
lightBlueRect.mouseEnabled = false;
addChild(lightBlueRect);
darkBlueRect.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
function mouseMoveEventHandler(evt:MouseEvent):void
{
lightBlueRect.x = darkBlueRect.x + Math.max(0.0, Math.min(darkBlueRect.mouseX / darkBlueRect.width * downScale, 1.0)) * (darkBlueRect.width - lightBlueRect.width);
}
function createSprite():Sprite
{
var result:Sprite = new Sprite();
result.graphics.beginFill(0x0000FF, 0.5);
result.graphics.drawRect(0, 0, 700, 200);
result.graphics.endFill();
return result;
}
i believe the problem is that the scaling of the shapes.
回答1:
Assuming you have a Clamp
function handy, and that width
is floating-point so that division works as expected:
lBR.x = dBR.x + Clamp((mouse.x - dBR.x) / dBR.width, 0, 1) * (dBR.width - lBR.width);
(You can define Clamp(x, m, M) = min(max(x, m), M)
if you don't have one.)
来源:https://stackoverflow.com/questions/6855190/setting-x-coordinate-from-mouse-location