В очередной статье серии об SVG фильтрах Sara Soueidan покажет как сделать текст соответствующим текстуре поверхности с помощью примитива feDisplacementMap.



Предлагаемая серия статей "Эффекты фильтрации SVG" Sara Soueidan, внештатного разработчика UI/UX интерфейса и автора многих технических статей, проживающей в Ливане, посвящена работе фильтров SVG и состоит из следующих статей:


Эффекты фильтрации SVG


  1. Эффекты фильтрации SVG. Часть 1. SVG фильтры 101
  2. Эффекты фильтрации SVG. Часть 2. Контурный текст при помощи feMorphology
  3. Эффекты фильтрации SVG. Часть 3. Эффект постеризации изображения при помощи feComponentTransfer
  4. Эффекты фильтрации SVG. Часть 4. Двухцветные изображения при помощи feComponentTransfer.
  5. Эффекты фильтрации SVG. Часть 5. Соответствие текста текстуре поверхности при помощи feDisplacementMap

Применение текстуры к тексту — один из самых популярных текстовых эффектов в графическом дизайне. Поскольку большая часть печатного и графического дизайна проникла в веб-платформу, такие эффекты также были воссозданы в интернете с помощью CSS, а также с использованием функций SVG, таких как шаблоны, маски и пути обрезки. У меня есть статья прямо здесь на Codrops, которая даcт вам полный обзор различных способов создания текстурированного текста в вебе с помощью CSS и SVG, что вас может заинтересовать сегодня. Yoksel затронул еще одну область этой темы и написал статью об анимации заливки текста.


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


Соответствие текста текстуре поверхности: путь Photoshop'а


Как и в случае с эффектом duotone, я изучила, как сделать в Photoshop текст соответствующим текстуре поверхности, пытаясь воспроизвести этот эффект с помощью SVG-фильтров. Я нашла этот пошаговый учебник на YouTube.


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


В Photoshop для соответствия текста поверхности дизайнер выполнял следующие действия:


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

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


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


Но самым важным шагом в этом эффекте является создание и применение карты смещений. Как мы можем создать ее в SVG?


Соответствие текста текстуре поверхности в SVG


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


feDisplacementMap принимает двое входных данных для получения одного результата. Изображение, которое вы захотите использовать для смещения контента, указывается в атрибуте in2. Атрибут in зарезервирован для входных данных, к которым вы захотите применить эффект смещения.


И как со всеми другими примитивами, входными данными для feDisplacementMap может быть что угодно, начиная от собственного источника графики (SourceGraphic), до результата другой операции фильтрации. Так как мы хотим применить карту смещения к нашему источнику текста, то это означает, что атрибут in будет иметь в качестве значения SourceGraphic.


Итак, давайте воссоздадим шаги руководства для Photoshop с примитивами SVG фильтрации. Процесс соответствия текста текстуре в SVG очень похож на тот, что мы видели в Photoshop. Я подробно остановлюсь на каждом шаге.


  • Получим изображение, которое будет использоваться в качестве текстуры при помощи feImage.
  • Обесцветим изображение при помощи feColorMatrix.
  • Применим размытие Гаусса на 0.5px к изображению при помощи feGaussianBlur.
  • Используем изображение для деформации текста при помощи feDisplacementMap.
  • Смешаем текст с фоновым изображением при помощи feBlend и применим к нему эффект прозрачности (уменьшим непрозрачность при помощи feComponentTransfer).
  • Отобразим текст и изображение позади него, объединив два слоя, используя feMerge.

Примитив фильтрации feImage это версия фильтра элемента image и имеет те же атрибуты, что и он. Поэтому для рендеринга изображения в области фильтра мы будем использовать feImage. Получив изображение, мы можем использовать его в качестве входных данных для других операций фильтрации. Оно будет использоваться для загрузки в операцию feColorMatrix, чтобы его обесцветить.


Мы уже описывали примитив feColorMatrix раньше, но не упомянули, что он поставляется с несколькими ключевыми словами, которые являются ярлыками для предопределенных матриц. Вместо того, чтобы всегда предоставлять матрицу в качестве исходных данных, можно изменить атрибут type, использовав один из возможных ключей:


matrix | saturate | hueRotate | luminanceToAlpha

Тип matrix используется, когда вы хотите предоставить собственную матрицу в качестве значения для матричных операций. Другие ключи добавляют возможностей.


