Предлагаемая серия статей "Эффекты фильтрации SVG" Sara Soueidan, внештатного разработчика UI/UX интерфейса и автора многих технических статей, проживающей в Ливане, посвящена работе фильтров SVG и состоит из следующих статей: Во второй части серии об SVG-фильтрах Sara Soueidan знакомит нас с фильтром feMorphology и приводит несколько примеров его использования для создания интересных эффектов.  В первой части этой серии, посвященной эффектам фильтров SVG, мы познакомились с основами фильтров SVG — как их создавать и как использовать. Мы также рассмотрели несколько наиболее часто используемых операций фильтрации, т.е. примитивы фильтра. Т.к. мы будем многократно использовать эту информацию, то я рекомендую остановиться и прочитать ту статью, прежде чем продвигаться дальше по этой. < feMorphology> — одна из моих любимых операций SVG-фильтра. Это также одна из самых простых операций, и результаты ее применения к различным элементам всегда предсказуемы. Морфинг означает преобразование или изменение формы или вида объекта. Морфологический фильтр оперирует формой объекта. Он обеспечивает два предопределенных преобразования формы: эрозия (т.е. прореживание или сокращение) и расширение (т.е. А. утолщение или расширение). Иными словами, примитив feMorphology можно использовать для сжимания или расширения элемента. Технически говоря, обе эти операции работают на уровне пикселя, расширяя пиксель на соседние пиксели (dilate), или разрушая соседние пиксели по краям пикселя, которым управляют (erode), сохраняя при этом контур на границе этого пикселя. Величина, на которую расширяется пиксель, или количество соседних пикселей, используемых для “растяжки” или “расширения” пикселя, определяется параметром radius. Радиус морфинга можно представить как радиус круга или эллипса. Все соседние пиксели, заключенные в круге этого радиуса, начиная с входного пикселя, считаются единым сообществом пикселей и будут использоваться в эффекте расширения или эрозии. Однако на самом деле радиус фактически характеризует размер ядра, называемого структурирующим элементом, который больше похож на матрицу. Пока достаточно представлять его в виде небольшого прямоугольника, ширина и высота которого задаются пикселями, указанными в атрибуте radius.
 Чтобы использовать фильтр, нам не нужно вдаваться в занудные мелочи того, что морфинг делает на пиксельном уровне. Достаточно знать, что вы можете предоставить одно или два значения радиуса в feMorphology, которые будут определять величину, на которую элемент будет сжиматься или расширяться. Если в атрибуте radius указать два числа, то первое будет соответствовать x-радиусу, а второе y-радиусу. Если операцию feMorphology применить к изображениям, то последуют два, как правило, предсказуемых, результата: Таким образом, чтобы применить эффект морфинга к изображению, наш код должен выглядеть примерно так: В этом фрагменте мы размываем (сжимаем) изображение (в пикселях) на 3 пикселя. На следующем рисунке показан результат этого кода. Обратите внимание, что размер изображения справа немного меньше: 
