最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - How to set Bounds such that the draggable element does not breach boundary - using react-moveable - Stack Overflow

programmeradmin2浏览0评论

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);
          }}
        />

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论