tutorial example create javascript canvas fabricjs

javascript - example - fabric.js tutorial



FabricJS previene canvas.clipTo de recorte canvas.backgroundImage (4)

Quiero establecer un clipTo global en mi Canvas impulsado por Fabric que afectará a todas las capas agregadas por el usuario. Quiero una imagen de fondo y una imagen de superposición, que no se ven afectadas por esta máscara de clip.

Ejemplo:

Esto es lo que está sucediendo en esta foto:

  1. Una imagen superpuesta de lona hace que la camiseta se vea naturalmente arrugada. Esta imagen de superposición es principalmente transparente
  2. Se agregó una imagen de fondo con la forma exacta de la camiseta, que se supone que hace que la camiseta se vea azul
  3. Se canvas.clipTo función canvas.clipTo , que canvas.clipTo el lienzo en una forma rectangular
  4. Se agregó una imagen agregada por el usuario (el famoso pug Fabric)

Quiero que la imagen añadida por el usuario (pug) se limite al área rectangular.

No quiero que la imagen de fondo (la forma de la camiseta azul) se vea afectada por el área del clip.

¿Hay una manera simple de lograr esto? Realmente no quiero tener que agregar un clipTo en cada capa de usuario en lugar de un ordenado clipTo global.

Puedes jugar con un violín de JS que muestra el problema here .


¿Has probado cortar un Group tela? Podrías hacer que toda la camisa sea un lienzo. Los gráficos del centro serían un grupo que usted recortaría donde lo desee. La camiseta blanca y la superposición azul, por supuesto, no serían parte del grupo recortado.

Aquí hay un ejemplo de recorte de un grupo:

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

Ver este jsfiddle que hice: https://jsfiddle.net/uvepfag5/4/


Encuentro el clip bastante lento, así que tiendo a usar globalCompositeOperation para hacer el enmascaramiento.

Si realmente necesita usar un clip, úselo junto con guardar y restaurar.

// ctx is canvas context 2d // pug is the image to be clipped // draw your background ctx.save(); // save state ctx.rect(100,100,100,100); // set the clip area ctx.clip(); // apply the clip ctx.drawImage(pug,x,y); // draw the clipped image ctx.restore(); // remove the clipping // draw the other layers.

o tu puedes

// draw background ctx.globalCompositeOperation = "xor"; // set up the mask ctx.fillRect(100,100,100,100); // draw the mask, could be an image. // Alpha will effect the amount of masking, // not available with clip ctx.globalCompositeOperation = "destination-over"; ctx.drawImage(pug,x,y); // draw the image that is masked ctx.globalCompositeOperation = "source-over"; // draw the stuff that needs to be over everything.

La ventaja de las operaciones compuestas es que tiene control sobre el recorte a nivel de píxel, incluida la cantidad de recorte a través del valor de píxel alfa.


Una solución (sorta hacky): establezca una imagen de fondo CSS en su elemento canvas, como se muestra en 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>


Vine aquí con la misma necesidad y finalmente encontré una solución para lo que estoy trabajando. Tal vez ayuda:

Para las rutas SVG, dentro de la función clipTo puede modificar la ctx directamente antes de llamar a render(ctx) y estos cambios se aplican fuera de la ruta recortada o. Al igual que:

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

Por supuesto, puede agregar una imagen en lugar de un color, o cualquier otra cosa que desee hacer. El truco que he encontrado es ponerlo en el clipTo funcionar en la ctx directamente.

aquí hay un violín