i was trying to make the image crop modal when you change your pfp in social midea sites

I have an absolutely positioned image with a circular crop area centered within it. you can currently drag the image, but I need to constrain this movement. The goal is to ensure the crop circle always remains fully inside the image boundaries. However, my current clamping code has errors, and the behavior varies unpredictably depending on the image dimensions, as shown in the attached image.
here is some of relevant part of my code
const handleCropPreviewDrag = (e: React.MouseEvent<HTMLDivElement>) => {
e.preventDefault();
const img = pfpPreviewImageRef.current;
if (!img) return;
// Get the bounding rect of the image (after zoom/scale)
const rect = img.getBoundingClientRect();
// Store mouse offset inside the image
dragOffsetRef.current = {
x: e.clientX - rect.left,
y: e.clientY - rect.top,
};
dragStartRef.current = {
left: parseFloat(img.style.left) || 0,
top: parseFloat(img.style.top) || 0,
};
const container = img.parentElement!;
const containerRect = container.getBoundingClientRect();
const cropSize = cropInducatorSize;
const crop = cropIndicatorRef.current;
function onMouseMove(ev: MouseEvent) {
if (!img || !crop) return;
// Get current image and container sizes
const imgRect = img.getBoundingClientRect();
const container = img.parentElement!;
const containerRect = container.getBoundingClientRect();
const cropSize = cropInducatorSize;
let newLeft = dragStartRef.current.left + (ev.clientX - e.clientX);
let newTop = dragStartRef.current.top + (ev.clientY - e.clientY);
const minLeft = containerRect.width / 2 + cropSize / 2 - imgRect.width;
const maxLeft = containerRect.width / 2 - cropSize / 2;
newLeft = Math.min(maxLeft, Math.max(minLeft, newLeft));
// Same for top
const minTop = containerRect.height / 2 + cropSize / 2 - imgRect.height;
const maxTop = containerRect.height / 2 - cropSize / 2;
newTop = Math.min(maxTop, Math.max(minTop, newTop));
img.style.left = `${newLeft}px`;
img.style.top = `${newTop}px`;
}
function onMouseUp() {
window.removeEventListener("mousemove", onMouseMove);
window.removeEventListener("mouseup", onMouseUp);
}
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("mouseup", onMouseUp);
}
<div className="w-full relative max-h-[85%] flex flex-grow p-0 bg-black border border-border rounded-xl overflow-hidden">
<Image
src={pendingPreviewUrl || user.image || "/user_placeholder.jpg"}
alt="Profile crop preview"
width={500}
height={500}
className="object-contain rounded-xl w-fit top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 absolute select-none p-1 border border-border "
sizes="180px"
onLoad={()=>{
setImageTrueHeight(getContainedSize(pfpPreviewImageRef.current!)[1]!);
setImageTrueWidth(getContainedSize(pfpPreviewImageRef.current!)[0]!);
}}
style={{
maxHeight: "100%",
position: "absolute",
}}
ref={pfpPreviewImageRef}
onMouseDown={handleCropPreviewDrag}
onDragStart={e => e.preventDefault()}
>
</Image>
<div
ref={cropIndicatorRef}
className="crop-inducator absolute cursor-move -translate-x-1/2 -translate-y-1/2 bg-white/20 top-1/2 left-1/2 size-[200px] rounded-full outline outline-black border-2 border-white pointer-events-none"
style={{ width: cropInducatorSize, height: cropInducatorSize }}
/>
</div>
there is also a zoom slider and it affects the image by setting style.scale css property and i want to account for that too when calculating bounds