Как сделать линию SVG с рамкой вокруг нее?

У меня есть небольшой виджет svg, целью которого является отображение списка углов (см. Изображение).

Прямо сейчас углы являются линейными элементами, которые имеют только обводку и не имеют заливки. Но теперь я хотел бы иметь цвет «внутренней заливки» и «обводку/границу» вокруг него. Я предполагаю, что элемент строки не может справиться с этим, так что же мне использовать вместо этого?

Обратите внимание, что конец линии штриха закруглен. Я хотел бы сохранить этот эффект в решении.

Угловая линия

<svg height="160" version="1.1" viewBox="-0.6 -0.6 1.2 1.2" width="160" xmlns="http://www.w3.org/2000/svg">
  <g>
    <g>
      <circle class="sensorShape" cx="0" cy="0" fill="#FFF" r="0.4" stroke="black" stroke-width="0.015"/>
      <line stroke="black" stroke-width="0.015" x1="0" x2="0" y1="-0.4" y2="0.4"/>
      <line stroke="black" stroke-width="0.015" x1="-0.4" x2="0.4" y1="0" y2="0"/>
    </g>
    <g class="lsNorthAngleHandsContainer">
      <line data-angle="348" stroke="red" stroke-linecap="round" stroke-width="0.04" transform="rotate(348)" x1="0" x2="0" y1="0" y2="-0.4"/>
      <text font-size="0.08" transform="translate(-0.02316467632710395,-0.45125904029352226)">
        348
      </text>
    </g>
  </g>
</svg>

person Tony R    schedule 13.01.2012    source источник


Ответы (5)


Добавьте вторую линию с теми же координатами, но с меньшей толщиной линии:

<g class="lsNorthAngleHandsContainer">
  <line data-angle="348" stroke="red" stroke-linecap="round" stroke-width="0.04" transform="rotate(348)" x1="0" x2="0" y1="0" y2="-0.4"/>
  <line data-angle="348" stroke="yellow" stroke-linecap="round" stroke-width="0.025" transform="rotate(348)" x1="0" x2="0" y1="0" y2="-0.4"/>
person Janne    schedule 13.01.2012

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

person Gabe    schedule 13.01.2012
comment
Спасибо, это хорошая идея. Но как мне убедиться, что верхняя строка находится точно по центру нижней строки? - person Tony R; 13.01.2012
comment
Просто используйте те же координаты с более тонкой линией. С закругленными шапками это будет смотреться правильно. - person Janne; 13.01.2012
comment
Ах, теперь, когда я думаю об этом, я верю, что вы правы! Спасибо Янне. - person Tony R; 13.01.2012

Я нашел элегантное решение, вдохновленное иллюстрацией к статье W3C о заполнение и обводка. По сути, вы перемещаете путь к определениям и используете это определение для рисования двух элементов:

<svg width="200" height="200" viewBox="0 0 100 100">
    <defs>
        <line id="line1" x1="25" x2="75" y1="25" y2="75"/>
    </defs>
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#line1" class="stroke"></use>
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#line1" class="line"></use>
</svg>

Используя <defs> и <use>, вы можете изменить только элемент пути, чтобы обновить обе строки. демонстрация JSFiddle

person kirschpirogge    schedule 03.12.2015

Вы можете использовать прямоугольник со скругленными углами, но математика немного изменится:

  <rect data-angle="348" stroke="red" stroke-linecap="round" stroke-width="0.02" fill="#FF0" transform="rotate(348, 0, 0)" x="-0.02"  y="-0.4" width=".06" height=".4" rx=".03" ry=".03"/>

http://jsfiddle.net/RNAuP/

person methodofaction    schedule 13.01.2012
comment
Это то, что я изначально думал, что решение будет. Однако ваш выглядит не так хорошо, как у Янны. Начальная и конечная точки прямоугольника не совпадают идеально в центре круга и на контуре круга. - person Tony R; 13.01.2012
comment
Если вы можете заставить его правильно выстроиться, этим решением будет легче манипулировать (скажем, если я хочу динамически добавлять/удалять контур, что я и делаю). Итак, это становится громоздким по другой причине... вы должны использовать среднюю точку каждой короткой стороны прямоугольника. - person Tony R; 13.01.2012
comment
Это вопрос арифметики, вы должны вычесть ширину границы из центра вращения jsfiddle.net/F5e74, я откровенно считаю, что две линии - более простое решение. - person methodofaction; 13.01.2012
comment
Я! Это немного лучше, но все еще не идеально... Первоначально центр конечной точки полукруга у меня совпадал с центром большого круга и его контуром. +1 за старание =) - person Tony R; 13.01.2012

Вы также можете сделать это с помощью пути, хотя это сложно вокруг круглых битов:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
  <!-- I often use entities to be able to change lot of numbers at once in static SVG, also kind of makes the paths more readable.
       Obvisouly, if you're generating the path you can use the same variables in code to append to d -->
  <!ENTITY handFill "0.01">
  <!ENTITY handFill2 "0.02"><!-- Should be 2 * handFill to be centered -->
  <!ENTITY handStroke "0.005"><!-- Should be less than handFill2 to not hide fill -->
]>
<svg height="160" version="1.1" viewBox="-0.6 -0.6 1.2 1.2" width="160" xmlns="http://www.w3.org/2000/svg">
  <g>
    <g>
      <circle class="sensorShape" cx="0" cy="0" fill="#FFF" r="0.4" stroke="black" stroke-width="0.015"/>
      <line stroke="black" stroke-width="0.015" x1="0" x2="0" y1="-0.4" y2="0.4"/>
      <line stroke="black" stroke-width="0.015" x1="-0.4" x2="0.4" y1="0" y2="0"/>
    </g>
    <g class="lsNorthAngleHandsContainer">
      <path d="
        M -&handFill;,0 l0,-0.4
        a &handFill;,&handFill; 0 0,1 &handFill2;,0
        l 0,0.4
        a &handFill;,&handFill; 0 0,1 -&handFill2;,0
      " stroke="red" stroke-linecap="round" stroke-width="&handStroke;" fill="yellow" transform="rotate(348)" />
      <text font-size="0.08" transform="translate(-0.02316467632710395,-0.45125904029352226)">
        348
      </text>
    </g>
  </g>
</svg>
person TWiStErRob    schedule 08.07.2015