[Перевод] UX-команда MailChimp: Паттерны и SVG-анимация [5-я часть книги]
[ 1-я часть книги ][ 2-я часть книги ][ 3-я часть книги ][ 4-я часть книги ]
Разбираемся с библиотекой паттерновФедерико ХолгадоКнига «Refabricating Architecture», написанная Стефеном Кираном и Джеймсом Тимберлейком, в значительной степени повлияла на мое понимание дизайна. Авторы этой книги сравнивают архитектуру с автомобильной, аэрокосмической и кораблестроительной индустрией, обсуждая практически полную неизменность строительных процессов (с фундаментальной точки зрения) в рамках последних 80-ти лет на контрасте со стремительными переменами в других отраслях производства и дизайна.
Они пишут о том, что в традиционном понимании процесс строительства заключается в доставке всех необходимых компонентов на строительную площадку и последующей сборке. Архитектор проводит исследование площадки, производит необходимые измерения и готовит соответствующие чертежи; далее — команда строителей интерпретирует результаты его работы, готовит площадку, используя различную технику, и начинает работать с фундаментом. По мере готовности структуры здания проводят коммуникации и переходят к отделочным работам.
Киран и Тимберлейк сравнивают этот процесс с аналогами из других сфер деятельности. Например, в автомобилестроении совмещаются сразу несколько процессов, что позволяет оптимизировать производство, сократить затраты и повысить качество производимой техники. Компоненты автомобиля не производят в рамках одного завода, а заказывают у сторонних подрядчиков. Модульный подход отлично зарекомендовал себя и в кораблестроении, и в аэрокосмической сфере.
Когда мы начали работать над редизайном нашего приложения в 2013-м, мы решили применить аналогичную разбивку процессов и модулей. В результате мы должны были получить систему, состоящую из взаимозаменяемых частей или «атомов» — наименьших компонентов. Более крупные компоненты должны были состоять из таких «атомов» и составлять ядро приложения. При этом была необходима последовательность в структуре и дизайне страниц и подсистем приложения.
В нашей библиотеке паттернов есть базовые элементы с готовыми компонентами на основе «атомов», позволяющие разработчикам создавать интерфейсы, согласующиеся с уже имеющимися системами. Далее я расскажу о практическом применении данной библиотеки.
Практика
Занявшись редизайном, мы начали с наиболее популярного раздела приложения — панели управления. В старой версии мы отображали данные по простой сетке, но поработав со скетчами и прототипами, решили внести изменения. Мы попробовали ввести два режима: с красивыми карточками и более информативной сеткой. «Визуальный» подход не сработал в силу того, что большинство кампаний наших пользователей выглядят достаточно похоже. При этом мы знали, что нашим клиентам очень важно иметь возможность сортировки кампаний по их атрибутам, что исключило и «табулярный» подход.
Таким образом, мы пришли к реечной системе, позволившая установить связь с различными разделами приложения. В итоге она пригодилась сразу в трех его разделах. Вместо сортировки мы использовали фильтры (где это было уместно) и получили в итоге готовую основу нашей панели управления. Несколько месяцев, потраченные на разработку реечной системы, окупились целым рядом преимуществ. Нам не нужно было тратить время на редизайн сразу нескольких других частей приложения. Ниже представлены мобильные версии разделов кампаний и экспортирования, сходство которых легко заметить. Адаптация реечной системы для панели управления экспортированием заналя всего 45 минут с учетом мобильной версии.
Мы применили реечную систему в целом ряде разделов приложения, которым ранее не уделялось достаточно внимания с точки зрения дизайна, но с именно паттерны позволили встроить эти разделы в общую дизайн-концепцию и обеспечить работу даже на очень скромном экранном пространстве. Еще один плюс такого подхода заключается в том, что мы смогли распределить человеческие ресурсы команды и организовать параллельную работу как над реечной системой, так и над общей структурой страниц, навигацией и т.д. Часть команды работала на базой, а другая часть занималась оформлением, при этом все были в курсе происходящего.
Что еще было сделано
Благодаря использованию такого подхода, нам удалось обеспечить модульность не только реечной системы, но и практически всех частей приложения: форм, кнопок, таблиц, элементы редактора и т.д. На первом этапе работ было достаточно сложно размышлять в такой концепции, когда ты уже привык готовить отдельные UI-элементы для каждой из новых идей. Таким образом, мы пришли к относительно хаотичному CSS, разнородному оформлению и различиям в программной реализации элементов.
Инвестиции в виде затраченного времени окупились, а мы многому научились, заимствуя опыт из других индустрий: модульный подход, организация процессов разработки и т.д. В процессе работы наша команда постоянно обменивается идеями — front-end разработчики всегда поддерживают контакт с инженерами. Наши дизайнеры помогли нам разобраться с принципами вертикального и горизонтального ритма, позволившего упростить верстку страниц. Теперь и back-end разработчики могут готовить универсальные системы, которые можно использовать повторно. Конечно, это позволяет сократить временные затраты на разработку, обеспечивая понимание стандартных состояний интерфейса.
Общий уровень аккуратности и согласованности, которого нам удалось достичь, радует не только нас, но и позволяет нашим клиентам эффективнее решать свои задачи. На сегодняшний день у нас есть стандартизированная система, позволяющая обеспечить дальнейшнее развитие. Кажется, что мы на правильном пути, исходя из тех знаний, которые мы получили, изучая другие сферы производства.
SVG, садись, 5! Калеб Эндрюс, Альваро СанчезМы достаточно долго и внимательно исследовали процесс использования нашего приложения клиентами. Не только для того, чтобы сделать наш продукт лучше, но и для общего понимания ощущений и мыслей клиентов, возникающих в процессе работы с ним. Исходя из такого опыта, мы понимаем, что отправка новостной рассылки — это достаточно волнительный процесс в силу сжатых сроков и необходимости исключить возможные ошибки. Чего только не делают люди перед отправкой писем своим подписчикам: кусают губы, потирают ладони и иногда чуть ли не потом обливаются. Мы и сами через все это проходим, работая над собственной рассылкой UX Newsletter.
Понимая эмоциональный контекст данного процесса, мы хотели поддержать наших клиентов, продемонстрировав им свое понимание происходящего. Мы решили, что в этом нам может помочь Фредди [талисман MailChimp], который по задумке «дает пять» всем, кто успешно справился с отправкой. Ранее мы отображали статичную ладонь Фредди и решили слегка оживить этот момент с помощью SVG-анимации.
SVG-анимация — это не какая-то новая технология, но многие только недавно добрались до работы с ней. Для того, чтобы структурировать наш рассказ, мы разбили его на две части: подготовка к работе с SVG и реализация на примере ладони Фредди.
Калеб: «Более лучшая» SVG
Начнем с подготовки файлов. Для начала необходимо разобраться с иерархией слоев.
Она является ключевым элементом в работе над SVG-иллюстрациями в Illustrator. Мы решили делить анимационные фреймы на группы так, чтобы на каждой иллюстрации не было ничего лишнего: только самое необходимое. Важно быть аккуратным с выбором названий для групп, чтобы понимать, для чего предназначены элементы, которые в них содержатся, и правильно прописывать путь к ним в текстовом редакторе (что придется сделать в процессе написания скрипта).
Удаление лишних опорных точек
Чем меньше точек, контуров и их групп содержит каждый слой, тем «легче» будет исполняться SVG-код. А если установить набор скриптов для Illustrator от Хироюки Сато, лишние опорные точки можно будет удалить, просто открыв вкладку Файл > Скрипты > Удалить опорные точки.
Маски хороши, но только в меру
На рисунке выше жест «дай пять» от Фредди был создан из 3 групп элементов, объединенных в один SVG-файл без использования масок. Эти группы представляют собой анимационные фреймы, которые можно скрыть или, наоборот, сделать видимыми тогда, когда это становится необходимо. Впоследствии мы решили создать маски, чтобы сделать SVG-анимацию более контролируемой и «чистой».
Отключите возможность редактирования в Illustrator
Теперь вам нужно экспортировать ваши рисунки из Illustrator как SVG-файл. Этот момент легко упустить: сохраняя файл в формате SVG, не забудьте отключить функцию «Сохранять возможность редактирования в программе Illustrator» во вкладке «Опции». Это позволит вам сделать итоговый файл гораздо легче — в браузере эти возможности вам не понадобятся. Такую процедуру надо производить только с финальной версией иллюстрации — как несложно догадаться, после этого файл будет уже не так-то просто снова открыть и отредактировать в Illustrator.
Фигуры против контуров
Вы можете открыть свой SVG-файл в текстовом редакторе и оценить созданный код. В примере мой SVG-файл содержит два элемента — прямоугольник и контур. В теории это два одинаковых прямоугольника, но код, генерирующий их, принципиально отличается. Если вам непривычно работать с контурами, их можно легко преобразовать с помощью команды «Объект» > «Разобрать».
Вывод
Не так уж все и сложно, правда? Немного вдумчивой подготовки, и создать SVG-анимацию, которая привлечет внимание и не затормозит работу браузера, оказывается совсем несложно.
Альваро: что скрывает жест «дай пять»
Калеб объяснил, как мы подготавливали нашу SVG-анимацию, теперь я попытаюсь пойти дальше и объяснить, что мы делали дальше. Я упростил свои объяснения, но в конце указал ссылку на исходный код на случай, если вам захочется увидеть все компоненты итоговой анимации.
Подготовка
Когда я только взялся за проект с анимацией Фредди, мне дали ее прототип, сделанный в After Effects, а затем экспортированный в GIF. Калеб помог мне воссоздать в Illustrator объекты из прототипа: лапку Фредди, мех и т.д. После того, как я расположил элементы каждый на нужном слое, я экспортировал их как SVG-файлы. В итоге у нас получилось 3 SVG-файла по одному на каждое изображение лапки Фредди. Затем я задумался над тем, как анимировать созданные образы.
Немного покопавшись в библиотеках JavaScript, я решил работать с Snap.svg. Snap поддерживает такие функции как создание масок, обрезка и выравнивание, создание узоров, градиентов, группировка элементов. Он также предоставляет простой и интуитивно понятный API для анимации.
Имплементация функции анимирования — «mina» (это «anim» [от слова «animation»] наоборот) использует запрос AnimationFrame, благодаря чему анимация воспроизводится в браузере без сбоев, как объяснил Пол Айриш (Paul Irish).
(Между прочим, если вы используете библиотеку, которая не поддерживает запрос AnimationFrame для анимации элементов, учитывайте возможность возникновения такого явления как «layout thrashing». Оно возникает, когда JavaScript снова и снова добавляет и удаляет элементы из DOM, тем самым замедляя работу браузера).
Анимация движения
Я создал анимацию жеста «дай пять» из 3 отдельных изображений лапки Фредди, каждое из которых отражало разную ее (лапки) позицию. Чтобы финальное изображение выглядело как единый объект, принимающий разные положения, мне нужно было создать «сглаженные» переходы из одного положения в другое. Для этого я применил технику пошаговой анимации и связал три основные изображения дополнительными «переходами». (Почему я не анимировал просто одно-единственное изображение? Учет всех точек на покрытой шерстью лапке Фредди, подсчет и настройка угла «скривления» лапки в каждом положении оказались слишком сложными в условиях сжатых сроков проекта).
Чтобы загрузить все три изображения, я использовал функцию Snap.load. Поначалу я вызывал эту функцию для каждого из изображений в отдельности. В результате итоговая картинка неплохо анимировалась в Firefox, но в Google Chrome с анимацией возникли проблемы. В итоге я понял, что Firefox «распознавал» все переходы и изначально заданные значения вне зависимости от того, сколько раз я вызывал функцию Snap.load. Chrome, однако, не сохранял информацию о переходах и заданных значениях, потому что каждый новый вызов Snap.load создавал новый SVG-фрагмент с собственной областью просмотра и системой координат. Я решил этот вопрос, сохранив все исходные материалы (3 вариации положения лапки Фредди) в одном SVG, поэтому мне понадобилось вызвать функцию только один раз вместо трех.
Следующим шагом мне нужно было определить порядок появления элементов в финальной версии анимации.
Чтобы добиться этого, мне понадобилось использовать функцию Snap.svg для группировки элементов. Например, для такой группироваки:
// Order of grouping is important!!! // s = SVG canvas created by Snap var group = s.group ( circleBG, hand1, hand2, hand3 ); Группировка также задает порядок расположения элементов в стеке: элемент circleBG будет находиться в самом низу, а hand3 — наверху.
Затем мы создали и применили маску к указанной группе, благодаря чему анимация элементов происходила «внутри» контура, заданного маской — в данном случае — внутри круга.
Маску мы создали так:
// Create a circle at x:200 and y:200 // and 200 px radius circleMask = s.circle ( 200, 200, 200 ); // Fill with white circleMask.attr ({ fill:»#FFFFFF» }); Чтобы применить маску к элементам группы, я добавил к ней (группе) атрибут маски:
group.attr ({mask: circleMask});
Как только мы создали и применили маску, я задал позицию каждого элемента и сделал нужные из них видимыми на итоговом изображении. Для нашего жеста «дай пять» я загрузил 3 элемента, которые я анимировал, один за другим и с разными интервалами.
Я задал позицию лапки в каждом из ее положений с помощью строки трансформации:
// Initialize position. arm1.transform ( «s0.6r-30t-100, 280» ); Каждая буква — это команда: «s» — для масштабирования [«scale»], «r» — для поворота [«rotate»], «t» — для команды translate.
Используя эту нотацию, я сделал элемент arm1 на 40% меньше, я повернул его на -30 градусов и расположил его вне границ маски так, чтобы он не был видимым.
Я применил похожие команды для инициализации элементов arm2 и arm3, но скрыл их, выставив значение показателя «непрозрачность» на 0.
// Set opacity to 0 arm2.attr ({opacity: 0}); Объединение элементов
Завершив эти операции, я начал анимировать изображения и создавать переходы между ними. Тут начинается самое интересное.
В Snap.svg есть функция Animate. Она получает следующие атрибуты:
Element.animate ( attrs, duration, [easing], [callback] ); Вот пример первой анимации для жеста «дай пять»:
arm1.animate ( {transform:'t-50,60'}, 400, mina.backout, function (){ // callback code here } ); Используя атрибуты трансформации и новые значения в качестве первого из параметров функции, я запрограммировал движение элемента arm1 от позиции -100 px до -50 px по оси Х и от 280 px до 60 px по оси Y.
Второй атрибут (400) — общая длительность анимации в миллисекундах.
Третий атрибут (mina.blackout) — функция тайминга, подобная mina.linear, mina.easein, mina.easeout и т.д. Функция mina.blackout создает эффект «взмаха», делая движение более естественным.
Четвертый атрибут — функция обратного вызова, которая исполняется, как только завершается анимация. Это очень важно, потому что так вы можете привязать одну анимацию к другой и контролировать создание согласованного анимированного ряда.
Например, при переходе между элементами arm1 и arm2 я скрываю arm1, используя функцию обратного вызова первоначальной трансформации. Как только процесс завершается, элемент arm1 перестает быть видимым (display: none), и начинается процесс анимирования элемента arm2.
Это все происходит очень быстро — «затухание» первого элемента длится 30 миллисекунд, а появление второго — 10 миллисекунд.
Вот часть кода, описывающая указанные callback-функции:
arm1.animate ( {transform: 't-50,60'}, 400, mina.backout, function (){ //400ms arm1.animate ( {opacity: 0}, 30, mina.linear, function (){ // hide arm1 arm1.attr ( {display: «none»} ); // Chain/Start // animation for arm2 _highFive.animate02(); // fadein 10ms }); }, 100); Для более детального обзора кода, который был создан для анимации жеста «дай пять», можете самостоятельно изучить исходную версию.