Статьи

Лучший способ создать фантастические эффекты «Невидимая ручка» в SVG

Невидимая ручка

Начиная с тега BLINK начала 90-х годов и заканчивая современными переходами и анимацией CSS3, возможность перемещать элементы на веб-страницах / в приложениях всегда была заманчивой целью.

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

Идея не нова. Еще в 1953 году в « Duck Amuck » невидимая рука (позже выяснилось, что это Bugs Bunny) классно мучает бедную Даффи-утку, постоянно стирая и перерисовывая окружающий мир. Это сюрреалистический шедевр.

Сцена из утки Amuck

Утка Амук — 1953 — Режиссер Чак Джонс

Перенесемся в 2013 год, и Джейк Арчибальд умело продемонстрировал, как можно манипулировать stroke-dashoffset , stroke-dasharray и некоторыми CSS stroke-dasharray чтобы создать этот «эффект волшебного пера» на любом пути SVG.

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

Я полагаю, что главный вопрос, который возникает у вас в голове сейчас: что делает Vivus лучшим решением, чем чистый CSS-подход?

На мой взгляд, у Vivus есть три основных преимущества, которые следует упомянуть:

  1. Простота использования : в Vivus мы контролируем большинство наших свойств анимации в «конструкторе» Vivus и в контексте вместе с нашим SVG-документом. Это делает изменения более удобными и интуитивно понятными для работы. С помощью всего лишь нескольких настроек мы можем получить совершенно другой результат анимации.

  2. Автоматизация . Как вы, возможно, уже знаете, SVG stroke-dashoffset свойство stroke-dashoffset — ключ к этому эффекту — доступно только для элементов path . Это может вызвать проблемы, если ваш чертеж SVG содержит circle , rectangle , line , polyline или другие распространенные объекты SVG «без контуров».

    К счастью, Vivus достаточно умен, чтобы автоматически конвертировать все объекты SVG в элементы пути, что позволяет нам их анимировать. Это огромное преимущество.

    Тем не менее, обратите внимание, что нам нужно преобразовать весь text элемент вручную в контуры, используя векторный редактор, такой как Illustrator, InkScape и другие.

  3. Гибкость : Vivus предлагает пять предустановленных типов анимации, а также множество опций для манипуляции, что дает нам большую гибкость в отношении поведения нашей анимации.

Теперь давайте начнем исследовать Vivus более подробно и увидим эти преимущества в действии.

Внимание дизайнеров: Да, впереди некоторый код, но Vivus предназначен для дизайнеров. Даже если вы не хардкорная кодовая обезьяна, небольшое вырезание, вставка и редактирование принесут вам довольно интересные результаты.

Исследуя Вивус

Чтобы начать использовать Vivus, нам нужно включить его в наш HTML-код следующим образом:

 <script src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.3.2/vivus.js"></script> 

Затем мы можем использовать встроенный SVG следующим образом:

 <svg id="canvas"> <path...> <path...> <path...> </svg> 

И сценарий:

 <script> new Vivus('canvas', {duration: 300}, callback); </script> 

Здесь у нас есть встроенный SVG и функция конструктора Vivus, которая принимает три параметра:

  • Идентификатор элемента DOM, с которым мы хотим взаимодействовать (наш идентификатор — «холст»).

  • Объект option, в который мы помещаем все параметры анимации.

  • И дополнительная функция обратного вызова, вызываемая в конце анимации.

Прежде чем двигаться дальше, нам нужно знать следующее:

  • По умолчанию Vivus рисует элементы в том же порядке, в котором они определены в документе SVG.

  • Все элементы SVG должны иметь свойство обводки и не могут быть заполнены.

  • Мы не должны помещать какие-либо скрытые элементы пути в наш SVG. В противном случае анимация может отображаться неправильно.

  • Текстовые элементы не могут быть преобразованы в элементы пути. Если вы хотите использовать текст в нашей анимации, нам нужно сначала преобразовать его в контуры (в редакторе, таком как Illustrator, InkScape).

Пять вариантов рисования Vivus

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

С задержкой

CodePen

Здесь наш рисунок SVG состоит из четырех линий одинаковой длины. В режиме delayed , который является анимацией по умолчанию, все пути начинаются почти одновременно с небольшой задержкой между каждым.

По одному

CodePen

В режиме oneByOne каждый путь рисуется один за другим. В приведенном выше примере те же четыре линии нарисованы одна за другой непрерывным образом.

асинхронный

CodePen

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

сценарий

Этот и следующий тип анимации дают нам возможность устанавливать свойства анимации непосредственно в DOM SVG. Это позволяет нам получить больше контроля над нашей анимацией и улучшить ее гораздо точнее.

В режиме scenario нам просто нужно определить время начала и продолжительность каждого элемента пути с атрибутами data-start и data-duration . Если он отсутствует, он будет использовать значение по умолчанию, данное конструктору.

CodePen

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

 <line data-start="200" data-duration="200" .../> <line data-start="0" data-duration="100" .../> <line data-start="100" data-duration="10" .../> <line data-start="300" data-duration="100" .../> 

Как мы видим, чтобы управлять нашей анимацией, нам просто нужно выполнить простые математические вычисления. И вот здесь проявляется гибкость Vivus. Мы не должны уважать первоначальный порядок SVG. Мы можем начать с любого элемента, который пожелаем, и продолжить со всеми остальными в любом порядке, который нам нужен.

Сценарий-Sync

В режиме scenario-sync поведение по умолчанию такое же, как и в режиме oneByOne . Однако мы можем дополнительно улучшить анимацию, нацелив некоторые атрибуты на конкретные элементы пути, такие как:

  • data-duration — определить продолжительность анимации пути

  • data-delay — определить задержку между окончанием анимации предыдущего пути и началом текущего пути

  • data-async (значение не требуется) — сделать рисование пути асинхронным, то есть одновременно начнется следующий путь. Если путь не имеет атрибута для длительности или задержки, будут использоваться значения по умолчанию, установленные в объекте option.

CodePen

В приведенном выше примере рисуется первая строка с продолжительностью по умолчанию 200ms . Вторая строка начинается с задержкой в 100ms и такой же продолжительностью. Третья строка начинается сразу после второй и продолжается 300ms . Поскольку третья строка имеет свойство data-async , последняя строка начинается в то же время, что и третья, но заканчивается до нее, поскольку ее продолжительность составляет 200ms .

Вот упрощенная схема нашего SVG:

 <line .../> <line data-delay="100" .../> <line data-duration="300" data-async .../> <line data-duration="200" .../> 

Полные примеры

Теперь, когда мы уже понимаем различные типы анимации, предлагаемые Vivus, пришло время протестировать их более практичным и реалистичным способом. В этом разделе мы собираемся создать две полные анимации, используя режимы `delayed` и` scene-sync`.

Чертеж автомобиля

В первом примере мы создадим этот проект из Seat Leon:

Файл ( Free vector art через Vecteezy! ) Был открыт в Illustrator, а затем экспортирован как SVG. Полный код SVG приведен в примере CodePen в конце этого раздела.

Сначала в нашем файле JavaScript или <script> мы создаем новый конструктор Vivus, указывающий на наш SVG с помощью идентификатора canvas . В объекте option мы определяем тип анимации, которая будет delayed и функцию синхронизации для всей анимации.

Для этого мы используем встроенный метод синхронизации Vivus.EASE . В результате анимация начнется и закончится более плавно. Мы также добавили функцию обратного вызова, которая будет сбрасывать рисунок через три секунды после окончания анимации, а затем будет рисовать его снова.

 new Vivus('canvas', { start: 'autostart', type: 'delayed', animTimingFunction: Vivus.EASE }, function(car){ setTimeout(function(){ car.reset().play(); }, 3000); } ); 

Вы можете увидеть окончательный результат здесь:

Как видите, мы получаем удивительный эффект анимации чертежа с минимальными усилиями с нашей стороны.

Ракетный рисунок

Во втором примере мы создадим анимацию ракеты и добавим цвет.

Простая ракета

Наша цель — нарисовать ракету, заполнить ее, а затем убрать удар. Код SVG см. В примере CodePen в конце этого раздела.

Мы начнем снова с нового конструктора Vivus. На этот раз мы установили тип анимации для scenario-sync по scenario-sync и установили для pathTimingFunction значение Vivus.EASE_OUT . Мы используем функцию обратного вызова, которая добавит несколько классов CSS в конце анимации. Они заполнят ракету и уберут ее удары.

 new Vivus('canvas', { start: 'autostart', type: 'scenario-sync', pathTimingFunction: Vivus.EASE_OUT }, function(obj){ obj.el.classList.add('fill-1', 'fill-2', 'fill-3', 'fill-4', 'fill-5', 'fill-6', 'fill-7', 'clear-stroke'); } ); 

В нашем CSS-файле или <style> мы изначально установили fill-opacity равной нулю и переход для него продолжительностью 1s . Затем мы используем CSS-селекторы, чтобы назначить свойство fill для каждого элемента в SVG и сделать его видимым, установив для параметра fill-opacity значение 1 . Вы можете прочитать больше об этой уловке здесь .

И, наконец, мы устанавливаем stroke для каждого пути none .

 path { fill-opacity: 0; transition: fill-opacity 1s; } .fill-1 g:first-of-type > path{ fill: #1c8ece; fill-opacity: 1; } .fill-2 g:last-of-type > path{ fill: #ffffff; fill-opacity: 1; } .fill-3 path:first-of-type{ fill: #f4a260; fill-opacity: 1; } .fill-4 path:nth-of-type(2){ fill: #ea3e2f; fill-opacity: 1; } .fill-5 path:nth-of-type(3){ fill: #d1d2d4; fill-opacity: 1; } .fill-6 path:nth-of-type(4), .fill-6 path:nth-of-type(5) { fill: #000000; fill-opacity: 1; } .fill-7 path:nth-of-type(6){ fill: #ffffff; fill-opacity: 1; } .clear-stroke path{ stroke: none; } 

В нашем SVG мы используем свойства data-duration и data-delay для создания анимации в соответствии с нашими потребностями. свойство data-async используется для одновременного рисования двух крыльев ракеты.

Вот упрощенная схема SVG:

 <path data-duration="50" .../> <path data-duration="150" data-delay="100" .../> <path data-duration="50" .../> <path data-duration="50" .../> <g> <polygon data-duration="300" data-async .../> <polygon data-duration="300" .../> </g> <path data-delay="25" .../> <path .../> <g> <polygon data-async .../> <polygon .../> </g> 

Вы можете увидеть окончательный результат здесь:

Резюме

Как вы можете видеть, с Vivus мы можем сконцентрироваться прежде всего на нашей идее рисования и ее практической реализации, вместо того, чтобы жонглировать свойствами CSS. Когда у нас есть готовый SVG-документ, его довольно просто превратить в рабочую анимацию.

С небольшим воображением и анимационными возможностями Vivus мы можем создавать сложные и интересные анимации в кратчайшие сроки.