Хабрахабр

[Перевод] Sketch + Node.js: генерируем иконки для множества платформ и брендов

Если же у вас с десяток проектов, несколько платформ и множество А/Б-тестов на дизайн, то достаточно делать всё то же самое, только в 40 раз чаще и нигде не ошибаться… либо постараться автоматизировать процесс. Нет ничего проще, чем добавить иконку в проект: нужно всего лишь написать дизайнеру, он экспортирует её из Sketch и пришлет вам нужный вариант, а вы используете ее у себя в коде. Под катом — первая часть перевода статьи моего коллеги Cristiano Rastelli про один из примеров такой автоматизации.

Проблема, которую мы решали

Мы в Badoo разрабатываем приложение для знакомств. Вообще-то это несколько приложений, каждое из которых функционирует на нескольких платформах (iOS, Android, Mobile Web, Desktop Web), и работу над ними ведут несколько команд.

Некоторые одинаковы в каждом приложении, другие — соответствуют тому или иному бренду. При разработке мы используем сотни различных иконок. Это не только отнимало время, но и зачастую приводило к ошибкам. Иногда дизайн меняется, а вместе с ним меняются и иконки: появляются новые, какие-то обновляются, какие-то — удаляются (но часто остаются при этом в кодовой базе).
Созданием и поддержкой иконок занимается наша команда дизайнеров, и когда иконки готовы к работе — дизайнеры обычно отправляли их по email, через чат или облако. Поэтому дизайнеры и разработчики вынуждены были находиться в постоянном контакте; разработчики экспортировали иконки напрямую из Sketch-файла, и те добавлялись в кодовую базу, но проверки на предмет наличия в базе аналогичных, доступных для повторного использования иконок не проводилось. Если честно, ошибки были каждый раз (все мы люди): иногда иконки обновлялись на одной платформе, но не обновлялись на другой, иногда они пропадали или не соответствовали по формату или размеру. Уверен, вы хорошо понимаете, о чём я говорю.

По сути, теперь изменения в дизайне (например, вид границы кнопки, цвет фона страницы, размер заголовка или продолжительность анимации во всплывающем окне) могут быть описаны с помощью набора параметров, который потом автоматически экспортируется и используется во всех приложениях на всех платформах. У нас в Badoo есть дизайн-система под названием Cosmos, и недавно мы представили мультиплатформенную (Mobile Web, Android и iOS) библиотеку токенов.

Поэтому следующим их вопросом (а заодно и заданием) было: «А нельзя ли сделать нечто похожее для ресурсов?» Мы ответили: «Да, можно (наверное)». Наше решение, позволяющее за короткое время в несколько кликов трансформировать дизайнерские идеи (например, изменение цвета) в функционирующий код, впечатлило наших продакт-менеджеров и дизайнеров в равной степени.

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

Требования

Требования к MVP-проекту были ясны: инструмент, который на входе получал бы Sketch-файл, а на выходе выдавал все иконки во всех необходимых нам форматах и поддерживал бы вариации иконок для A/B-тестов.

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

Обратите внимание на то, что используемые в иконках цвета — не просто цвета: они в точности соответствуют указанным в токенах цветам бренда и конкретных фич.

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

Sketch и SketchTool

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

Мы представляли себе процесс примерно так: экспортировать иконки из Sketch-файла в формате SVG, затем «скормить» SVG-файлы версиям для мобильного браузера и Android, а для iOS найти библиотеку, которая конвертирует SVG в PDF. Фактически в начале проекта мы даже не были уверены, какой формат файлов необходим для платформ. В сущности, для этого нам и понадобился MVP — чтобы понять, реализуем ли наш проект, и, если да, насколько он будет трудоёмким. Таким план был изначально, хотя мы и понятия не имели, сработает ли наша задумка и с какими проблемами мы можем столкнуться.

Они всегда почти справляются с задачей, но никогда не делают это на 100%. Не знаю, приходилось ли вам работать с PDF-конвертерами, но мой опыт говорит, что это кошмар. Поэтому спинным мозгом я ощущал, что мы идём по скользкой дорожке.

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

Переименовав .sketch в .zip, вы можете открыть файл двойным щелчком; в получившейся папке вы увидите список JSON-файлов и файл для предварительного просмотра в формате PNG. Я знал, что внутренняя структура Sketch-файла, по сути, представляет собой архив.

Итак, я начал изучать JSON-файлы в попытке понять, как они между собой связаны.

У вас есть страницы, артборды и слои. Я обнаружил, что, хотя они и имеют большую степень вложенности (и велики по размеру), отношения между различными сущностями внутри объектов не столь запутанны. У каждой из этих сущностей есть уникальный ID, позволяющий сохранить связь между разными файлами; а все страницы сохраняются в JSON-файлах и содержатся в подпапке pages (ID страницы служит именем файла). Внутри каждого слоя содержатся пути (paths), у которых могут быть общие стили.

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

, "fillType": 0, "noiseIndex": 0, "noiseIntensity": 0, "patternFillType": 1, "patternTileScale": 1 } ], "miterLimit": 10, "startMarkerType": 0, "windingRule": 1 }
}

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

SketchTool

Таким образом, когда первичное исследование было завершено, план «Экспортируем иконки в SVG, а потом конвертируем» превратился в «Сделаем для Sketch плагин, который позволит напрямую экспортировать иконки в конечном формате». Однако и тогда ещё схема работы была довольно размытой (и не факт, что реализуемой).

