javascript

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

  • понедельник, 19 февраля 2018 г. в 03:12:58
https://habrahabr.ru/post/349362/
  • Разработка веб-сайтов
  • JavaScript




О существовании 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>

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



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

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

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


Можно зарисовать только необходимую фигуру, а можно выйти немного за ее пределы – это простой способ добавить небольшие паузы в закрашивании.
А теперь мы сделаем линию потолще и прорисуем ее от начала до конца, анимируя свойство 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 делать такие вещи сложно. Но если взять маски, состоящие из нескольких прямоугольников, которые двигаются в одном направлении или увеличиваются в размерах, то все становится куда проще:

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

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