You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fabric.js限制对象不超边框的缩放方法在旋转后失效该如何解决

问题根因

你原来的逻辑只适用于未旋转的对象:shape.left/shape.top是对象原点的画布坐标,shape.width * shape.scaleX是对象未旋转时的宽度,二者相加得到的是未旋转状态下的右边界,旋转后对象的实际边界会根据角度产生偏移,这个计算方式完全失效。

核心修复思路

Fabric.js 内置了getBoundingRect()方法,会自动计算对象经过旋转、缩放、斜切变换后的实际视觉包围盒,返回值包含画布坐标系下的left/top/width/height,不需要自己手动计算旋转矩阵。
调整逻辑为:

  • 每次缩放时先获取当前对象的实际包围盒
  • 判断包围盒是否超出画布边界
  • 根据溢出量反向调整scaleX/scaleY,同步修正位置避免缩放时对象抖动

修改后代码

let scalingProperties = {
    'left': 0,
    'top': 0,
    'scaleX': 0,
    'scaleY': 0
}

export function scaling(e) {
    const shape = e.target;
    const maxWidth = shape.canvas.width;
    const maxHeight = shape.canvas.height;
    // 获取旋转后的实际视觉包围盒
    const boundingRect = shape.getBoundingRect();

    // 左边界处理
    if(boundingRect.left < 0) {
        const overflow = -boundingRect.left;
        // 修正位置抵消左溢出
        shape.left += overflow;
        // 同步修正scale避免右边界同时溢出
        if(boundingRect.width + shape.left > maxWidth) {
            shape.scaleX = (maxWidth - shape.left) / shape.width;
        }
        scalingProperties.left = shape.left;
        scalingProperties.scaleX = shape.scaleX;
    } 
    // 右边界处理
    else if(boundingRect.left + boundingRect.width > maxWidth) {
        shape.scaleX = (maxWidth - boundingRect.left) / shape.width;
        scalingProperties.scaleX = shape.scaleX;
    }
    else {
        scalingProperties.left = shape.left;
        scalingProperties.scaleX = shape.scaleX;
    }

    // 上边界处理
    if(boundingRect.top < 0) {
        const overflow = -boundingRect.top;
        // 修正位置抵消上溢出
        shape.top += overflow;
        // 同步修正scale避免下边界同时溢出
        if(boundingRect.height + shape.top > maxHeight) {
            shape.scaleY = (maxHeight - shape.top) / shape.height;
        }
        scalingProperties.top = shape.top;
        scalingProperties.scaleY = shape.scaleY;
    }
    // 下边界处理
    else if(boundingRect.top + boundingRect.height > maxHeight) {
        shape.scaleY = (maxHeight - boundingRect.top) / shape.height;
        scalingProperties.scaleY = shape.scaleY;
    }
    else {
        scalingProperties.top = shape.top;
        scalingProperties.scaleY = shape.scaleY;
    }
}

注意事项

  • 即使自定义了对象的originX/originY也不需要额外适配,getBoundingRect()会自动适配原点设置
  • 如果需要限制等比例缩放,调整scaleX/scaleY时可以按比例同步修改另一个参数即可

内容的提问来源于stack exchange,提问作者Marcel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 20:18:01