2017-06-20 5 views
0

Bei Verwendung von Fabric.js 1.7.3 habe ich beim Beschneiden von Bildern ein merkwürdiges Verhalten festgestellt. Im Grunde habe ich die clipTo Methode in einem Bild gesetzt habe nur einen kleinen Platz in der Mitte des Bildes anzuzeigen:Fabric.js: Auswahlfeld nach dem Beschneiden Bild

The image's selection box still takes up the original size rather than the cropped size

Allerdings ist das Problem, dass das noch Auswahlbox des Bildes die Originalgröße nimmt eher als die beschnittene Größe. Wenn ich auf das Bild klicke, würde ich erwarten, dass die Ecken direkt neben den Bildrändern liegen; Ebenso sollte die Auswahl nur aktiviert werden, wenn ich auf das zugeschnittene Bild klicke.

Eine mögliche Lösung hierfür besteht darin, den beschnittenen Teil des Bildes als base64 zu exportieren, das alte Bild zu entfernen und stattdessen die beschnittene Version hinzuzufügen. Dies ist jedoch ziemlich unpraktisch und fühlt sich an wie Overkill. Gibt es einen Weg, wie ich die Auswahlbox einfach anpassen kann, um die beschnittene Größe zu respektieren?

+0

Bitte geben Sie an, was Sie bisher erreicht haben. – Observer

Antwort

1

auf AndreaBogazzi Antwort zu erstellen, hier ist meine komplette Lösung, in der ich die _render Methode außer Kraft setzen. Jedes Mal, wenn ich ein Bild zu erstellen, füge ich ein „Sizemode“ Attribut es, die sagt _render, wie genau es zu malen:

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

Die drawCenterImage Funktion I definiert haben, ist hier:

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

Während dieser funktioniert zum Zentrieren von Bildern (wie meine ursprüngliche Frage), unterschiedliche Aufrufe von ctx.drawImage führen zu unterschiedlichen Effekten. Here is the documentation for the drawImage method.

1

Es gibt tatsächlich keine croppTo-Methode in Fabricjs.

Es gibt eine clipTo-Methode, die sich wie beschrieben verhält.

Zuschneiden ist noch keine grundlegende Fabricjs-Funktionalität. Es wird wahrscheinlich mit der Version 2.0 einfacher gemacht werden, aber für den Moment ist der einzige Weg, es zu erhalten, die Render-Methode zu untergliedern und es komplett selbst zu machen.

  • Verwenden Sie die Formel ctx.drawImage (this._element, sx, sy, sw, sh, dx, dy, dw, dh).
  • Ihre eigene inforamtion für die Ernte mantain durch sx vertreten ist, sy, sw, sh
+0

Danke! Und Entschuldigung - ich schrieb "cropTo" anstatt "clipTo"; Ich meinte offensichtlich den zweiten. Ich habe meine Frage bereits bearbeitet, um das zu berücksichtigen. – unpollito

Verwandte Themen