Fabric.JS调整画布尺寸时如何保持背景图片宽高比?
解决方案
问题根源
- Fabric.js的
setDimensions()方法不支持maxWidth和maxHeight参数,你设置的这两个值不会生效,画布只会严格按照传入的width和height渲染。 - 重复加载图片(原生Image和fabric.Image各加载一次)不仅冗余,还可能导致尺寸计算时机混乱。
- 直接将原图设为背景时未做比例缩放,导致图片被强制拉伸填满画布。
修正步骤
直接利用fabric.Image.fromURL回调中已加载完成的oImg处理,按以下逻辑实现:
- 计算图片宽高比,算出不超过600x600的最大缩放尺寸
- 按比例缩放背景图
- 根据缩放后的图片尺寸设置画布大小
修正后代码
var canvas = new fabric.Canvas('canvas'); fabric.Image.fromURL(path, function(oImg) { const maxSize = 600; let scaleFactor = 1; // 取宽、高方向缩放比例的较小值,保证图片完全在600x600范围内 if (oImg.width > maxSize || oImg.height > maxSize) { const widthScale = maxSize / oImg.width; const heightScale = maxSize / oImg.height; scaleFactor = Math.min(widthScale, heightScale); } // 按比例缩放图片 oImg.scale(scaleFactor); // 设置画布尺寸为缩放后的图片尺寸 canvas.setDimensions({ width: oImg.width * scaleFactor, height: oImg.height * scaleFactor }); // 设置背景图并渲染画布 canvas.setBackgroundImage(oImg, canvas.renderAll.bind(canvas)); });
额外需求方案(画布固定600x600,图片居中不拉伸)
如果需要画布固定为600x600,图片在画布内居中显示,可改用以下代码:
var canvas = new fabric.Canvas('canvas'); // 先固定画布尺寸为600x600 canvas.setDimensions({ width: 600, height: 600 }); fabric.Image.fromURL(path, function(oImg) { const maxSize = 600; let scaleFactor = 1; if (oImg.width > maxSize || oImg.height > maxSize) { const widthScale = maxSize / oImg.width; const heightScale = maxSize / oImg.height; scaleFactor = Math.min(widthScale, heightScale); } oImg.scale(scaleFactor); // 让图片在画布中居中 oImg.set({ left: (canvas.width - oImg.width * scaleFactor) / 2, top: (canvas.height - oImg.height * scaleFactor) / 2 }); canvas.setBackgroundImage(oImg, canvas.renderAll.bind(canvas)); });
内容的提问来源于stack exchange,提问作者Davide Iori
相关产品推荐
相关产品推荐