И в тот момент я наткнулся на инструмент, о котором прежде не слышал, — SketchTool. Изучая исходный код существующих плагинов, я пытался понять, могут ли они взаимодействовать с API экспорта из Sketch, и, если да, то как.

Согласно документации, он
SketchTool — официальный инструмент Sketch (то есть разработанный Bohemian Coding).

Также она позволяет вам управлять некоторыми функциями Sketch из командной строки — например, запуском плагинов. является утилитой командной строки, идущей в комплекте со Sketch и позволяющей выполнять с документами в формате Sketch определённые действия, например проверять или экспортировать ресурсы.

Подождите-ка, утилита командной строки, позволяющая выполнять экспорт ресурсов? То что нужно! К тому же, поскольку это официальный инструмент, не должно возникнуть проблем с совместимостью версий, устареванием, поддержкой и т. д.

Я начал изучать утилиту и прочёл всю документацию — единственную страницу на сайте Sketch (в Интернете ей посвящено очень мало материалов, поэтому неудивительно, что я услышал о ней только сейчас).

SketchTool прилагается к Sketch, и её можно найти по адресу: Sketch.app/Contents/Resources/sketchtool/

Выполнив в терминале команду $/Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool, вы получите следующий результат (я немного упростил данные):

Usage: sketchtool <command> [<args>] [--formats=<string>] [--use-id-for-name{=YES|NO}] [--export-page-as-fallback{=YES|NO}] [--serial{=YES|NO}] [--context=<string>] [--application=<path>] [--without-activating{=YES|NO}] [--item=<string>] [--items=<string>] [--safemode{=YES|NO} | --no-safemode | -S {<YES|NO>}] [--max-size=<float> | -m <float>] [--background=<string> | -g <string>] [--compression=<float> | -c <float>] [--new-instance{=YES|NO}] [--reveal{=YES|NO}] [--timeout=<float>] [--include-symbols{=YES|NO}] [--bounds=<rectangle>] [--outputJSON=<path>] [--filename=<string>] [--wait-for-exit{=YES|NO}] [--scales=<path>] [--overwriting{=YES|NO}] [--group-contents-only{=YES|NO}] [--trimmed{=YES|NO}] [--help] [--progressive{=YES|NO}] [--save-for-web{=YES|NO}] [--output=<path>]
Commands:
dump Dump out the structure of a document as JSON.
export artboards Export one or more artboards
export layers Export one or more layers
export pages Export an area from one or more pages
export preview Export a preview image for a document
export slices Export one or more slices
help Show this help message.
list artboards List information on the document's artboards.
list formats List the supported export formats.
list layers List information on all of the document's layers.
list pages List information on the document's pages.
list slices List information on the document's slices.
metadata List the metadata for a document.
run Run a command from a plugin, inside Sketch.
show Show the location of the various sketch folders.
See ‘sketchtool help <command>’ for more information on a specific command.

Как видите, у инструмента есть четыре основные функции:

read/dump — прочитать/создать дамп метаданных внутренних JSON-файлов,
list — создать список сущностей файла,
export — экспортировать эти сущности,
run — запустить команду, предоставляемую плагином.

В случае экспорта почти все опции, которые можно найти в соответствующей панели, доступны и в командной строке SketchTool: В дополнение к этому каждая команда имеет несколько доступных опций.

Шикарно! Это означает, что SketchTool позволяет использовать для экспорта (например, из SVG в PNG или PDF) непосредственно Sketch, не прибегая к помощи внешних конвертеров.

Sketch может всё! Быстрый тест с использованием SketchTool и обычного Sketch-файла с несколькими иконками внутри подтвердил наши догадки: благодаря этому простому инструменту мы можем не задействовать для экспорта внешние программы и не писать свои.

Файл(ы) Sketch

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

Изначально мы планировали работать лишь с ограниченным набором иконок, сформированным для MVP-проекта, но быстро поняли, что будет лучше собрать их все, — чтобы сразу устранить дублирование, несогласованность и другие проблемы.

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

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

Динамическая колоризация иконок с помощью общих стилей (и дизайн токенов)

Следующим шагом после сбора иконок было применение к ним нужных цветов. Мы создали в Sketch набор предопределённых общих стилей (Shared Styles), названия которых соответствовали названиям токенов нашей дизайн-системы, а затем использовали их для раскрашивания иконок.

Вот пример того, как стиль применяется к определённому слою:

А вот как объявляются стили, а затем применяются к элементу:

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

Названия страниц и артбордов, используемых для A/B-тестирования

Пришло время понять, как дать возможность дизайнерам проводить A/B-тестирование иконок. И вновь мы решили прибегнуть к соглашению о наименовании (я большой поклонник принципа KISS).

В данном случае мы использовали названия страниц для определения тестируемого набора (с помощью префикса XP_), а названия арбордов — для определения, к какому ресурсу относится A/B-тест и к какому именно из его вариантов (указывается в квадратных скобках).

Таким образом, впоследствии ресурсы могут быть корректно сопоставлены с конкретной пользовательской группой. Используемые для теста названия и варианты не придуманы нами — они должны совпадать с уникальными ID, присвоенными тестам и вариантам в нашем собственном инструменте сплит-тестирования.

Несколько файлов для нескольких брендов

Последнее что нас интересовало, — как поддерживать разные формы одной и той же иконки для разных брендов?

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

Пришёл черед написания кода. Наши Sketch-файлы готовы!

Вторая появится в нашем блоге через несколько дней. Примечание переводчика: Как я уже говорил, статья состоит из двух частей, и это первая часть перевода. Спасибо за внимание.

Показать больше

Похожие публикации

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

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

Кнопка «Наверх»