Почему SVG-width: 1 делает линии прозрачными? - PullRequest
28 голосов
/ 13 сентября 2011

Я создаю биржевые диаграммы с помощью svg, и у меня возникает проблема, когда я устанавливаю ширину обводки элементов контура равной 1. Вместо того, чтобы сделать линии более узкими, он просто имеет тот же размер, что и штрих- ширина: 2, но слегка прозрачная. Я не могу опубликовать его изображение, потому что у меня недостаточно очков репутации ...

Мой тег svg выглядит так:

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

И я добавляю элементы пути динамически, используя 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);

Я пропустил значение атрибута пути d, так как оно было довольно длинным. Кроме того, color - это строковая переменная, которая определяется заранее как «зеленая», «красная» или «черная».

Что-то не так в моем коде, что вызывает это, или это другая проблема?

Ответы [ 6 ]

58 голосов
/ 15 сентября 2011

Если линии прямые горизонтальные или вертикальные, просто поместите линии на полпикселя, как x="1.5px".

Другой способ - применить CSS к строкам:

.thelines{
    shape-rendering:crispEdges
}

Глава о свойствах рендеринга формы.

29 голосов
/ 13 сентября 2011

Вероятно, это связано с сглаживанием, применяемым в большинстве реализаций SVG.Когда ширина линии приближается к 1 или ниже, сглаживание делает так, чтобы наполовину покрытые пиксели оказывались частично непрозрачными.При использовании преобразований по умолчанию и области просмотра ваша однопиксельная линия, вероятно, находится точно на границе между двумя физическими пикселями, поэтому каждый из них покрыт наполовину, что обеспечивает общую прозрачность 50%.С черной линией на белом фоне получается 50% серого.

17 голосов
/ 20 сентября 2012

может быть немного поздно, но настоящая причина этого в том, что когда вы рисуете на бесконечно малой линии сетки, линия с шириной обводки 1 отображается как половина пикселя влево и вправо (или выше / ниже) от линии сетки. Я решил это, добавив группу вокруг всех объектов с трансформацией 0.5,0.5, чтобы все сместилось на половину линии сетки.

Итак, все, что вы рисуете, теперь находится точно посередине между двумя линиями сетки. Линия с шириной обводки 1 теперь будет иметь половину пикселя влево и половину пикселя влево, но обе от середины. В результате получается линия с нужной толщиной: 1 пиксель ...

Пример:

<g transform="translate(0.5,0.5)">
 <g>
   <path />
   <path />
 </g>
 <g>
   <path />
   <path />
 </g>
</g>
3 голосов
/ 10 августа 2017

Если это D3js, попробуйте добавить атрибут стиля ниже к вашему элементу d3:

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

Это делает линию тоньше.

Если вы хотите добиться того же с помощью CSS, добавьте следующий стиль:

.the_Line_CLass{
  shape-rendering: crispEdges;
}
2 голосов
/ 08 марта 2013

Ответ пользователя user616586 выглядит нормально.

Проблема, которую я вижу, состоит в том, что линии не имеют одинакового расстояния от центра фигуры, потому что одна из них смещена на 1 пиксель.В большинстве ситуаций это, вероятно, приемлемо, но иногда это не так.

Другой вариант:

  • использовать ширину обводки 2px (при этом 1px отображается снаружи, а 1px - внутриshape)
  • применить форму к себе в качестве пути клипа (удаляет рендеринг внешнего 1px)
0 голосов
/ 13 сентября 2016

исправлено:

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

Ссылка: http://code.tonytuan.org/2016/09/svg-horizontal-line-not-visible-in.html

...