2017-06-20 1 views
0

En utilisant Fabric.js 1.7.3, j'ai remarqué un comportement étrange lors du rognage d'images. Essentiellement, j'ai mis la méthode clipTo dans une image pour afficher uniquement une petite place dans le centre de l'image:Fabric.js: case de sélection après le rognage de l'image

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

Cependant, le problème est que la boîte de sélection de l'image occupe toujours la taille d'origine plutôt que la taille recadrée. En cliquant sur l'image, je m'attendrais à ce que les coins soient juste à côté des bords de l'image; de même, la sélection ne doit être activée que lorsque je clique sur l'image recadrée.

Une solution possible consiste à exporter la partie recadrée de l'image en tant que base64, en supprimant l'ancienne image et en ajoutant la version recadrée à la place. Cependant, c'est plutôt impraticable et se sent comme exagéré. Y a-t-il une manière dont je pourrais simplement ajuster la boîte de sélection pour respecter la taille recadrée?

+0

Veuillez inclure ce que vous avez accompli jusqu'à maintenant. – Observer

Répondre

1

Pour construire sur la réponse de AndreaBogazzi, voici ma solution complète dans laquelle je remplacer la méthode _render. Chaque fois que je crée une image, ajouter un attribut « SizeMode » à ce qui dit _render exactement comment le peindre:

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

La fonction drawCenterImage J'ai défini est ici:

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

Bien que cette fonctionne pour centrer les images (comme c'était ma question initiale), différents appels à ctx.drawImage auront des effets différents. Here is the documentation for the drawImage method.

1

Il n'existe actuellement aucune méthode cropTo dans fabricjs.

Il existe une méthode clipTo qui se comporte comme décrit.

Le recadrage n'est pas encore une fonctionnalité de base du fabricjs. Cela sera probablement rendu plus facile avec la version 2.0, mais pour l'instant le seul moyen de l'obtenir est de sous-classer la méthode de rendu et de le faire par vous-même complètement.

  • utilisez la formule ctx.drawImage (this.élément, sx, sy, sw, sh, dx, dy, dw, dh).
  • mantenir votre inforamtion pour la culture sont représentés par sx, sy, sw, sh
+0

Merci! Et excuses - j'ai écrit "cropTo" plutôt que "clipTo"; Je voulais dire évidemment le second. J'ai déjà édité ma question pour refléter cela. – unpollito