简体   繁体   English

Fabric.js:裁剪图像后的选择框

[英]Fabric.js: selection box after cropping image

On using Fabric.js 1.7.3, I have noticed an odd behavior when cropping images. 在使用Fabric.js 1.7.3时,我注意到裁剪图像时出现了奇怪的行为。 Essentially, I have set the clipTo method in an image to display only a small square in the center of the image: 本质上,我已经在图像中设置了clipTo方法,以在图像中心仅显示一个小方块:

图像的选择框仍然占据原始尺寸,而不是裁切的尺寸

However, the problem is that the image's selection box still takes up the original size rather than the cropped size. 但是,问题在于图像的选择框仍占据原始尺寸,而不是裁剪的尺寸。 When clicking on the image, I would expect the corners to be right next to the edges of the picture; 当单击图像时,我希望拐角位于图片边缘的旁边。 similarly, the selection should only be activated when I click on the cropped picture. 同样,仅当我单击裁剪后的图片时,才能激活选择。

A possible solution for this involves exporting the cropped part of the image as base64, removing the old image and adding the cropped version instead. 一个可能的解决方案包括将图像的裁剪部分导出为base64,删除旧图像并添加裁剪的版本。 However, this is rather impractical and feels like overkill. 但是,这是不切实际的,感觉像是过分杀伤力。 Is there a way in which I could simply adjust the selection box to respect the cropped size? 有没有一种方法可以简单地调整选择框以符合裁切后的尺寸?

There is actually no cropTo method in fabricjs. fabricjs中实际上没有cropTo方法。

There is a clipTo method that behaves as you described. 有一个clipTo方法的行为与您描述的一样。

Cropping is not a basic fabricjs functionality yet. 裁剪还不是基本的fabricjs功能。 It will be probably made easier with the 2.0 release, but for now the only way to obtain it is subclassing the render method and do it by yourself completely. 2.0发行版可能会使其变得更容易,但是目前唯一的获取方法是将render方法子类化并完全由您自己完成。

  • use the ctx.drawImage(this._element, sx, sy, sw, sh, dx, dy, dw, dh) formula. 使用ctx.drawImage(this._element,sx,sy,sw,sh,dx,dy,dw,dh)公式。
  • mantain your own inforamtion for the crop are represented by sx, sy, sw, sh 维护自己的农作物信息以sx,sy,sw,sh表示

To build on AndreaBogazzi's answer, here's my complete solution in which I override the _render method. 为了建立AndreaBogazzi的答案,这是我完整的解决方案,其中我覆盖了_render方法。 Whenever I create an image, I add a "sizeMode" attribute to it which tells _render how exactly to paint it: 每当创建图像时,都会向其添加“ sizeMode”属性,该属性告诉_render如何精确绘制图像:

fabric.Image.prototype._render = function(ctx, noTransform) {
    /* This is the default behavior. I haven't modified anything in this part. */
    let x, y, imageMargins = this._findMargins(), elementToDraw;

    x = (noTransform ? this.left : -this.width / 2);
    y = (noTransform ? this.top : -this.height / 2);

    if (this.meetOrSlice === 'slice') {
        ctx.beginPath();
        ctx.rect(x, y, this.width, this.height);
        ctx.clip();
    }

    if (this.isMoving === false && this.resizeFilters.length && this._needsResize()) {
        this._lastScaleX = this.scaleX;
        this._lastScaleY = this.scaleY;
        elementToDraw = this.applyFilters(null, this.resizeFilters, this._filteredEl
            || this._originalElement, true);
    }
    else {
        elementToDraw = this._element;
    }

    /* My changes begin here. */
    if (elementToDraw && elementToDraw.naturalHeight > 0) {
        if (this.sizeMode === BadgingImageSizeMode.CenterImage) {
            drawCenterImage.apply(this, [ctx, elementToDraw, imageMargins, x, y]);
        } else {
            // Default _render behavior
            ctx.drawImage(elementToDraw,
                x + imageMargins.marginX,
                y + imageMargins.marginY,
                imageMargins.width,
                imageMargins.height);
        }
    }

    /* And they finish here. */
    this._stroke(ctx);
    this._renderStroke(ctx);
};

The drawCenterImage function I've defined is here: 我定义的drawCenterImage函数在这里:

const drawCenterImage = function(ctx, elementToDraw, imageMargins, x, y) {
    const sx = (elementToDraw.naturalWidth - this.width) / 2;
    const sy = (elementToDraw.naturalHeight - this.height) / 2;
    ctx.drawImage(elementToDraw,
        sx,
        sy,
        imageMargins.width,
        imageMargins.height,
        x + imageMargins.marginX,
        y + imageMargins.marginY,
        imageMargins.width,
        imageMargins.height);
};

While this works for centering images (as was my original question), different calls to ctx.drawImage will result in different effects. 虽然这可以使图像居中(这是我最初的问题),但对ctx.drawImage的不同调用将导致不同的效果。 Here is the documentation for the drawImage method . 这是drawImage方法的文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM