2011-09-13 5 views
25

Estoy creando gráficos de stock con svg y estoy teniendo un problema cuando establezco el ancho de trazo de mis elementos de trazado en 1. En lugar de hacer las líneas más angostas, simplemente lo hace del mismo tamaño que el ancho de trazo : 2 pero ligeramente transparente. No puedo publicar una imagen de ella, porque aunque no tengo suficientes puntos de reputación ...¿Por qué SVG stroke-width: 1 hace que las líneas sean transparentes?

Mi etiqueta SVG se ve así:

<div style="height:300px; width:400px; overflow:hidden"> 
<svg style="position:relative" height="10000" width="10000" version="1.1" xmlns="http://www.w3.org/2000/svg"> 
</svg> 
</div> 

Y estoy añadiendo elementos de ruta dinámicamente usando JavaScript/jQuery:

var shape = document.createElementNS("http://www.w3.org/2000/svg", "path"); 
$(shape).attr({"d":"...", 
       "fill":"none", 
       "stroke":color, 
       "stroke-width":"1"}); 
$("svg").append(shape); 

me dejó fuera el valor del atributo de la ruta d ya que era una especie de largo. Además, color es una variable de cadena que se determina antes de la mano como "verde", "rojo" o "negro".

¿Hay algún error en mi código que esté causando esto o es un problema diferente?

+2

Si no se puede publicar una imagen, es probable que pueda publicar un jsFiddle. – Marcin

Respuesta

28

Esto probablemente se deba al anti-aliasing aplicado en la mayoría de las implementaciones de SVG. Cuando el ancho de línea se acerca o está por debajo de 1, el antialiasing lo hace de forma que los píxeles medio cubiertos se vuelvan parcialmente opacos. Con las transformaciones predeterminadas y la ventana gráfica en su lugar, su línea de un píxel probablemente se encuentra exactamente en el límite entre dos píxeles físicos, por lo que están medio cubiertos, lo que genera una transparencia general del 50%. Con una línea negra sobre un fondo blanco, esto produce un 50% de gris.

+1

¿Hay alguna manera de que pueda cambiar eso? Cuando jugué con los ejemplos de svg en w3schools.com, las líneas con ancho de trazo: 1 se mostraban muy bien sin la transparencia. – MattL922

+0

Depende del renderizador; no tengo idea si hay una forma de influenciar esto. Puede haber una manera de desactivar el anti-aliasing, pero no hay una forma estándar de la que sea consciente. – tdammers

+47

Ok, busqué en Google esto y pude resolverlo. Todo lo que tengo que hacer es agregar la representación de la forma: crispEdges al estilo del elemento ruta y ahora aparece como una línea ancha de 1px. ¡Gracias por la ayuda! – MattL922

54

Si las líneas son rectas horizontales o verticales simplemente coloque las líneas a medio píxel apagado, como x="1.5px".

Otra forma es aplicar un poco de CSS a las líneas:

.thelines{ 
    shape-rendering:crispEdges 
} 

The spec chapter on shape-rendering property.

+1

Gracias, szamil! Pero en realidad no es un truco porque si la línea real se coloca en coordenadas exactas, el trazo se pinta en ambos lados del mismo, y en realidad se ve una línea transparente de dos píxeles, no un opaco de un píxel. –

17

tal vez un poco tarde, pero la verdadera razón de esto es que cuando se dibuja en una línea de cuadrícula que es infinitamente pequeña, la línea con el ancho de trazo 1 se representa como medio píxel a la izquierda y a la derecha (o arriba/abajo) de la línea de la cuadrícula. Lo resolví agregando un grupo alrededor de todos los objetos con la transformación 0.5,0.5 para que todo se moviera a la mitad de la línea de la cuadrícula.

Así que todo lo que dibuja ahora está exactamente en el medio entre 2 líneas de cuadrícula. Una línea con un ancho de trazo 1 tendrá ahora medio píxel a la izquierda y medio píxel a la izquierda, pero ambos desde el centro. Lo que resulta en una línea con exactamente el espesor que quería: 1 píxel ...

Ejemplo:

<g transform="translate(0.5,0.5)"> 
<g> 
    <path /> 
    <path /> 
</g> 
<g> 
    <path /> 
    <path /> 
</g> 
</g> 
2

La respuesta por user616586 parece estar bien.

El problema que veo es que las líneas no tienen la misma distancia desde el centro de la forma porque una de ellas está compensada por 1 px. En la mayoría de las situaciones eso es probablemente aceptable, pero a veces no lo es.

Otra opción:

  • utilizan un accidente cerebrovascular-anchura de 2px (habiendo 1px prestados fuera y de 1 píxel generado en el interior de la forma)
  • aplican la forma a sí mismo como un clip-path (elimina la prestación de la 1px exterior)
2

Si sus D3js continuación, intente añadiendo a continuación atributo de estilo a su elemento d3:

.style('shape-rendering','crispEdges') 

Esto hace que el más delgado de línea.

Si usted quiere lograr lo mismo con CSS, a continuación, agregar el estilo a continuación:

.the_Line_CLass{ 
    shape-rendering: crispEdges; 
} 
Cuestiones relacionadas