Se si sta eseguendo un disegno complesso a strati, è possibile utilizzare globalCompositeOperation per emulare il ritaglio in una seconda area di lavoro. È quindi possibile utilizzare drawImage per copiare nuovamente l'area di lavoro nella tela originale. Non posso garantire le prestazioni di questo approccio, ma è l'unico modo che conosco per ottenere quello che vuoi.
//set-up - probably only needs to be done once
var scratchCanvas = document.createElement('canvas');
scratchCanvas.width = 100;
scratchCanvas.height = 100;
var scratchCtx = scratchCanvas.getContext('2d');
//drawing code
scratchCtx.clearRect(0, 0, scratchCanvas.width, scratchCanvas.height);
scratchCtx.globalCompositeOperation = 'source-over'; //default
//Do whatever drawing you want. In your case, draw your image.
scratchCtx.drawImage(imageToCrop, ...);
//As long as we can represent our clipping region as a single path,
//we can perform our clipping by using a non-default composite operation.
//You can think of destination-in as "write alpha". It will not touch
//the color channel of the canvas, but will replace the alpha channel.
//(Actually, it will multiply the already drawn alpha with the alpha
//currently being drawn - meaning that things look good where two anti-
//aliased pixels overlap.)
//
//If you can't represent the clipping region as a single path, you can
//always draw your clip shape into yet another scratch canvas.
scratchCtx.fillStyle = '#fff'; //color doesn't matter, but we want full opacity
scratchCtx.globalCompositeOperation = 'destination-in';
scratchCtx.beginPath();
scratchCtx.arc(50, 50, 50, 0, 2 * Math.PI, true);
scratchCtx.closePath();
scratchCtx.fill();
//Now that we have a nice, cropped image, we can draw it in our
//actual canvas. We can even draw it over top existing pixels, and
//everything will look great!
ctx.drawImage(scratchCanvas, ...);
Il motivo per cui lo facciamo in una tela zero è quella destinazione-in è un'operazione piuttosto distruttivo. Se avevi già disegnato alcune cose nella tela principale (forse hai messo un gradiente gradevole sullo sfondo), e poi volevi disegnare un'immagine ritagliata, il cerchio di ritaglio avrebbe anche ritagliato tutto ciò che avevi già disegnato. Naturalmente, se la tua situazione particolare è più semplice (forse TUTTI quelli che vuoi disegnare è un'immagine ritagliata), puoi rinunciare alla tela antigraffio.
È possibile giocare con le diverse modalità di ritaglio su my demo page. La riga in basso (con i gradienti) non è troppo utile per te, ma la riga in alto (con il cerchio e il quadrato) è molto più rilevante.
modificare
Ops, ho accidentalmente forked your JSFiddle per dimostrare la tecnica.
fonte
2012-12-13 06:25:41
Mi sono imbattuto in questo problema pure. Quello che ho fatto è stato disegnare un cerchio nello stesso punto dell'immagine, dietro di esso, con raggio maggiore di 1 o 2 px. Mantieni il colore simile e vai, "anti alias". – Automatico