web-dev-qa-db-fra.com

Pourquoi la largeur de trait SVG: 1 rend-elle les lignes transparentes?

Je crée des graphiques boursiers avec svg et je rencontre un problème lorsque je règle la largeur de trait de mes éléments de chemin sur 1. Au lieu de rendre les lignes plus étroites, la taille du texte est identique à celle de la largeur de trait: 2 mais légèrement transparent. Je ne peux cependant pas en publier une image car je n'ai pas assez de points de réputation ...

Mon tag svg ressemble à ceci:

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

Et j'ajoute des éléments de chemin dynamiquement en utilisant 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);

J'ai omis la valeur de l'attribut d du chemin car il était plutôt long. De plus, color est une variable de chaîne qui est déterminée au préalable comme étant "vert", "rouge" ou "noir".

Y at-il quelque chose de mal dans mon code qui cause cela ou est-ce un problème différent?

28
MattL922

Ceci est probablement dû à l'anti-aliasing appliqué à la plupart des implémentations SVG. Lorsque la largeur de trait est proche ou inférieure à 1, l'antialiasing permet de rendre les pixels à moitié recouverts partiellement rendus opaques. Avec les transformations et la fenêtre par défaut en place, votre ligne d'un pixel est probablement située exactement à la frontière entre deux pixels physiques. Elles sont donc toutes recouvertes à moitié, ce qui donne une transparence globale de 50%. Avec une ligne noire sur un fond blanc, cela donne 50% de gris.

29
tdammers

Si les lignes sont droites horizontales ou verticales, placez-les à un demi-pixel, comme x="1.5px"

Une autre méthode consiste à appliquer des CSS aux lignes:

.thelines{
    shape-rendering:crispEdges
}

Le chapitre de spécification sur la propriété de rendu de forme.

57
Spadar Shut

peut-être un peu tard, mais la vraie raison à cela est que, lorsque vous dessinez sur une ligne de grille infinie petite, la ligne de largeur de trait 1 est affichée sous forme de demi-pixel à gauche et à droite (ou au-dessus/en dessous) de la grille ligne. J'ai résolu ce problème en ajoutant un groupe autour de tous les objets avec la transformation 0.5.0.5 afin que tout soit décalé d'une demi-grille. 

Donc, tout ce que vous dessinez est maintenant exactement au milieu entre 2 lignes de la grille. Une ligne avec une largeur de trait 1 aura maintenant un demi-pixel à gauche et un demi-pixel à gauche, mais les deux à partir du milieu. Résultat: une ligne correspondant exactement à l'épaisseur souhaitée: 1 pixel ...

Exemple:

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

Si c'est le cas, essayez d'ajouter l'attribut style ci-dessous à votre élément d3:

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

Cela rend la ligne plus mince.

Si vous souhaitez obtenir le même résultat avec CSS, ajoutez le style ci-dessous:

.the_Line_CLass{
  shape-rendering: crispEdges;
}
3
Gil Baggio

La réponse de user616586 semble bien.

Le problème que je vois est que les lignes n’ont pas la même distance du centre de la forme car l’une d’elles est décalée de 1 px. Dans la plupart des situations, c'est probablement acceptable, mais parfois ce n'est pas le cas.

Une autre option:

  • utilisez une largeur de trait de 2px (1px rendu à l'extérieur et 1px à l'intérieur de la forme)
  • appliquer la forme à elle-même en tant que chemin de clip (supprime le rendu du 1px externe)
2
Codepunkt

réparer:

<line
  x1="10" y1="1"
  x2="90" y2="1.0001" // hack: horizontal line in SVG not visible in Chrome
  stroke="#FF0000"
  strokeWidth="1"/>

Réf.: http://code.tonytuan.org/2016/09/svg-horizontal-line-not-visible-in.html

0
cwtuan