I am using a SVG image as a background , then adding other SVG Icons over the background, to set the position on the background (Resize and Rotate). Current implementation does not cross the boundary on the left and top(Image 1), however breaches in the right and bottom (Image 2)
Looking for a solution that will consider the whole icon instead of taking the reference of top-left corner of the icon
<Moveable
ref={moveableRef}
target={iconRefs.current[selectedIcon.id] || null}
draggable
resizable
rotatable
throttleDrag={0.5} // Reduce sensitivity for better control
throttleResize={1}
throttleRotate={0.2}
updateRect={false} // Prevent unnecessary re-renders
bounds={{
left: 0,
top: 0,
right: floormapRef.current?.clientWidth || 0,
bottom: floormapRef.current?.clientHeight || 0,
}}
onDrag={({ left, top }) => {
requestAnimationFrame(() => {
// Ensure the icon stays within bounds
const floormap = floormapRef.current;
if (!floormap) return;
const maxX = floormap.clientWidth;
const maxY = floormap.clientHeight;
// console.log("Height",floormapRef.current?.clientHeight)
// console.log("Width",floormapRef.current?.clientWidth)
tempTransformRef.current.x = Math.max(
0,
Math.min(left, maxX)
);
tempTransformRef.current.y = Math.max(0, Math.min(top, maxY));
});
}}
onDragEnd={() => {
const floormap = floormapRef.current;
if (!floormap) return;
const { width, height } = floormap.getBoundingClientRect();
const relativeLeft = tempTransformRef.current.x / width;
const relativeTop = tempTransformRef.current.y / height;
setPlacedIcons((prevIcons) =>
prevIcons.map((icon) =>
icon.id === selectedIcon.id
? {
...icon,
x: tempTransformRef.current.x,
y: tempTransformRef.current.y,
relativeLeft,
relativeTop,
}
: icon
)
);
console.log(relativeLeft, relativeTop);
setTimeout(() => {
moveableRef.current?.updateRect();
}, 0);
}}
onResize={({ target, width, height, drag }) => {
requestAnimationFrame(() => {
const floormap = floormapRef.current;
if (!floormap) return;
const maxX = floormap.clientWidth;
const maxY = floormap.clientHeight;
// Ensure the icon does not exceed the floormap bounds
tempTransformRef.current.width = Math.min(
width,
maxX - drag.left
);
tempTransformRef.current.height = Math.min(
height,
maxY - drag.top
);
// Apply the constraints to the target
target.style.width = `${tempTransformRef.current.width}px`;
target.style.height = `${tempTransformRef.current.height}px`;
});
}}
onResizeEnd={() => {
setPlacedIcons((prevIcons) =>
prevIcons.map((icon) =>
icon.id === selectedIcon.id
? {
...icon,
width: tempTransformRef.current.width,
height: tempTransformRef.current.height,
}
: icon
)
);
setTimeout(() => {
moveableRef.current?.updateRect();
}, 0);
}}
onRotate={({ target, beforeRotate }) => {
requestAnimationFrame(() => {
tempTransformRef.current.rotation = beforeRotate;
// Keep the rotated element inside the floormap
target.style.transform = `rotate(${beforeRotate}deg)`;
});
}}
onRotateEnd={() => {
setPlacedIcons((prevIcons) =>
prevIcons.map((icon) =>
icon.id === selectedIcon.id
? { ...icon, rotation: tempTransformRef.current.rotation }
: icon
)
);
setTimeout(() => {
moveableRef.current?.updateRect();
}, 0);
}}
/>