2012-02-10 17 views
7

Estoy trabajando en una aplicación de trazado de garabatos en HTML5 y me gustaría hacer una especie de función de segmento. La idea es dibujar un camino y se cerrará y se llenará con el color seleccionado (color del trazo). Funciona bastante bien con colores sólidos, pero si quiero tener un trazo y relleno transparente, me encuentro con este problema: http://imgur.com/0N3MWTransparencia de un trazo lleno en HTML5

Lo que sucede es que el relleno se realiza hasta la mitad del trazo (el punto de muestreo real de el camino) entonces hay una línea de la mitad del tamaño del trazo dentro de la forma que es más oscura porque es la intersección del relleno y el trazo.

¿Ve alguna solución para esto?

Lamentablemente, no puedo publicar en JSFiddle en este momento porque está en modo READ ONLY. Sin embargo, usted debe ser capaz de ver lo que estoy hablando de vivir en este entorno limitado: http://bit.ly/AbaMLl (El sitio web y la biblioteca no está relacionada con lo que estoy usando, es sólo un lienzo sanbox he encontrado)

Cualquier ideas/clientes potenciales bienvenido :)

Respuesta

4

de Simón correcto en el momento, pero ahora parece que Chrome 36 ha corregido un error que afecta a su solución y ya no funciona. Ya no funcionaba en Firefox y parece ser el comportamiento esperado: https://bugzilla.mozilla.org/show_bug.cgi?id=898375

Entonces, ¿cómo se hace esto?
Primero necesita otro lienzo.
Dibuje su forma rellenada y acariciada en este lienzo sin opacidad (no en el color y sin Alfil global).
Ahora, dibuja el globalAlpha a lo que quieras en tu lienzo principal.
Dibuja el primer lienzo en el principal.
Establezca globalAlpha a todo lo que tenía en su lienzo principal.
Hecho.

10

Claro, use ctx.globalCompositeOperation = 'destination-atop'; y debe verse de la manera que espera.

así: http://jsfiddle.net/UcyX4/

(Sacar esa línea con el fin de ver el problema que tienes)

Suponiendo que no es el único dibujado sobre tela, usted está probablemente va a tener que dibuja esto en un lienzo temporal y luego dibuja ese lienzo sobre el normal, de lo contrario puede arruinar todas las formas dibujadas previamente. Así que había necesidad de un sistema de este modo: http://jsfiddle.net/dATfj/

edición: código pegado en caso de fallo jsFiddle:

html:

<canvas id="canvas1" width="500" height="500"></canvas> 

guión: Respuesta

var can = document.getElementById('canvas1'); 
var ctx = can.getContext('2d'); 

var can2 = document.createElement('canvas'); 
can2.width = can.width; 
can2.height = can.height; 
ctx2 = can2.getContext('2d'); 

ctx.strokeStyle = 'rgba(0,0,0,0.7)'; 
ctx.fillStyle = 'rgba(0,0,0,0.7)'; 
ctx.lineWidth = 10; 


// Stuff drawn normally before 
// Here I draw one rect in the old way just to show the old way 
// and show something on the canvas before: 
ctx.beginPath(); 
ctx.rect(50,50,100,100); 
ctx.fill(); 
ctx.stroke(); 


// Draw on can2 then draw can2 to can 
ctx2.strokeStyle = 'rgba(0,0,0,0.7)'; 
ctx2.fillStyle = 'rgba(0,0,0,0.7)'; 
ctx2.lineWidth = 10; 
ctx2.beginPath(); 
ctx2.rect(50,250,100,100); 
ctx2.globalCompositeOperation = 'destination-atop'; 
ctx2.fill(); 
ctx2.stroke(); 

ctx.drawImage(can2, 0, 0); 
+0

Desafortunadamente, JSFiddle me da un 404 pero he intentado cambiar el modo compuesto y parece que funciona. Pero también tienes razón, necesito dibujar mi lienzo "intermedio" que estoy usando para dibujar formas sobre la final con las formas finales. Trataré de encontrar cómo hacerlo mientras JSFiddle se recupera :) ¡Gracias de nuevo! – Mathieu

+0

Ah, agregué todo el código del violín por si acaso. ¡Mucha suerte con tu proyecto! –

+0

Me serví de este mientras tanto: http: // stackoverflow.com/questions/4405336/how-to-copy-contents-of-one-canvas-to-another-canvas-localmente. Sería bueno mencionar a los usuarios de JQuery que para obtener el tipo necesario para can2 en su ejemplo, debe hacer $ ("# myCanvas"). Get (0) .getContext ('2d'). Canvas. Funciona como un encanto ahora. ¡Muchas gracias una vez más! – Mathieu

Cuestiones relacionadas