Почему SVG stroke-width: 1 делает линии прозрачными?

Я создаю фондовые диаграммы с 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);

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

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

6 ответов


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


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

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

.thelines{
    shape-rendering:crispEdges
}

глава спецификации о свойстве отрисовки фигуры.


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

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

пример:

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

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

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

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

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

.the_Line_CLass{
  shape-rendering: crispEdges;
}

ответ user616586 кажется прекрасным.

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

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

  • используйте ширину штриха 2px (с 1px, отображаемым снаружи и 1px, отображаемым внутри фигуры)
  • применить фигуру к себе в качестве пути клипа (удаляет отрисовку наружной в 1px)

исправления:

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

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