Setting X Coordinate from Mouse Location

吃可爱长大的小学妹 提交于 2020-01-15 12:20:38

问题


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:

  1. State A: mouse.x is over darkBlueRect.x = 1 and both sprites are aligned to the left.
  2. State B: mouse.x is in the middle of darkBlueRect and both sprites are aligned to the middle.
  3. State C: mouse.x is on the last pixel of darkBlueRect 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!