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
相关产品推荐
相关产品推荐

