В настоящее время строит SVG-приложение на основе браузера. В этом приложении пользователь может стилизовать и позиционировать различные формы, включая прямоугольники.
Когда я применяю a stroke-width
к rect
элементу SVG, скажем 1px
, обводка применяется к rect
смещению и вставке по-разному в разных браузерах. Это оказывается проблематичным, особенно когда я пытаюсь вычислить внешнюю ширину и визуальное положение прямоугольника и расположить его рядом с другими элементами.
Например:
- Firefox добавляет вставку в 1 пиксель (внизу и слева) и смещение в 1 пиксель (вверху и справа)
- Chrome добавляет вставку в 1 пиксель (вверху и слева) и смещение в 1 пиксель (внизу и справа)
Мое единственное решение до сих пор состояло бы в том, чтобы нарисовать фактические границы самостоятельно (возможно, с помощью path
инструмента) и расположить границы за обведенным элементом. Но это решение - неприятный обходной путь, и я бы предпочел не идти по этому пути, если это возможно.
Итак, мой вопрос, можете ли вы контролировать, как SVG stroke-width
рисуется на элементах?
paint-order
параметр, в котором вы можете указать, что заливка должна отображаться поверх обводки, поэтому вы получите «внешнее выравнивание», см. Jsfiddle.net/hne0kyLg/1Ответы:
Нет, вы не можете указать, рисуется ли обводка внутри или снаружи элемента. Я сделал предложение рабочей группе SVG по этой функциональности в 2003 году, но он не получил поддержки (или обсуждения).
Как я отметил в предложении,
Изменить : этот ответ может быть неправильным в будущем. Должно быть возможно достичь этих результатов, используя векторные эффекты SVG , комбинируя
veStrokePath
сveIntersect
(для «внутри») или сveExclude
(для «снаружи»). Однако Vector Effects все еще является рабочим черновым модулем без реализаций, которые я пока не могу найти.Редактировать 2 : черновая спецификация SVG 2 включает
stroke-alignment
свойство (с центром | внутри | вне возможных значений). Это свойство может в конечном итоге превратиться в UA.Редактировать 3 : Забавно и неутешительно, рабочая группа SVG удалила
stroke-alignment
из SVG 2. Вы можете увидеть некоторые проблемы, описанные после проза здесь .источник
UPDATE:
stroke-alignment
атрибут был на 1 апреля 2015 года перешел в совершенно новую спецификацию под названием SVG Strokes .Начиная с редакции SVG 2.0 от 26 февраля 2015 г. (и, возможно, с 13 февраля ),
со значениямиstroke-alignment
свойство присутствуетinner
,center
( по умолчанию) иouter
.Кажется, он работает так же, как
stroke-location
свойство, предложенное @Phrogz и последующимstroke-position
предложением . Это свойство было запланировано как минимум с 2011 года, но кроме аннотации, которая гласила, это никогда не было детализировано в спецификации, как это было отложено - до сих пор, кажется.
Ни один браузер не поддерживает это свойство или, насколько мне известно, какие-либо новые функции SVG 2, но, надеюсь, они появятся в ближайшее время, когда спецификации будут готовы. Это было свойство, которое я лично хотел получить, и я очень рад, что он наконец-то есть в спецификации.
Кажется, есть некоторые проблемы относительно того, как свойство должно вести себя как на открытых путях, так и на циклах. Эти проблемы, скорее всего, продлят реализации в браузерах. Однако я обновлю этот ответ новой информацией, поскольку браузеры начинают поддерживать это свойство.
источник
stroke-alignment
указано в SVG Strokes, W3C Working Draft. Между тем, черновик редактора SV3 для W3C гласит, что свойство позиционирования штриха должно быть в спецификации SVG по адресу svgwg.org/svg2-draft/painting.html#SpecifyingStrokePaint , но эта спецификация уже достигла статуса рекомендации кандидата W3C и такого свойства не существует. в спецификации, кроме ссылки наstroke-position
предложение, кажется, что это не так.Я нашел простой способ, который имеет несколько ограничений, но работал для меня:
Вот рабочий пример:
источник
<use>
? Почему бы просто не поместить путь и обрезать путь напрямую? Это работает просто отлично<svg width="240" height="240" viewBox="0 0 1024 1024"> <path id="ld" d="M256,0 L0,512 L384,512 L128,1024 L1024,384 L640,384 L896,0 L256,0 Z" clip-path="url(#clip)" stroke="#0081C6" stroke-width="160" fill="#00d2b8"/> <clipPath id="clip"> <use xlink:href="#ld"/> </clipPath> </svg>
. (Да, это совершенно разумный и правильный SVG, и он будет правильно отображаться везде. Не бойтесь рекурсии.)Вы можете использовать CSS для стилизации порядка обводки и заливки. То есть сначала обведите, а затем залейте второе и получите желаемый эффект.
MDN на
paint-order
: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/paint-orderКод CSS:
источник
Вот функция, которая подсчитает, сколько пикселей нужно добавить - используя данный штрих - к верху, справа, снизу и слева, все на основе браузера:
источник
Как уже отмечалось выше, вам придется либо пересчитать смещение по координатам траектории обводки, либо удвоить его ширину, а затем замаскировать одну или другую сторону, потому что SVG не только изначально не поддерживает выравнивание обводки Illustrator, но и PostScript не поддерживает ,
Спецификация для ударов в ручном PostScript 2 - состояниях издания компании Adobe: " 4.5.1 Поглаживания: тактный оператор рисует линию некоторой толщины вдоль пути тока для каждого прямого или изогнутого сегмента в пути,. Тактный рисует линию, центрированная на отрезок с параллельными сторонами сегменту. " (акцент их)
Остальная часть спецификации не имеет атрибутов для смещения позиции строки. Когда Illustrator позволяет вам выравнивать внутри или снаружи, он пересчитывает фактическое смещение пути (потому что это все еще в вычислительном отношении дешевле, чем наложение, чем маскирование). Координаты пути в документе .ai являются ссылочными, а не растровыми или экспортированными в окончательный формат.
Поскольку родной формат Inkscape - это спецификация SVG, он не может предложить функции, которой не хватает в спецификации.
источник
Вот обходной путь для внутреннего граничного
rect
использованияsymbol
иuse
.Пример : https://jsbin.com/yopemiwame/edit?html,output
SVG :
Примечание: Убедитесь в том , чтобы заменить
?
вuse
реальных значениях.Предпосылки : Причина , почему это работает, потому что символ устанавливает новый видовой экран, заменив
symbol
сsvg
и создавая элемент в тени DOM. Этотsvg
теневой DOM затем связывается с вашим текущимSVG
элементом. Обратите внимание, чтоsvg
s может быть вложенным, и каждыйsvg
создает новый видовой экран, который обрезает все перекрывающиеся области, включая перекрывающуюся границу. Для более подробного обзора происходящего прочитайте эту фантастическую статью Сары Соуэйдан.источник
Я не знаю, насколько это будет полезно, но в моем случае я просто создал еще один круг с рамкой и поместил его «внутри» другой фигуры.
источник
(Грязное) возможное решение - использование шаблонов,
Вот пример с внутренним штрихованным треугольником:
https://jsfiddle.net/qr3p7php/5/
источник
Решение от Ксавье Хо об удвоении ширины обводки и изменении порядка рисования является блестящим, хотя работает только в том случае, если заливка имеет сплошной цвет без прозрачности.
Я разработал другой подход, более сложный, но работает для любой заливки. Это также работает в эллипсах или путях (с более поздним есть некоторые угловые случаи со странным поведением, например, открытые пути, которые пересекаются, но не сильно).
Хитрость заключается в том, чтобы отобразить форму в два слоя. Один без обводки (только заливка), а другой только с обводкой на двойной ширине (прозрачная заливка), пропущенный через маску, которая показывает всю форму, но скрывает исходную форму без обводки.
источник