本文介绍了FabricJS:如何自动调整图像大小以适合组或矩形对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:我正在尝试将图像添加到FabricJS组或矩形对象中,以使图像保持其原始宽高比并居中放置其父级宽度/高度.

Goal: I'm seeking to add an image to a FabricJS group or rectangle object, and for the image to maintain it's original aspect ratio and center fit it's parent width/height.

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

I don't want the image overflow to show, but will show the overflow as a less opaque green in the examples below:

风景图片示例:

如果它是面向风景的图像,它将缩放到最大高度,但是在宽度放置方面居于中心:

If it was a landscape oriented image, it would scale to max height, but then center itself with regards to width placement:

由于我不希望显示图像溢出,所以最终产品应如下所示:

Since I'm not looking for the image overflow to show, the final product should look like this:

肖像图片示例:

类似地,如果图像是纵向的,则图像将按比例缩放100%,但将其自身居中放置在高度上:

Similarly, if the image was portrait oriented, the image would scale 100% in width, but center itself in height:

然后消除溢出,这就是我要寻找的最终产品:

And then negating the overflow, this is what I'm looking for as a final product:

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

Here's my stackblitz so far: 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();
}

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

This is obviously not the right solution, but a start. Any advice?

推荐答案

我知道了,这是Stackblitz: https://stackblitz.com/edit/angular-yoo8h5

I figured it out, here's the Stackblitz: https://stackblitz.com/edit/angular-yoo8h5

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

First, I compared whether or not the rectangle aspect ratio is proportional to the image through an if/else statement which decides whether or not to initially scale the image to the rectangle width/height.

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

Then I set either the top or the left attribute of the image to the rectangle boundary point. Then calculating the center point of the rectangle and subtracting half of the image's boundary and lastly, setting the rectangle group object's clipPath to that of the rectangle, it worked!

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

这篇关于FabricJS:如何自动调整图像大小以适合组或矩形对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-16 21:51
查看更多