【问题标题】:FabricJS: How to auto-resize image to fit group or rectangle object?FabricJS:如何自动调整图像大小以适合组或矩形对象?
【发布时间】:2020-03-08 14:41:27
【问题描述】:

目标:我正在寻求将图像添加到 FabricJS 组或矩形对象,并让图像保持其原始纵横比和中心适合其父宽度/高度。

我不希望显示图像溢出,但会在以下示例中将溢出显示为不透明的绿色:


风景图片示例

如果是横向图像,它会缩放到最大高度,然后根据宽度放置将自身居中:

由于我不是在寻找要显示的图像溢出,因此最终产品应如下所示:


人像图片示例

同样,如果图像是纵向的,图像的宽度会缩放 100%,但高度会居中:

然后否定溢出,这就是我正在寻找的最终产品:


到目前为止,这是我的堆栈闪电战:https://stackblitz.com/edit/angular-gpfkkw

基本情况代码如下:

this.canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({
    left: 100,
    top: 50,
    width: 450,
    height: 200,
    fill: '#e3e3e3',
});

var rectGroup = new fabric.Group([rect], {
    name: 'Rectangle',
});

this.canvas.add(rectGroup);

fabric.Image.fromURL('https://placehold.it/888x500&text=16:9', (img) => {
    let bounds = rectGroup.getBoundingRect();

    const scaleFactor = Math.min(
        Math.min(bounds.width / img.width),
        Math.min(bounds.height / img.height)
    );
    img.scale(scaleFactor);

    img.set({
        top: bounds.top + Math.max(bounds.height - img.height * scaleFactor, 0)/2,
        left: bounds.left + Math.max(bounds.width - img.width * scaleFactor, 0)/2,
    });

    rectGroup.addWithUpdate(img);
    this.canvas.renderAll();
}

这显然不是正确的解决方案,而是一个开始。有什么建议吗?

【问题讨论】:

    标签: html5-canvas fabricjs


    【解决方案1】:

    我想通了,这里是 Stackblitz:https://stackblitz.com/edit/angular-yoo8h5

    首先,我通过if/else 语句比较了矩形纵横比是否与图像成比例,该语句决定是否最初将图像缩放到矩形宽度/高度。

    然后我将图像的顶部或左侧属性设置为矩形边界点。然后计算矩形的中心点并减去图像边界的一半,最后将矩形组对象的clipPath设置为矩形的,就可以了!


    fabric.Image.fromURL('https://placehold.it/888x500&text=16:9', (img) => {
        let bounds = rectGroup.getBoundingRect();
    
        if ((bounds.height / bounds.width) >= (img.height / img.width)) {
            img.scaleToHeight(bounds.height);
            img.set({
                top: bounds.top,
                left: (bounds.left + (bounds.width/2)) - (img.getBoundingRect().width/2)
            });
        }
        else {
            img.scaleToWidth(bounds.width);
            img.set({
                top: (bounds.top + (bounds.height/2)) - (img.getBoundingRect().height/2),
                left: bounds.left
            });
        }
    
        rectGroup.addWithUpdate(img);
        rectGroup.clipPath = rect;
        this.canvas.renderAll();
    });
    

    【讨论】:

      【解决方案2】:

      这里有点晚了,但如果这可能会有所帮助。

      您使用Math.min 朝着正确的方向前进,但您可以使用Math.max 代替具有较大组/图像比率的一侧以缩放到该侧的全长。然后,您可以将 x y 原点设置为 center

      fabric.Image.fromURL('https://placehold.it/888x500&text=16:9', (img) => {
          let bounds = rectGroup.getBoundingRect();
      
          const scaleFactor = Math.max(bounds.width / img.width, bounds.height / img.height);
      
          img.set({
            originX: 'center',
            originY: 'center',
            scaleX: scaleFactor,
            scaleY: scaleFactor
          });
      
          rectGroup.addWithUpdate(img);
          this.canvas.renderAll();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-03
        • 2017-11-20
        • 2011-02-13
        • 2019-06-12
        • 2020-01-31
        • 2017-08-07
        • 1970-01-01
        相关资源
        最近更新 更多