Для обесцвечивания изображения используется тип saturate. В атрибуте values указывается размер обесцвечивания изображения. Так как мы хотим полностью обесцветить наше изображение, в качестве значения мы установим 0. Обратите внимание, что значения представляются в виде долей, при этом 1 (значение по умолчанию) означает полное насыщение, а 0 — полное обесцвечивание (оттенки серого).


Итак, давайте начнем переводить наши шаги в код:


<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.-->
<filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> 

    <!-- Get the image. -->
    <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage>

    <!-- Desaturate the image. -->
    <feColorMatrix type="saturate" values="0" result="IMAGE"/>

    <!-- ... -->

В данный момент наша область фильтра выглядит следующим образом:


Исходное изображение после обесцвечивания
Рис_1. Исходное изображение после обесцвечивания.


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


<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.-->
<filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> 

    <!-- Get the image. -->
    <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage>

    <!-- Desaturate the image. -->
    <feColorMatrix type="saturate" values="0" result="IMAGE"/>

    <!-- decrease level of details so the effect on text is more realistic -->
    <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur>

    <!-- ... -->

И наша карта смещения теперь выглядит так:


Вид карты смещения
Рис_2. Вид карты смещения.


Использовав feDisplacementMap, мы можем теперь исказить текст при помощи нашей карты смещения:


<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.-->
<filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> 

    <!-- Get the image. -->
    <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage>

    <!-- Desaturate the image. -->
    <feColorMatrix type="saturate" values="0" result="IMAGE"/>

    <!-- decrease level of details so the effect on text is more realistic -->
    <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur>

    <!-- Use the displacement map to distort the source text -->
    <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap>

    <!-- ... -->

На этом этапе изображение, которое мы использовали для искажения текста, больше не отображается, так как оно было использовано для создания искаженного текста. Итак, область фильтрации в настоящий момент содержит только текст, который теперь соответствует форме и текстуре ткани нашей карты смещения:


Отображение искаженного текста
Рис_3. Отображение искаженного текста.


Вы уже можете увидеть, как текстура ткани принимает форму по краям текста. Это замечательно.


Как и в руководстве для Photoshop, мы будем повторно отобразить изображение за текстом, снова используя feImage:


<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.-->
<filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> 

    <!-- Get the image. -->
    <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage>

    <!-- Desaturate the image. -->
    <feColorMatrix type="saturate" values="0" result="IMAGE"/>

    <!-- decrease level of details so the effect on text is more realistic -->
    <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur>

    <!-- Use the displacement map to distort the source text -->
    <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap>

    <!-- Re-display the image as a background image -->
    <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="BG"></feImage>

    <!-- ... -->

Наконец, мы хотим смешать текст с фоном, чтобы улучшить эффект. Мы уменьшим непрозрачность текста до 0,9 с помощью feColorMatrix, а затем применим примитив feBlend к тексту для смешивания с фоном.


Аналогично CSS Blend Modes, у нас есть на выбор 16 режимов смешивания. Для нашего эффекта подойдет режим multiply. В руководстве для Photoshop дизайнер использовал линейную запись, которая недоступна в SVG/CSS.


feBlend будет принимать два входных данных для смешивания: текст и фоновое изображение:


<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.-->
<filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> 

    <!-- Get the image. -->
    <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage>

    <!-- Desaturate the image. -->
    <feColorMatrix type="saturate" values="0" result="IMAGE"/>

    <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur>

    <!-- Use the displacement map to distort the source text -->
    <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap>

    <!---->
    <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="BG"></feImage>

    <!-- Reduce the opacity of the text -->
    <feColorMatrix in="Textured_Text" result="Textured_Text_2" type="matrix" 
       values="1 0 0 0 0 
       0 1 0 0 0 
       0 0 1 0 0 
       0 0 0 .9 0" />  

    <!-- Blend the text with the background -->
    <feBlend in="BG" in2="Textured_Text_2" mode="multiply" result="BLENDED_TEXT"></feBlend>

    <!-- ... -->

И в конце, но не по значению, мы наложим новый слой смешанного текста поверх слоя фонового изображения при помощи feMerge:


<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.-->
<filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> 

        <!-- Get the image. -->
        <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage>

        <!-- Desaturate the image. -->
        <feColorMatrix type="saturate" values="0" result="IMAGE"/>

        <!-- decrease level of details so the effect on text is more realistic -->
        <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur>

        <!-- Use the displacement map to distort the source text -->
        <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap>

        <!---->
        <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="BG"></feImage>

        <!-- Reduce the opacity of the text -->
        <feColorMatrix in="Textured_Text" result="Textured_Text_2" type="matrix" 
           values="1 0 0 0 0 
                   0 1 0 0 0 
                   0 0 1 0 0 
                   0 0 0 .9 0" />      

        <!-- Blend the text with the background -->
        <feBlend in="BG" in2="Textured_Text_2" mode="multiply" result="BLENDED_TEXT"></feBlend>

        <!-- Layer the text on top of the background image -->
        <feMerge>
            <feMergeNode in="BG"></feMergeNode>
            <feMergeNode in="BLENDED_TEXT"></feMergeNode>
        </feMerge>
