2015-10-07 15 views
24

Desidero impostare un valore globale clipTo nella mia Tela alimentata a tela che interesserà tutti i livelli aggiunti dall'utente. Voglio un'immagine di sfondo e un'immagine di sovrapposizione, che non sono influenzate da questa maschera di ritaglio.FabricJS impedisce canvas.clipTo dal clipping canvas.backgroundImage

Esempio:

enter image description here

Ecco quello che sta succedendo in questa foto: sovrapposizione di immagini

  1. Una tela rende il look maglietta spiegazzata, naturalmente. Questa sovrapposizione di immagini è in gran parte trasparente
  2. Un'immagine di sfondo nella forma esatta della t-shirt è stato aggiunto, che dovrebbe rendere il look t-shirt blu
  3. Una funzione canvas.clipTo è stato aggiunto, che clip la tela per un forma rettangolare
  4. a user-added image (la famosa pug Fabric) è stato aggiunto

voglio che l'immagine aggiunti dall'utente (il pug) per essere limitata alla zona rettangolare.

I do non desidera l'immagine di sfondo (la forma della maglietta blu) interessata dall'area di ritaglio.

C'è un modo semplice per realizzare questo? Non voglio davvero aggiungere un clipTo a ogni singolo livello utente anziché uno ordinato globale clipTo.

È possibile giocare con un violino JS che mostra il problema here.

+0

Hai mai ottenuto questo lavoro? – Rivka

+0

@Rivka non in un modo che mi piacesse. Ho funzionato aggiungendo un (molto complesso) 'clipTo' a ogni singolo livello utente, piuttosto che un semplice' clipTo' globale. – chadoh

risposta

0

Una soluzione (sorta hacky): impostare un'immagine di sfondo CSS sul vostro elemento canvas, come mostrato nella 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

Questo ha almeno due problemi: 1) se si usa un SVG come immagine di sfondo e si cambia colore, sarà necessario in qualche modo usare questo svg generato dinamicamente come immagine di sfondo nel proprio css-forse si può sormontare questo esportandolo come un'immagine di dati in linea. 2) Quando esporti l'immagine finale da Fabric, i tuoi stili CSS NON saranno ovviamente inclusi, quindi il colore della maglietta sarà sbagliato nell'immagine generata. – chadoh

-1

trovo la clip piuttosto lento così io tendo a usare globalCompositeOperation fare mascheramento.

Se è davvero necessario utilizzare la clip, utilizzarla in combinazione con salvataggio e ripristino.

// 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. 

oppure

// 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. 

Il vantaggio di operazioni composite è puoi controllare il ritaglio ad un livello per pixel, compresa la quantità di clipping tramite il valore del pixel alpha

+0

Grazie! Sembra che tu abbia risposto come se stessi disegnando manualmente sulla tela. Ma io non sono. Sto usando FabricJS per fare la maggior parte del disegno. Ora, sono abbastanza nuovo in tutto questo materiale su tela, quindi forse non capisco! Hai guardato il mio JSfiddle? Puoi dimostrare questo approccio con una forchetta di questo? Non capisco come applicare ciò che mi hai detto alla situazione che ho descritto ... – chadoh

0

I è venuto qui con lo stesso bisogno e alla fine ho trovato una soluzione per ciò su cui sto lavorando. Forse aiuta:

Per i percorsi SVG, all'interno della funzione clipTo è possibile modificare direttamente il ctx prima di chiamare render(ctx) e queste modifiche si applicano all'esterno del percorso troncato o. Così:

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

Naturalmente è possibile aggiungere un'immagine anziché un colore o qualsiasi altra cosa si desideri. Il trucco che ho trovato è di inserirlo direttamente nella funzione clipTo su ctx.

here's a fiddle

+0

Per quanto posso dire, questo è per aggiungere una semplice area di clip rettangolare. Sono già in grado di aggiungere un'area di clip globale. Funziona alla grande. Il guaio è che taglia la forma dello sfondo, però. Voglio un'area di clip globale che non ritagli la forma dello sfondo. – chadoh

+0

Sono abbastanza sicuro che stiamo parlando della stessa cosa. Modificando il ctx all'interno della funzione clipTo prima del rendering dal percorso della clip (che è arbitrario btw -In questo esempio è un rettangolo semplice ma può essere qualsiasi forma di svg che desideri), puoi disegnare sulla tela al di fuori dell'area di clip globale . Quindi, nell'esempio del violino, puoi disegnare un'immagine anziché la bg grigia, o nel tuo caso disegna la t-shirt e la t-shirt blu sovrapposta e non saranno influenzate dalla clip globale. [Vedi qui] (https://jsfiddle.net/v3ustgk9/4/) – qrrr

0

Hai provato deviando un tessuto Group? Potresti rendere l'intera maglietta una tela. La grafica centrale sarebbe un gruppo che si aggancia al punto in cui lo si desidera. La t-shirt bianca e la sovrapposizione blu sarebbero ovviamente non far parte del gruppo ritagliato.

Ecco un esempio di clipping un gruppo:

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

Vai a questa jsfiddle ho fatto: https://jsfiddle.net/uvepfag5/4/

Problemi correlati