how to move an UI image just in the surface of the canvas???

i have an ui image draggable , but I want to move it just inside the canvas.
the code i have allows me to move the image but not within the limits of canvas.
i use unity 4.6
This is my code:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;

public class DragUI : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {
	public Vector2 Canvas_Size;
	public Vector2 a;
	//public float b;
	public RectTransform Rt; /***/
	public GameObject bot; /****/
	private bool mouseDown = false;
	private Vector3 startMousePos;
	private Vector3 startPos;
	
	
	public void OnPointerDown(PointerEventData ped) 
	{
		//BoxCollider2D.widht = 
		//Canvas.
		mouseDown = true;
		startPos = transform.position;
		startMousePos = Input.mousePosition;
	}
	/*******************************************/
	void Get()
	{
		Rt = bot.GetComponent<RectTransform>();
		a.x = Rt.rect.height;
		a.y = Rt.rect.width;
		//Rt.rect.center = a;
	}

	/***********************************************/
	
	public void OnPointerUp(PointerEventData ped) 
	{
		mouseDown = false;
	}
	
	
	void Update () 
	{
		if (mouseDown) {
			Vector3 currentPos = Input.mousePosition;
			Vector3 diff = currentPos - startMousePos;
			Vector3 pos = startPos + diff;
			transform.position = pos;
		}
//it is the test on the canvas  limits

		
		if(transform.position.x <= -(Rt.rect.width/2 ))
		{
			transform.position = new Vector2(-(Rt.rect.width/2), transform.position.y);
		}
		else if (transform.position.x >= (Rt.rect.width/2))
		{
			transform.position = new Vector2((Rt.rect.width/2), transform.position.y);
			//transform.position.x = b; //Rt.rect.width;
			
		}
		if(transform.position.y <= -(Rt.rect.width /2))
		{
			transform.position = new Vector2(transform.position.x, -(Rt.rect.width/2 ));
		}
		else if(transform.position.y >= (Rt.rect.width/2 ))
		{
			transform.position = new Vector2(transform.position.x, (Rt.rect.width/2));
		}
		//a = new Vector2(0, 0);
		
	}
}

help me please

Thank you

Hey @LAFI that code I updated in the last question works perfectly well for canvases as well as panels, in fact it’ll work with any two objects that have a RectTransform in the new UI.

I’ll post the updated code here as well just make the Canvas the ParentRT and the image MyRect.

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;

public class DragUI : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {

	private bool mouseDown = false;
	private Vector3 startMousePos;
	private Vector3 startPos;
	private bool restrictX;
	private bool restrictY;
	private float fakeX;
	private float fakeY;
	private float myWidth;
	private float myHeight;

	public RectTransform ParentRT;
	public RectTransform MyRect;

	void Start()
	{
		myWidth = (MyRect.rect.width + 5) / 2;
		myHeight = (MyRect.rect.height + 5) / 2;
	}

	
	public void OnPointerDown(PointerEventData ped) 
	{
		mouseDown = true;
		startPos = transform.position;
		startMousePos = Input.mousePosition;
	}
	
	public void OnPointerUp(PointerEventData ped) 
	{
		mouseDown = false;
	}
	

	void Update () 
	{
		if (mouseDown) {
			Vector3 currentPos = Input.mousePosition;
			Vector3 diff = currentPos - startMousePos;
			Vector3 pos = startPos + diff;
			transform.position = pos;

			if(transform.localPosition.x < 0 - ((ParentRT.rect.width / 2)  - myWidth) || transform.localPosition.x > ((ParentRT.rect.width / 2) - myWidth))
				restrictX = true;
			else
				restrictX = false;

			if(transform.localPosition.y < 0 - ((ParentRT.rect.height / 2)  - myHeight) || transform.localPosition.y > ((ParentRT.rect.height / 2) - myHeight))
				restrictY = true;
			else
				restrictY = false;

			if(restrictX)
			{
				if(transform.localPosition.x < 0)
					fakeX = 0 - (ParentRT.rect.width / 2) + myWidth;
				else
					fakeX = (ParentRT.rect.width / 2) - myWidth;

				Vector3 xpos = new Vector3 (fakeX, transform.localPosition.y, 0.0f);
				transform.localPosition = xpos;
			}

			if(restrictY)
			{
				if(transform.localPosition.y < 0)
					fakeY = 0 - (ParentRT.rect.height / 2) + myHeight;
				else
					fakeY = (ParentRT.rect.height / 2) - myHeight;
				
				Vector3 ypos = new Vector3 (transform.localPosition.x, fakeY, 0.0f);
				transform.localPosition = ypos;
			}

		}
	}
}

Really you need to tick questions that have been answered correctly. It benefits you as well because some people won’t help if someone gets a reputation for not marking correct answers.

This is a piece of code I made using the example Unity provides. (Forum post and asset store)

using UnityEngine;
using UnityEngine.EventSystems;

public class DragableUI : UIBehaviour, IBeginDragHandler, IDragHandler
{
    /// <summary>
    /// The RectTransform that we are able to drag around.
    /// if null: the transform this Component is attatched to is used.
    /// </summary>
    public RectTransform dragObject;

    /// <summary>
    /// The area in which we are able to move the dragObject around.
    /// if null: canvas is used
    /// </summary>
    public RectTransform dragArea;

    private Vector2 originalLocalPointerPosition;
    private Vector3 originalPanelLocalPosition;
    
    private RectTransform dragObjectInternal
    {
        get
        {
            if (dragObject == null)
                return (transform as RectTransform);
            else
                return dragObject;
        }
    }

    private RectTransform dragAreaInternal
    {
        get
        {
            if (dragArea == null)
            {
                RectTransform canvas = transform as RectTransform;
                while (canvas.parent != null && canvas.parent is RectTransform)
                {
                    canvas = canvas.parent as RectTransform;
                }
                return canvas;
            }
            else
                return dragArea;
        }
    }

    public void OnBeginDrag(PointerEventData data)
    {
        originalPanelLocalPosition = dragObjectInternal.localPosition;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(dragAreaInternal, data.position, data.pressEventCamera, out originalLocalPointerPosition);
    }

    public void OnDrag(PointerEventData data)
    {
        Vector2 localPointerPosition;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(dragAreaInternal, data.position, data.pressEventCamera, out localPointerPosition))
        {
            Vector3 offsetToOriginal = localPointerPosition - originalLocalPointerPosition;
            dragObjectInternal.localPosition = originalPanelLocalPosition + offsetToOriginal;
        }

        ClampToArea();
    }

    // Clamp panel to dragArea
    private void ClampToArea()
    {
        Vector3 pos = dragObjectInternal.localPosition;

        Vector3 minPosition = dragAreaInternal.rect.min - dragObjectInternal.rect.min;
        Vector3 maxPosition = dragAreaInternal.rect.max - dragObjectInternal.rect.max;

        pos.x = Mathf.Clamp(dragObjectInternal.localPosition.x, minPosition.x, maxPosition.x);
        pos.y = Mathf.Clamp(dragObjectInternal.localPosition.y, minPosition.y, maxPosition.y);

        dragObjectInternal.localPosition = pos;
    }
}

The reason why I post this is because even though @Mmmpies his answer does work in some cases, this code works better when you change the pivot or when you change the Render Mode of the Canvas to ‘Screen Space - Camera’ or ‘World Space’.

ps. I did make it in a way that it uses default values when you leave dragObject or dragArea empty/null, though it is better for performance when you set those values in the inspector :wink: