2010-11-25 13 views

Respuesta

46

lo hice esto el otro día por una gran cosa que estoy haciendo;

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

Funcionó perfecto para mí.

Aquí hay una versión más compleja de lo que he hecho, que hace caché de imagen también, https://jsfiddle.net/jaredwilli/ex5n5/

+0

Se ve muy bien, definitivamente lo intentaré! – tbleckert

+1

Si bien esto fue en última instancia lo que se me ocurrió como solución en el lienzo, después de aumentarlo y modificarlo con todo tipo de cosas que debían hacerse para la aplicación en la que trabajé, resultó que 2 días antes de lanzar algo vino y tenía 2 días para hacer una solución alternativa que resultó ser mucho mejor, más rápida y con más navegadores entre computadoras de escritorio y dispositivos móviles. La solución fue la respuesta @MatTheCat sugirió "Usar un con CSS para border-radius". Solo usé border-radius: 100% para hacerlo circular. La mejor solución sin duda alguna. Solo digo ... – jaredwilli

+0

Solo quería agregar, que es una buena práctica establecer src * después de * establecer la devolución de llamada 'onload'. Es decir. 'thumbImg.src = 'path_to_image';' se convierte en la última línea –

3

considerar el uso de algunas de estas alternativas:

  • El uso de un <img> con CSS para border-radius: http://jsfiddle.net/ChrisMorgan/BQGxA/

  • Uso SVG en lugar de <canvas> y establecer la elipse como el trazado de recorte de una imagen. (Más trazados de recorte complejos son entonces fácil, demasiado)

Sin saber más acerca de sus necesidades y la situación no sé si estos serán satisfacer sus necesidades, pero creo que vale la pena teniendo en cuenta. <canvas> no es la solución a todos sus problemas, en muchos de estos casos, CSS en HMTL normal y/o SVG puede ser una mejor combinación.

+0

SVG podría ser el camino a seguir. Lo que estoy haciendo es que tengo un video y cuando lo pausa, aparece una lupa. Luego, con un lienzo, dibujo la imagen del video en el lienzo y lo acercamiento. El problema es que la lupa es redonda, así que tengo que recortarla o llenarla con un arco. – tbleckert

+1

En ese caso, es posible que le interese consultar un artículo de Tutorialzine de junio, [http://tutorialzine.com/2010/06/apple-like-retina-effect-jquery-css/](Efecto Retina similar a la manzana Con jQuery). Cubre obtener un efecto de trabajo como ese, aunque con una imagen estática en lugar de un marco '

+0

De hecho, tuve que usar CSS border-radius como alternativa a la respuesta que publiqué anteriormente que fue marcada como la respuesta aceptada en el proyecto en el que he estado trabajando para la aplicación de Facebook de Samsung Olympic Genome Project.Resultó ser la mejor solución para hacer lo que teníamos que hacer para que el lanzamiento reciente de Chrome 18 no arruinara por completo el rendimiento de la aplicación, ya que habilitaban la aceleración de hardware 2D Canvas por defecto en esa versión, que tenía un error que por alguna razón hizo que dibujar grandes cantidades de caminos complejos e imágenes extremadamente lentas. – jaredwilli

9

No estoy seguro si usted todavía está buscando la respuesta, pero aquí es cómo:

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"; 

También puede hacer esto con el patrón, pero se obtiene menos la imagen flexibilidad de colocación

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" 
2

El problema con el método de clip() es que Chrome hará que las fronteras no suavizadas, como se muestra en this question.

Una solución es utilizar globalCompositeOperation como se muestra en la respuesta de Daniel: "¿Cómo puedo entonces utilizar de relleno() para llenarlo con mi imagen dibujada"

//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, ...); 
Cuestiones relacionadas