web-dev-qa-db-fra.com

Toile HTML5 - Remplir le cercle avec l'image

Comment puis-je dessiner une image dans un cercle? Si je fais:

context.beginPath();
context.arc((e.pageX),(e.pageY),161,0,Math.PI*2,true);
context.closePath();

Comment puis-je utiliser fill () pour le remplir avec mon image dessinée?

27
tbleckert

Je l'ai fait l'autre jour pour une grosse chose que je fais;

var thumbImg = document.createElement('img');

thumbImg.src = 'path_to_image';
thumbImg.onload = function() {
    tmpCtx.save();
    tmpCtx.beginPath();
    tmpCtx.arc(25, 25, 25, 0, Math.PI * 2, true);
    tmpCtx.closePath();
    tmpCtx.clip();

    tmpCtx.drawImage(thumbImg, 0, 0, 50, 50);

    tmpCtx.beginPath();
    tmpCtx.arc(0, 0, 25, 0, Math.PI * 2, true);
    tmpCtx.clip();
    tmpCtx.closePath();
    tmpCtx.restore();
};

A travaillé parfaitement pour moi. 

Voici une version plus complexe que j'ai créée et qui fait aussi de la mise en cache d’images, https://jsfiddle.net/jaredwilli/ex5n5/

50
jaredwilli

Vous ne savez pas si vous cherchez toujours la réponse, mais voici comment:

var ctx = document.getElementById('your_canvas').getContext("2d");
//ctx.lineWidth = 13; 
//ctx.strokeStyle = 'rgba(0,0,0,1)'; 
//ctx.fillStyle="rgba(0,0,0,0)" // if using this, make sure alpha < 1

ctx.arc(100,100, 50, 0, Math.PI*2,true); // you can use any shape
ctx.clip();

var img = new Image();
img.addEventListener('load', function(e) {
    ctx.drawImage(this, 0, 0, 200, 300);
    //ctx.fill();
//ctx.stroke();
}, true);
img.src="/path/to/image.jpg";

Vous pouvez également le faire avec un motif, mais vous obtenez moins de flexibilité de placement d'image

ctx.arc(100,100, 70, 0, Math.PI*2,true);
ctx.clip();

img = new Image()
img.addEventListener('load', function(e) {
    ctx.fillStyle = ctx.createPattern(this, 'no-repeat') 
    ctx.fill();
}, true);
img.src="/path/to/image.jpg"
10
moby

Pensez à utiliser certaines de ces alternatives:

  • Utilisation d'un <img> avec CSS pour border-radius: http://jsfiddle.net/ChrisMorgan/BQGxA/

  • Utilisez SVG plutôt que <canvas> et définissez l'ellipse comme tracé de détourage pour une image. (Les chemins de détourage plus complexes sont alors faciles, aussi)

Ne sachant pas plus sur vos exigences et votre situation, je ne sais pas si elles satisferont vos exigences, mais je pense qu’elles valent la peine d’être examinées. <canvas> n'est pas la solution à tous vos problèmes - dans de nombreux cas, CSS en HMTL normal et/ou SVG peut être une meilleure correspondance.

4
Chris Morgan

Le problème avec la méthode clip () est que Chrome rendra les frontières non antialiasées, comme indiqué dans cette question .

Une solution consiste à utiliser globalCompositeOperation comme indiqué dans la réponse de Daniel:

//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(scratchCanves, ...);
2
Jesús Carrera
0
MatTheCat