web-dev-qa-db-fra.com

FabricJS empêche canvas.clipTo de découper canvas.backgroundImage

Je souhaite définir un clipTo global dans mon canevas basé sur Fabric qui affectera toutes les couches ajoutées par l'utilisateur. Je veux une image d’arrière-plan et une image superposée, qui ne sont pas affectées par ce masque de découpe.

Exemple:

 enter image description here

Voici ce qui se passe sur cette photo: 

  1. Une image de superposition de toile donne au t-shirt un aspect naturellement froissé. Cette image de recouvrement est principalement transparente
  2. Une image de fond dans la forme exacte du t-shirt a été ajoutée, ce qui est censé donner au t-shirt un aspect bleu.
  3. Une fonction canvas.clipTo a été ajoutée. Elle associe la toile à une forme rectangulaire.
  4. Une image ajoutée par l'utilisateur (le célèbre carlin Fabric) a été ajoutée.

Je veux que l'image ajoutée par l'utilisateur (le carlin) soit limitée à la zone rectangulaire.

Je fais not je veux que l’arrière-plan (la forme bleue du t-shirt) soit affecté par la zone de clip.

Y a-t-il un moyen simple d'accomplir cela? Je ne veux vraiment pas avoir à ajouter un clipTo sur chaque couche d'utilisateur plutôt qu'un global ordonné clipTo.

Vous pouvez jouer avec un violon JS montrant le problème ici .

29
chadoh

Je suis venu ici avec le même besoin et, finalement, j'ai trouvé une solution à ce sur quoi je travaille. Peut-être que ça aide:

Pour les chemins SVG, dans la fonction clipTo, vous pouvez modifier le fichier ctx directement avant d'appeler render(ctx). Ces modifications s'appliquent en dehors du chemin coupé. Ainsi:

var clipPath = new fabric.Path("M 10 10 L 100 10 L 100 100 L 10 100", {
  fill: 'rgba(0,0,0,0)',
});

var backgroundColor = "rgba(0,0,0, 0.2)";

var opts = {
  controlsAboveOverlay: true,
  backgroundColor: 'rgb(255,255,255)',
  clipTo: function (ctx) {
    if (typeof backgroundColor !== 'undefined') {
      ctx.fillStyle = backgroundColor;
      ctx.fillRect(0, 0, 300, 150);
    }
    clipPath.render(ctx);
  }
}
var canvas = new fabric.Canvas('c', opts);

canvas.add(new fabric.Rect({
  width: 50,
  height: 50,
  left: 30,
  top: 30,
  fill: 'rgb(255,0,0)'
}));

Vous pouvez bien sûr ajouter une image à la place d'une couleur, ou tout ce que vous voulez faire. Le truc que j’ai trouvé est de le mettre directement dans la fonction clipTo sur ctx

voici un violon

1
qrrr

Une solution (en quelque sorte): définissez une image d’arrière-plan CSS sur votre élément canvas, comme indiqué dans https://jsfiddle.net/qpnvo3cL/

<canvas id="c" width="500" height="500"></canvas>
<style>
  background: url('http://fabricjs.com/assets/jail_cell_bars.png') no-repeat;
</style>
<script>
  var canvas = window._canvas = new fabric.Canvas('c');
  canvas.clipTo = function(ctx) {
      ctx.rect(100,100,100,100);
  }
</script>
0
chadoh

Avez-vous essayé de couper un tissu Groupe ? Vous pouvez faire toute la chemise une toile. Les graphiques centraux seraient un groupe que vous coupez où vous le souhaitez. Le t-shirt blanc et la superposition bleue feraient bien sûr partie de ce groupe - pas .

Voici un exemple de découpage d'un groupe:

var rect = new fabric.Rect({width:100, height: 100, fill: 'red' });
var circle = new fabric.Circle({ radius: 100, fill: 'green' });
var group1 = new fabric.Group([ circle, rect ], { left: 100, top: 100 });
canvas.add(group1);

group1.clipTo = function(ctx) {
    ctx.rect(50,50,200,200);
};

Voir ce jsfiddle que j'ai fait: https://jsfiddle.net/uvepfag5/4/

0
Stafree