Moving smoothly around the bounds of a circle

This is the image of what I’m trying to achieve, in a 3D space. I want the object to follow my finger within the green zone, but stay on the edge of the green zone if I move my finger outside of it. I have achieved this with the code below, but when moving my finger around the red zone a lot of jitters and clipping occurs as the object keeps snapping back within it’s bounds. My main camera is attached to the moving object so it’s important that I eliminate the jitters. How can I smooth this out?

public class Player : MonoBehaviour
{
    public Camera movementCam;
    readonly float radius = 0.45f;
    readonly float speed = 3f;
    Ray firstTouchPos;
    Vector2 playerPos;

    void Update()
    {
        if (Input.GetMouseButtonDown(0)) {
            firstTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
            playerPos = transform.position;
        }

        if (Input.GetMouseButton(0)) {
            Ray currentTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
            Vector2 direction = currentTouchPos.origin - firstTouchPos.origin;
            float distance = Vector3.Distance(transform.position, Vector3.zero);
            transform.position = distance >= radius ? (Vector3)(direction.normalized * radius) : (Vector3)(playerPos + direction * speed);
        }
    }
}

You can achieve this by using Lerp or Slerp. See example below

public Camera movementCam;
     readonly float radius = 0.45f;
     readonly float speed = 3f;
     Ray firstTouchPos;
     Vector2 playerPos;
 
     void Update()
     {
         if (Input.GetMouseButtonDown(0)) {
             firstTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
             playerPos = transform.position;
         }
 
         if (Input.GetMouseButton(0)) {
             Ray currentTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
             Vector2 direction = currentTouchPos.origin - firstTouchPos.origin;
             float distance = Vector3.Distance(transform.position, Vector3.zero);
             var targetPosition = distance >= radius ? (Vector3)(direction.normalized * radius) : (Vector3)(playerPos + direction * speed);
			 transform.position = Vector3.Lerp (transform.position, targetPosition, 1f); 
         }
     }

However, I would recommend you put the slerp function outside of the MouseButtonDown. That way you can add a smoother following/delay

readonly float radius = 0.45f;
     readonly float speed = 3f;
     Ray firstTouchPos;
     Vector2 playerPos;
	 Vector3 targetPosition;
	 float followDelay = 2f;
     void Update()
     {
         if (Input.GetMouseButtonDown(0)) {
             firstTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
             playerPos = transform.position;
         }
 
         if (Input.GetMouseButton(0)) {
             Ray currentTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
             Vector2 direction = currentTouchPos.origin - firstTouchPos.origin;
             float distance = Vector3.Distance(transform.position, Vector3.zero);
             targetPosition = distance >= radius ? (Vector3)(direction.normalized * radius) : (Vector3)(playerPos + direction * speed);
			
         }
		 
		  transform.position = Vector3.Lerp (transform.position, targetPosition, followDelay); 
     }