0
\$\begingroup\$

I have some RectTransform on Unity UI. I have already implemented some Zoom functionality but now I need it to zoom to the area where the mouse cursor is located. Currently, it zooms to the anchor point. How can I zoom to the mouse cursor?

Here are some screenshots from a hierarchy.

enter image description here

enter image description here

enter image description here

I have already implemented zoom itself.

public class ZoomableRect : MonoBehaviour { [SerializeField] private RectTransform rectToZoom;

[SerializeField] private ZoomConfigs zoomConfigs;

private bool onObj = false;

[SerializeField] private ScrollRect scrollRect;
public ScrollRect ScrollRect
{
    get { return scrollRect; }
    set { scrollRect = value; }
}

private bool isZoomAllowed;
public bool IsZoomAllowed
{
    get { return isZoomAllowed; }
    set { isZoomAllowed = value; }
}

private bool isFullScreen;
public bool IsFullScreen
{
    get { return isFullScreen; }
    set { isFullScreen = value; }
}

void Start()
{
    if (!rectToZoom)
        rectToZoom = GetComponent<RectTransform>();

}

void Update()
{
    float scrollWheel = -Input.GetAxis("Mouse ScrollWheel");

    if (isZoomAllowed && scrollWheel != 0)
    {
        ChangeZoom(scrollWheel);
        SetPosition(Input.mousePosition);
    }
}

private void ChangeZoom(float scrollWheel)
{
    float rate = 1 + zoomConfigs.zoomRate * Time.unscaledDeltaTime;

    if (scrollWheel > 0)
    {
        SetZoom(Mathf.Clamp(transform.localScale.y / rate,
         zoomConfigs.minSize, zoomConfigs.maxSize));
    }
    else
    {
        SetZoom(Mathf.Clamp(transform.localScale.y * rate,
         zoomConfigs.minSize, zoomConfigs.maxSize));
    }
}

private void SetZoom(float targetSize)
{
    transform.localScale = new Vector3(targetSize, targetSize, 1);
}

public void SetPosition(Vector2 mouseInput)
{
    float rectWidth = rectToZoom.rect.width;
    float rectHeight = rectToZoom.rect.height;

    float mousePosX = mouseInput.x;
    float mousePosY = mouseInput.y;

    float widthPivot = mousePosX / rectWidth;
    float heightPivot = mousePosY / rectHeight;

    Debug.Log("widthPivot = " + widthPivot + " heightPivot = " + heightPivot);

    rectToZoom.anchorMin = new Vector2(widthPivot, heightPivot);
    rectToZoom.anchorMax = new Vector2(widthPivot, heightPivot);

    rectToZoom.transform.position = new Vector2(mousePosX, mousePosY);
    Debug.Log("MousePosX = " + mousePosX + " MousePosY = " + mousePosY);
}

public void SetAnchors(bool isFullScreen)
{
    if (!isFullScreen)
    {
        rectToZoom.anchorMin = new Vector2(1, 1);
        rectToZoom.anchorMax = new Vector2(1, 1);
    }
}

}

But anchors always snap to the bottom left corner. And widthPivot and heigtPivot values are always bigger than 1.

Actually, after testing, I see that anchors are less than 1 when the cursor is located in the bottom left part of the screen. And bigger than 1 when the cursor is in the top right part of the screen.

When zooming it always snaps to the bottom left corner.

enter image description here

enter image description here

It seems that mouse position connected to the current resolution at the same time canvas on which zoomableRect is potisioned has reference resolution of 1920 x 1080.

Changing a pivot in the same way instead of anchors doesn't have any effect. Same result.

\$\endgroup\$
  • 1
    \$\begingroup\$ Knowing a bit more about how your hierarchy is structured and how you've configured your transform properties like anchors would help us get more accurate answers. There are a lot of moving parts in UI layout, so if we don't account for all of them we might not get the desired effect. ;) \$\endgroup\$ – DMGregory Jan 28 at 13:27
  • \$\begingroup\$ I have updated the info about this issue :) \$\endgroup\$ – Nikita Demidenko Jan 29 at 9:03

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.