Фиксированная ширина штриха в SVG

104

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

Контекст следующий:

У меня есть элемент SVG с установленными атрибутами viewBox и preserveAspectRatio. Это выглядит примерно так

<svg version="1.1" baseProfile="full"
    viewBox="-100 -100 200 200" preserveAspectRatio="xMidYMid meet"
    xmlns="http://www.w3.org/2000/svg" >
</svg>

Это означает, что когда я масштабирую этот элемент, фактические формы внутри него соответственно масштабируются (пока все хорошо).

Как видите, я настроил viewBox так, чтобы начало координат было в центре. Я хотел бы нарисовать оси x и y внутри этого элемента, что я делаю следующим образом:

<line x1="-1000" x2="1000" y1="0" y2="0" />

Опять же, это нормально работает. Однако в идеале эта ось всегда должна иметь ширину всего 1 пиксель. Меня не интересует, что оси становятся толще при масштабировании родительского элемента svg.

Так я облажался?

wxs
источник

Ответы:

129

Вы можете использовать vector-effectсвойство, установленное на non-scaling-stroke, см. Документацию . Другой способ - использовать transform(ref).

Это будет работать в браузерах, которые поддерживают эти части из SVG Tiny 1.2, например Opera 10. Резервный вариант включает в себя написание небольшого скрипта, который делает то же самое, в основном инвертируя CTM и применяя его к элементам, которые не должны масштабироваться.

Если вам нужны более четкие линии, вы также можете отключить сглаживание ( shape-rendering=optimizeSpeedили shape-rendering=crispEdges) и / или поиграть с позиционированием.

Эрик Дальстрём
источник
1
К сожалению, это приложение XUL, и оно, похоже, еще не поддерживает векторный эффект. Ну что ж.
wxs
1
Это должно появиться в Firefox 15, все в порядке, поэтому вы сможете использовать его, как только
создадите
2
IE11 по-прежнему не поддерживает vector-effectсвойство. Можно ли добиться того же эффекта, что и vector-effect: non-scaling-strokeв IE11?
merlin
1
@merlin да, с помощью js это можно эмулировать в IE.
Эрик Дальстрем
3
@merlin клонирует элемент (с настройкой fillна noneи наоборот stroke), вычисляет и устанавливает соответствующие преобразования (одно для заливки и одно для обводки). Конечно, это будет немного беспорядочно, но это так - вы также можете попросить Microsoft добавить для него поддержку. В любом случае я считаю, что ваш вопрос заслуживает отдельного рассмотрения.
Эрик Дальстрем