SVG маски и вау-эффекты: о магии простыми словами

О существовании SVG знают все, кто занимается фронтендом. Этой технологии уже не один год, про нее уже не раз писали на хабре. Но есть один момент. Частенько на разных ресурсах, в том числе и на тостере, начинающие задают вопросы о создании определенного семейства анимаций на сайте и получают довольно странные ответы от “бывалых” разработчиков. Возникает ощущение, что в такие моменты все думают в контексте HTML+CSS+JS и просто забывают о существовании SVG, предлагая все рисовать на canvas и попутно давая обещания дать тому, кто это придумал, клавиатурой по голове. Но этот путь (рисование на canvas) зачастую слишком сложен относительно решаемой задачи. В предыдущей статье мы обсуждали идеи создания частичных вау-эффектов, а в этой поговорим о масках и посмотрим пару анимаций, которые с их помощью можно сделать.

Что вообще такое эти маски?

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

В базовом варианте маска создается примерно так:

<svg>     <defs>         <mask id=’mask-1’>             . . .         </mask>     </defs>     <image mask=’url(#mask-1)’ /> </svg>

Вместо картинки может быть что угодно. Маску вполне можно применять ко всему, что мы там нарисуем. Сама она также может состоять из каких угодно компонентов, мы можем сделать ее из картинки, использовать многоугольники или кривые.

Удобно делать маску черно-белой. Точнее сказать, делать так, чтобы она состояла из оттенков серого, которые будут работать как прозрачность. Крайние значения, черный и белый – это полная прозрачность и непрозрачность, а оттенки серого – что-то посередине. Формально это не обязательно (будет работать и цветной вариант), но довольно удобно.

В большинстве случаев мы используем двухцветные черно-белые схемы, чтобы делать маски с четкими границами, но стоит помнить и о том, что можно добавить прозрачность при необходимости.

В целом это все, что нужно знать. Маски – это очень простой инструмент в нашем арсенале, но польза от него может быть довольно внушительной. Рассмотрим пару примеров.

Текст с заливкой

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

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

<svg viewBox='0 0 100 100'>     <defs>         <mask id='mask-1' x='0' y='0' width='100' height='100'>             <!-- Тут меняем #000 на #fff -->             <rect id='main-rect' x='0' y='0' width='100' height='100' fill='#000' />             <!-- Тут меняем #fff на #000 -->             <text id='text' x='50' y='80' fill='#fff'>SVG</text>         </mask>     </defs>     <image width='100' height='100' xlink:href='. . .' mask='url(#mask-1)' /> </svg>

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

Если добавить пару дополнительных прямоугольников нужного цвета в маску и немного это все анимировать, то получится довольно привлекательный эффект:

Полезно обратить внимание на то, как текст выезжает из-за невидимой стенки в самом начале. Подобные действия часто применяют при создании различных анимаций.

В примере используется anime.js, кто-то скажет, что нужно использовать GSAP, потому, что это “стандарт”. Но, как мы знаем, на вкус и цвет фломастеры разные, так что используйте то, что вам нравится больше. Можно и на чистом JS все это делать. По сути все эти анимации – это постепенное изменение тех или иных атрибутов у элементов, так что никто не мешает взять requestAnimationFrame, querySelector, setAttribute и самостоятельно увеличивать или уменьшать необходимые значения. В первом примере меняются только координаты элементов в маске и их цвета.

Раскраски. Детский сад глазами верстальщика.

Одни говорят, что раскраски – это не для взрослых, другие – что они успокаивают. Но как бы там ни было, это очень хорошая фишка для сайтов, связанных с детскими развивающими играми, художественными курсами или еще чем-нибудь таким. При раскрашивании какого-либо объекта (опять же, прямоугольник, фотография – не важно, пусть будет сердечко), маска будет очень полезным инструментом.

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

Можно зарисовать только необходимую фигуру, а можно выйти немного за ее пределы – это простой способ добавить небольшие паузы в закрашивании.

А теперь мы сделаем линию потолще и прорисуем ее от начала до конца, анимируя свойство strokeDashoffset. Сделав это в маске мы получим эффект зарисовывания нашего объекта.

Все это реализовано буквально в несколько строк:

<svg viewBox='0 0 100 100'>     <defs>         <mask id='mask-1' x='0' y='0' width='100' height='100'>             <path id='path-1'  d='. . .' fill='none' stroke='#fff' stroke-width='8' stroke-linecap='round' />         </mask>     </defs>          <path d='. . .'  stroke='#AF1B3F' stroke-width='0' fill='#FF686B' mask='url(#mask-1)'/> </svg>

И сама анимация:

var lineDrawing = anime({     targets: '#path-1',     strokeDashoffset: [anime.setDashoffset, 0],     duration: 5000 });

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

Переходы для каруселей

Чаще всего мы видим переходы, которые основаны на сдвиге слайдов, как при плавном проматывании пленки, или основанные на увеличении/уменьшении прозрачности этих самых слайдов. Но это же скучно. Маски дают нам возможность делать куда более интересные переходы. Для примера возьмем вот такой вариант:

На чистом CSS+JS делать такие вещи сложно. Но если взять маски, состоящие из нескольких прямоугольников, которые двигаются в одном направлении или увеличиваются в размерах, то все становится куда проще:

WebKit имеет в себе небольшой плавающий баг, когда значения округляются не совсем в ту сторону, в которую мы ожидаем. В результате появляются дырки в 1px между элементами. Можно решать это с помощью calc из CSS, добавляя или вычитая 0.5px из нужных значений, а в нашем контексте – можно сделать фигуры немного больше, чем они должны быть по идее (помните о том, что на маленьких экранах нужно увеличивать сильнее — в примере это намеренно не сделано и при уменьшении размера окна можно заметить появление просветов между прямоугольниками). При правильно подобранных значениях для увеличения никто не заметит, что там что-то не так.

Точно таким же образом можно сделать “пузырьки”, чтобы следующий слайд расползался по предыдущему в виде увеличивающихся кругов или в виде кляксы, если вы ее нарисуете в виде замкнутой кривой, различные мозаики из многоугольников или пазлы, когда единственное, что нам нужно делать – это менять цвет заливки этих фигур в маске, и много других интересных эффектов — все зависит от вашей фантазии.

Заключение

Маски – это очень полезный инструмент в арсенале фронтендера. Тем, кто только начинает входить в эту тему, стоит уделить им определенное внимание, поскольку они не требуют долгого изучения и дают мощные результаты здесь и сейчас.

Если вы хотите почитать о простых идеях создании какого-либо другого семейства эффектов (в контексте фронтенда, разумеется) – оставляйте ваши предложения в комментариях.

FavoriteLoadingДобавить в избранное

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *