Найти в Дзене
WebBeaver

Анимированная SVG-маска своими руками

Как сделать простую анимированную SVG-фигуру и использовать её как маску?

Для начала в иллюстраторе или в любом другом векторном редакторе рисуем фигуру. Я рисовал с помощью инструмента «Кривизна». Боковые точки сделал опорными (двойным кликом), чтобы между ними не образовывалась дуга, которая выходит за пределы монтажной области.

Это у нас будет первый кадр. Рисуем ещё. Можно просто сдвинуть какие-то точки, можно нарисовать заново. Главное — чтобы количество точек было одинаковым на всех кадрах.

-2

Открываем наши кадры в редакторе. Видим подобный код для каждого кадра:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1024 320" style="enable-background:new 0 0 1024 320;" xml:space="preserve">
<style type="text/css">
.st0{stroke:#000000;stroke-miterlimit:10;}
</style>
<path class="st0" d="M-0.5,319.5c0-60.7,0-121.3,0-182c25.4-57.6,101.8-69.7,123-74c70-14.2,69,136.1,154,127
c52.9-5.7,79.9-130.4,144-143c70.4-13.8,85.3,138.9,168,135c78.9-3.8,97.4-137.9,168-136c74.3,2,79.9,139.9,152,144
c58.5,3.3,84.6-88.4,115-114c0,81,0,162,0,243"/>
</svg>

Теперь самое интересное. Для path указываем id, а атрибут dвырезаем. Создаём тег animate внутри SVG, прописываем ему длительность анимации (dur), количество повторов (repeatCount), как себя вести после завершения (fill). И самое главное: в xlink:href прописываем id, указанный для path. В attributeName — аттрибут, который хотим анимировать (в нашем случае, d). И, наконец, в values, через точку с запятой перечисляем все значения. В моём случае там перечислены все значения аттрибута d у каждого кадра.

Получается вот такой код:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1024 320" style="enable-background:new 0 0 1024 320;" xml:space="preserve">

<path id="mask" />

<animate
xlink:href="#mask"
attributeName="d"
attributeType="XML"
values="
M-0.5,319.5c0-60.7,0-121.3,0-182c25.4-57.6,52.8-74.7,74-79c70-14.2,117,102.1,202,93
c52.9-5.7,51.9-52.4,116-65c70.4-13.8,90.3,38.9,173,35c78.9-3.8,84.4-52.9,155-51c74.3,2,93.9,56.9,166,61
c58.5,3.3,107.6-29.4,138-55c0,81,0,162,0,243;
M-0.5,319.5c0-60.7,0-121.3,0-182c25.4-57.6,101.8-69.7,123-74c70-14.2,69,136.1,154,127
c52.9-5.7,79.9-130.4,144-143c70.4-13.8,85.3,138.9,168,135c78.9-3.8,97.4-137.9,168-136c74.3,2,79.9,139.9,152,144
c58.5,3.3,84.6-88.4,115-114c0,81,0,162,0,243;
M-0.5,319.5c0-60.7,0-121.3,0-182c25.4-57.6,153.8-88.7,175-93c70-14.2,23.1,112.9,102,146
c69,29,89.9-195.4,117-136c41,90,141.3,191,195,128c35-41,98.6-149.5,168-136c206,40,79.9,139.9,152,144c58.5,3.3,84.6-88.4,115-114
c0,81,0,162,0,243;
M0,320c0-60.1,0-120.3,0-180.4c11.4-25.5,31.5-58.7,67.1-75c75-34.3,132.9,45.8,256.5,45
c106.2-0.7,101-60.1,208.5-57c102.1,3,133.2,57.4,228,37.5c40.3-8.5,61.2-23.9,99-15c21.2,5,46.4,22.9,96,58.5
c4.5,3.3,68.8,49.4,68.9,49.5c0,45.6,0,91.3,0,136.9;
M-0.5,319.5c0-60.7,0-121.3,0-182c25.4-57.6,52.8-74.7,74-79c70-14.2,117,102.1,202,93
c52.9-5.7,51.9-52.4,116-65c70.4-13.8,90.3,38.9,173,35c78.9-3.8,84.4-52.9,155-51c74.3,2,93.9,56.9,166,61
c58.5,3.3,107.6-29.4,138-55c0,81,0,162,0,243"
dur="4s"
repeatCount="indefinite"/>
</svg>
Обратите внимание, что первое и последнее значения одинаковые. Это сделано для того, чтобы не было рывков от последнего кадра к первому.
Обратите внимание, что первое и последнее значения одинаковые. Это сделано для того, чтобы не было рывков от последнего кадра к первому.

Теперь применяем данную маску в CSS.

div{
-webkit-mask-image: url('mask.svg');
mask-image: url('mask.svg');
}

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