Рис_2. Справа результат применения эффекта размывания морфинга к изображению слева. Теперь, если мы сохраним тот же радиус морфинга и изменим оператор с erode на dilate, эффект будет аналогичным, но также отчетливо различаться: 
Рис_3. Справа результат применения операции dilate morph к изображению слева. В обоих случаях изображение выглядит как абстрактная нарисованная версия самой себя, а ее общий размер изменяется по мере расширения или сжатия пикселей. Но в дополнение к этим результатам, вероятно, первое, что вы заметите, это разницу в цветах, возникающую в результате каждого из этих двух эффектов: erode создает изображение с большим количеством темных пикселей, в то время как dilate осветляет результат. Это связано с тем, что: Если отбросить технические подробности в сторону, то применение feMorphology к изображениям почти всегда будет иметь один и тот же результат: сжатие или растяжение мелких деталей изображения как копия изображения с темным или светлым основными контуром. Однако применение feMorphology к одноцветным элементам, таким как текст, только сжимает или растягивает его, не производя никаких заметных изменений цвета пикселей, потому что у нас все равно есть только один цвет для работы… Сейчас мы можем добавить контур к тексту в SVG, используя для этого текста атрибут stroke. Добавление контура, который обычно центруется по краям текста так, что половина его толщины перекрывается самим текстом, делает текст тоньше, даже если это и не предполагалось. Вместо этого мы можем расширить (dilate) текст на толщину контура или обводки при помощи feMorphology. Если не указано иное, текст обычно имеет один цвет. Так, примененный к тексту, feMorphology позволяет уменьшить или увеличить толщину текста. Как только текст расширится при помощи feMorphology, его можно использовать в качестве входных данных для других примитивов фильтра, чтобы создать контур текста, что нам и требовалось. Прежде чем мы углубимся в то, как это сделать, посмотрите на рисунок, показывающий разницу между текстом с обведенным контуром и контуром, добавленным при помощи feMorphology. 
Рис_4. Сравнение исходного текста с текстом, имеющим обводку, и контуром, созданным при помощи feMorphology. Обратите внимание, что исходный текст на второй строке стал тоньше после добавления гладкого контура, по сравнению с текстом третьей строки, расширенным при помощи feMorphology. Итак, давайте по шагам создадим цветной фрагмент текста с контуром. Вот результат, к которому мы будем стремиться: 
Рис_5. Конечный результат. Итак, мы создадим SVG, содержащее наш текст и фильтр, запускающий простую операцию расширения. Размер расширения текста зависит от толщины контура, который мы хотим получить. Приведенный выше код получит альфа-канал текста, который является просто черной версией текста, и увеличивает толщину шрифта на 4px. Результат кода на этом этапе выглядит следующим образом: 
Рис_6. Текст после утолщения. … по сравнению с исходным текстом, который имеет темно-синий цвет заливки: 
Рис_7. Исходный текст. Чтобы создать эффект контура, мы наложим исходный текст поверх расширенного, что оставит видимыми только края расширенного текста (наши дополнительные 4px) вокруг исходного текста, делая их похожими на контур. Наложение текста поверх его контура (расширенного текста) будет выполнено при помощи feMerge. Как это делается мы рассмотрели в предыдущей статье. Что еще нам нужно сделать, прежде чем расположить контур вокруг текста, так это окрасить сам контур. Подобно тому, как мы это делали в предыдущей статье, зальем область фильтра нужным цветом, а затем сложим цветовой слой с уже расширенным текстовым слоем, т.е. нашим контуром, с помощью оператора in. В результате будут отображаться только те части цветной заливки, которые пересекаются с расширенным текстом, таким образом раскрашивая его. Затем, мы соединим получившийся цветной контур с исходным текстом, чтобы получить желаемый результат. Теперь наш код выглядит так: Процесс создания эффектов фильтрации в SVG состоит в представлении окончательного результата в виде небольших последовательных операций, используя результат одной операции в качестве входных данных для другой и, наконец, объединения всех слоев, созданных ими, для достижения конечного результата. А вот демо приведенного выше кода: Цвет заливки текста можно указать либо в вашем CSS, либо в элементе text при помощи атрибута fill. Цвет контура можно настроить в атрибуте flood-color примитива feFlood. Отлично! А если вы захотите изменить цвет контура? Вам придется снова использовать примитив feFlood и комбинировать цветную заливку с контуром. И каждый раз, когда вы захотите изменить цвет контура, вам придется делать то же самое снова и снова. Это, надо признать, слишком утомительно. К счастью, есть более простой способ. Кроме добавления контура к тексту мы можем создать также контурный, т.е. выбитый текст, что означает, что внутренняя часть текста будет “вырезана”, чтобы вы могли видеть фон позади него через контур. Пример такого эффекта может выглядеть как текст на следующем GIF, который показывает изменение цвета фона, и как этот фон можно увидеть внутри нашего текста. Вот демо, которое мы будем создавать в этом разделе: 
Рис_8. Пример выбитого текста. Этот эффект легче создать, а код, необходимый для его выполнения, заметно короче. Основное различие здесь заключается в том, что вместо наслоения исходного текста поверх расширенного мы будем использовать тот же исходный текст для вырезания внутренних частей у расширенного текста. Это означает, что будет оставаться только добавленная толщина расширенного текста, а внутренняя часть будет удалена, тем самым оставляя нам только контур. Если вместо захвата и расширения Альфа-канала текста (который по умолчанию черный) вы захватываете сам исходный текст (который может иметь любой цвет заливки!), расширите его, а затем снова используйте текст, чтобы вырезать внутреннюю часть расширенного текста, то получите контур, который выходит из самого исходного текста. Это означает, что цвет этого контура всегда будет совпадать с цветом исходного текста. А так как мы можем определить цвет заливки исходного текста в CSS, это означает, что у вас есть контур текста, который отделен от его стилей. (Ура разделение забот!) Затем вы можете применить этот фильтр к любому фрагменту текста и изменить цвет этого текста в CSS в любое время, без необходимости настройки кода фильтра. Наш улучшенный код теперь выглядит так: Используя хороший шрифт, наше демо теперь выглядит так: 
Рис_9. Результат нашей работы. В своей таблице стилей мы можем выбрать цвет контура, а также цвет фона SVG. Вы также можете выбрать изображение за текстом внутри SVG. В коде ниже я абсолютно без причины использую анимацию CSS, чтобы изменять цвет фона, кроме того, что это красиво. Выше SVG фильтр является многоразовым через SVG так же как HTML. Если вы хотите применить его к HTML-элементу, вы можете сделать это с помощью свойства filter; просто поместите фильтр в HTML и “вызовите” его в CSS: И наша готовая демо, которая включает в себя HTML-заголовок с примененным к нему фильтром: Моя любимая вещь об этом рецепте фильтра заключается в том, что его можно использовать в качестве визуального улучшения. Если браузер не поддерживает SVG-фильтры, или он не поддерживает CSS-фильтры, или он не поддерживает применение фильтров SVG в HTML-элементы, пользователь получит исходный текст без контуров и эффекта просвечивания, примененных к нему. О, а вишенка на торте сверху? И SVG, и HTML-текст будут полностью доступны для поиска и изменения. Ура прогрессивному улучшению! Да здравствует SVG! Используя всего две операции фильтрации в SVG, вы можете применить эффект выделенного текста к текстовому содержимому SVG или HTML. Поместите этот фильтр в HTML и используйте его, когда вам нужно. В следующей статье этой серии мы рассмотрим feComponentTransfer, один из моих любимых примитивов фильтра, и посмотрим, как он работает и какие эффекты мы можем создать с его помощью. Оставайтесь с нами.