2011-01-02 9 views
6

con el lienzo HTML si se traza una línea de puntos así:¿Por qué HTML Canvas redondea lineCap para el último segmento?

ctx.lineWidth = 40; 
ctx.lineCap  = 'round'; 
ctx.strokeStyle = 'red'; 

ctx.beginPath(); 
ctx.moveTo(100,100); 
ctx.lineTo(150,200); 
ctx.moveTo(200,300); 
ctx.lineTo(250,400); 
ctx.moveTo(300,500); 
ctx.lineTo(350,600); 
ctx.closePath(); 
ctx.stroke(); 

entonces el resultado es el siguiente:

Dashed line with first two dashes using rounded line caps and last dash using butt caps http://phrogz.net/tmp/canvas_broken_rounded_stroke.png

Como se puede ver en this test page, la adición de un "superflua" moveTo llame después de que el último lineTo arregla el último segmento de línea para usar límites redondeados.

Estaba preparado para presentar esto como un error, pero luego descubrí que el comportamiento es idéntico en Safari v5, Chrome v8 y FireFox v3.6 y v4.0b. Esto me lleva a creer que es intencional.

¿En qué parte de la norma se especifica este comportamiento, y (si puede discernirlo) por qué se especificó así?

Respuesta

7

Estas son las definiciones pertinentes de la canvas spec (section 9, paths):

El método moveTo(x, y) debe crear una nueva subtrazado con el punto especificado como su primer punto (y única).

El método lineTo(x, y) ... debe conectar el último punto en el subtrayecto al punto dado (x, y) usando una línea recta, y luego debe agregar el punto dado (x, y) al subestado.

El método closePath() ... debe marcar el último subtrazado como cerrado ... esto es equivalente a la adición de una línea recta que conecta el último punto de vuelta al primer punto, por lo tanto "cierre" de la forma ...

Cada llamada a moveTo crea un nuevo subtrayecto, por lo que finaliza el subestado anterior. En su caso, los primeros dos segmentos se terminan de esta manera. Para el segmento final, llamar al closePath "cierra" el segmento dibujando otro segmento en la dirección inversa, de ahí el resultado que está viendo: no hay un segmento sino dos segmentos superpuestos. Agregar otro moveTo termina este segmento como los demás, por lo que verá el límite de línea redondeado como se esperaba.

+4

En otras palabras: si bien siempre debe llamar a 'beginPath()' al iniciar su nueva ruta, solo debe llamar a 'closePath()' cuando realmente lo necesite y saber lo que hace. No se requiere, o se desea, la mayor parte del tiempo. – Phrogz

Cuestiones relacionadas