2011-09-28 26 views
15

Yo sé que no es la biblioteca jQuery SVG causando este problema, pero cuando la prestación de líneas SVG horizontales o verticales en x integrales, coordinadas Y, las líneas se 2px amplia en lugar de 1 píxel. Probablemente esto tenga que ver con el anti-aliasing. Para arreglarlos, y dibujar una línea que sea perfectamente de 1px de ancho, necesito ajustar las coordenadas agregando 0.5px.cuadrícula de dibujo con jQuery SVG produce líneas 2px en lugar de 1px

¿Hay una manera de obtener líneas de 1px de grosor sin tener que ajustar como esto?

Respuesta

31

Una manera de resolver el problema es aplicar un poco de CSS a las líneas:

.thelines{ 
    shape-rendering:crispEdges 
} 

The spec chapter on shape-rendering property.

Básicamente se apaga antialiasing para las líneas y las líneas que no están en línea recta horizontal o vertical NO puede verse muy bonita.

Pero probablemente sea mejor que sigas agregando .5 a las coordenadas de las líneas, porque los navegadores hacen lo que se les dice: la línea está en coordenadas exactas y el trazo está pintado en ambos lados de la línea, medio píxel aquí y medio píxel allí.

+0

Esto puede funcionar, si puedo apagar AA, solucionará el problema. –

+0

Ok, este problema solo funcionó, el estilo de jQuery SVG no se establece correctamente si lo llama shapeRendering, como se refieren en su documentación, tiene que ser la representación de forma, de lo contrario no funciona. –

+0

Supongo que tiene que ser 'shapeRendering' cuando lo configura como una propiedad de objeto DOM:' yourElement.style.shapeRendering = "crispEdges" ', pero dentro de un atributo de estilo debe conservar su nombre original. –

10

Así que quieres de un píxel de líneas horizontales y verticales grande para mostrarse con afilada en lugar de bordes difusos.

Si todas las coordenadas en su SVG son enteros, tal vez usted puede compensar toda la imagen en un 0,5, mediante el uso de un elemento de transformar:

// first group has no transform 
// lines appear blurred, because they are centered on boundary of two pixels 
<g id = "blurred"> 
    <line x1="10" y1="10" x2="110" y2="10" stroke="black" stroke-width="1"/> 
    <line x1="10" y1="10" x2="10" y2="100" stroke="black" stroke-width="1"/> 
</g> 

    // second group has half pixel transform - 
    // lines will appear sharp because they are translated to a pixel centre 
    <g id="sharp" transform="translate(0.5,0.5)"> 
    <line x1="120" y1="10" x2="220" y2="10" stroke="black" stroke-width="1"/> 
    <line x1="120" y1="10" x2="120" y2="100" stroke="black" stroke-width="1"/> 
</g> 

svg renders like this

Pero esta voluntad no funciona para líneas horizontales/verticales que no están definidas con coordenadas enteras, o cuando otra transformación las aleja de las coordenadas enteras.

Así que si esta idea no se puede utilizar para resolver su problema, entonces probablemente necesite una técnica de "ajuste de píxeles". Esto analizaría una línea antes de dibujarla. Si la línea es vertical u horizontal (después de la transformación), entonces es necesario ajustar las coordenadas para que puedan terminar en un centro del píxel después de la transformación.

usted puede estar interesado en el estudio de la explicación WPF Pixel Snapping para obtener información básica con respecto a este problema común.

+0

¡Parece una buena idea! :) Gracias –

+0

setTimeout (function() { d3.selectAll ('.cpu-statistics .c3-ygrid-lines .c3-ygrid-line') .attr ('transform', función (d, i) { return 'translate (0.5,0.5)'; }); }, 300); – Ivan

0

sólo tiene que utilizar una amplia rectángulo de 1 píxel con un relleno (sólo para líneas verticales horizontales/por supuesto).

p. Ej. para una línea horizontal de ancho completo:

<rect x="0" y="0" width="100%" height="1" fill="#c2c2c2"></rect> 

Perfectas líneas de 1px de ancho cada vez.

Cuestiones relacionadas