</filter>

<text dx="60" dy="200" font-size="10em" font-weight="bold" filter="url(#conform)" fill="#00826C"> organic </text>

А вот и наш конечный результат:


Конечный результат
Рис_4. Конечный результат.


Примечания по использованию карт смещения в SVG


Элемент feDisplacementMap имеет три атрибута, которые определяют, как карта смещения влияет на исходную графику:


  • xChannelSelector: указывает, какой цветовой канал (R/G/B/A) из in2 использовать для горизонтального cмещения;
  • yChannelSelector: указывает, какой цветовой канал (R/G/B/A) из in2 использовать для вертикального cмещения;
  • scale(масштаб): определяет величину искажения изображения. Чем выше scale, тем сильнее эффект искажения. Вероятно, вы будете экспериментировать с этим значением, чтобы получить желаемый результат.

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


Вы также можете встроить изображение в фильтр (в feImage) и использовать его в качестве карты смещения. Этот pen от Gabi является отличным примером, который использует встроенный шаблон SVG для искажения исходного изображения. Эта круговая картина, образующая эффект наподобие пульсаций, моя любимая.


Применение преобразования к исходному тексту


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


Если применить преобразование поворота к <тексту>, к которому применяется фильтр, будет повернута вся область фильтрации, включая фоновое изображение:


Вид изображения после применения поворота, при этом повернулся и фон
Рис_5. Вид изображения после применения поворота, при этом повернулся и фон.


Это происходит также, если к исходному тексту применить и другие стили. Например, если установить параметр непрозрачности < text> в 0,5, это также повлияет на текст и фоновое изображение.


Для того, чтобы повернуть текст, но не остальную область фильтрации, мы можем обернуть текст в группу (< g>) и применить фильтр к этой группе, а затем применить преобразование поворота к тексту. Это гарантирует, что только текст будет повернут, тогда как остальная часть области фильтрации, которая теперь определена обернутой группой, остается незатронутой преобразованием. Этот способ любезно предоставлен Amelia Bellamy-Royds.


<g filter="url(#conform)">
     <text dx="60" dy="200" font-size="10em" transform="translate(-20 30) rotate(-7)" fill="#00826C">organic</text>
</g>

Я немного изменила преобразование, добавив пересчет, чтобы убедиться, что текст остается по центру области фильтрации. Результат этой трансформации теперь выглядит так:


Преобразование вместе с пересчетом для центровки текста
Рис_6. Преобразование вместе с пересчетом для центровки текста.


Обратите внимание, что я применяю преобразование поворота к тексту, используя атрибут преобразования SVG, а не CSS, потому что на момент написания этой статьи Internet Explorer и MSEdge не поддерживают CSS-преобразования в элементах SVG.


Реальное демо


Этот эффект смещения текста в настоящее время работает во всех основных браузерах, включая MSEdge. Ниже приведен скриншот эффекта в MSEdge:


Как выглядит обработка текста в MSEdge
Рис_7. Как выглядит обработка текста в MSEdge.


Тем не менее, Chrome недавно остановил применение эффекта искажения к тексту. В этой ветке содержится дополнительная информация об этой проблеме. Остальные операции фильтрации, однако, работают и применяются просто отлично, поэтому, пока Chrome не исправит эту проблему, вы сможете увидеть текст, смешанный с фоном, только без искажений по его краям. Ниже приведен скриншот того, как демо выглядит в Chrome:


Как выглядит в настоящее время эффект искажения текста в Chrome
Рис_8. Как выглядит в настоящее время эффект искажения текста в Chrome.


Вы можете посмотреть демо здесь.


Заключение


Я надеюсь, что вы уже начинаете наслаждаться мощью SVG фильтров и задумались о большом количестве возможностей и эффектов, которые можно с ними создать.


Если вам понравилась идея соответствия текста текстуре поверхности, то вам конечно же захочется изучить как создавать свою собственную текстуру в SVG. Да, вы все правильно прочитали. SVG может создавать текстуры.


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

Комментарии (0)