Прототипирование с натуры
или как использовать реальные данные во Framer X.
О прототипировании мы говорили неоднократно: и о низкоуровневом (типа сторифреймы, скетчи, микрофреймы — вот это вот всё), а также затрагивали проектирование более высокого уровня в обзоре Framer X. Однако сегодня я хотел бы пойти ещё дальше.
И я говорю не о высокоточном воспроизведении состояний и нарезке невероятного количества скринов для InVision или Zeplin, а о построении максимально реалистичного пользовательского опыта при помощи Framer X. Интересно? Нет? Блин…
Тогда давайте вспомним для чего вообще прототип нужен.
Прототип создаётся с целью проверки решения, его тестирования и дальнейшего улучшения.
И с этой фразой в голове, давайте ещё немного напряжёмся и вспомним ваше последнее тестирование концепта. Может, конечно, у вас всё происходило по-другому, но у меня это было примерно так:
«… только помните, что это прототип, и он не полностью проработан … нет, сюда нажать нельзя, а что бы вы хотели там увидеть? … ну давайте представим, что оно так «Пуф!» и исчезло … так Сергей, представьте, что вы Елена … не обращайте внимания, что добавляете сюда свинью, это же прототип … что, всё сломалось нафиг? эх, ну вы были почти у цели … »
Знакомо? Уверен, что кто-то уже находил себя в подобной ситуации. Но что с этим делать? В дополнение, все подобные тесты, на таких хлипеньких прототипах, должны быть модерируемыми (если только они не тривиальные), иначе пользователь не будет понимать, что происходит и может просто зафейлить тест, на шаг отойдя от заданного маршрута. А ведь нам, как я думаю, было бы интересно посмотреть и на количественные данные для разнообразия.
И я пока не нашёл каких-то инструментов, которые помогли бы лонгитюдно тестировать взаимодействие в условиях, максимально приближенным к реальным. Можно было бы конечно задевелопить PoC (proof of concept) и начать тестировать с него, итеративно внося изменения и выпрямляя метрики. Но давайте взглянем в лицо реальности: пока вы наполируетесь на ваш прототип, пока фронт-енд разработчик вникнет и сделает что и как вы хотите, пока подключите какие-нибудь моковые данные, пройдёт уже очень много времени.
Как вы могли догадаться, как решение я хочу предложить вам закатать рукава и по локти самим запустить их в тёмные дебри… ой да ладно вам, блин, пара строк кода во Framer X! Ребята, камон!
Disclaimer! Я не разработчик, я дизайнер. И рассказ буду вести как дизайнер, по-босяцки. То есть не исключены некоторые неточности в сложных синтаксическо-семантических определениях, и если вы захотите помочь мне их улучшить, поправить меня или объяснить, что и как на самом деле — я буду только рад.
Прежде, чем вы скажете маме «Я программист!»
Мы можем значительно облегчить себе жизнь, если заранее подготовимся к погружению. То есть запастись всем необходимым, чтобы не выходить из потока креативности и не обламываться на то, что что-то не работает.
Поставить Framer X. Блин, логично.
Поставить XCode. Самим им вам пользоваться не придётся, но вот необходимые зависимости для терминала подтянуть всё-таки придётся. Делается один раз и забывается.
Поставить Yarn. Что это за зверь и зачем он нужен можно узнать из урока по Framer. Но если в кратце, то этот менеджер пакетов и зависимостей поможет устанавливать чужой код в ваш проект. Захотите какую-нибудь библиотеку работы с датами и временем? Пишите одну команду и вуаля!
Завести аккаунт на GitHub. Если вы когда-либо сталкивались с версионированием, то уже могли познакомиться с основными концепциями через Abstract, Versions или ещё что-нибудь. GitHub позволит вам бесплатно вести версионирование вместе с разработчиками, вносить изменения и управлять ими. Это не понадобится прямо сейчас, но зато очень интересно.
Завести аккаунт на Netlify. Меня очень пропёрло, что можно соединить ваш репозиторий на GitHub и видеть изменения проекта в реальном времени… прямо онлайн.
Завести аккаунт на Firebase. Это очень пригодится, если вы захотите создать прототип с длительным хранением данных или соединять прототипы в режиме реального времени. По сути эта чудесная платформа агрегирует в себе всё необходимое для создания, тестирования и улучшения кроссплатформенных сервисов: вам не нужно париться создавая масштабируемую бэк-энд архитектуру (да и любую архитектуру в принципе), у вас сразу подключена аналитика и есть доступ к конечным пользователям через любые каналы коммуникации. Очень удобно и приятно :) Если интересно, то вот этот урок от команды Framer — просто бомба 💣.
Ну что, везде побывали и всё поставили? Тогда не будем откладывать. И начнём пожалуй с «…представьте, что оно так «Пуф», и исчезло…»
Оно живое! Или повторение — мать учения
Если вы уже смотрели прошлый беглый обзор Framer X, то знаете, что он в принципе обладает всей необходимой функциональностью, чтобы делать такие привычные интерфейсы. Тут есть и графический режим, и дизайн системы, цветовые переменные, адаптив и всё такое прочее. И при этом, мы рассматривали Framer X с обороняющейся стороны, а теперь пора перейти в нападение. Допустим, что вы уже нарисовали какой-то интерфейс, как и делали это раньше и сейчас, хотите вдохнуть в него жизнь.
Делать это можно и стандартными средствами, типа линковки элементов, создания модалок (все есть из коробочки) и так далее, а что если нам нужны микроинтерации?
Этот случай вполне себе можно покрыть магазином бесплатных компонентов, где вы сможете найти для себя всё, что только душеньке угодно: свайпы с открытием действия, преобразования svg, работа с картой и т.д.
Окей. А, что если я хочу сам? Тогда нам помогут Overrides, о которых речь уже шла в прошлой статье посвящённой Framer. Я быстро напомню, в чём их суть.
Override — это реиспользуемый кусочек кода, который определяет поведение компонента, к которому он привязан. Например, если на дизайне в нарисовали квадрат, а после привязали к нему Override, который говорит «Сим, размер твой будет в два раза меньше! А ещё повернись-ка!», то во время превью он действительно станет в два раза меньше и нехотя склонит колено.
Причем, это касается не только конкретных свойств, но ещё и реакции на триггеры. Например, наведение курсора мыши, тап или любое событие, которое нам нужно отследить.
Если вы нажмёте на волшебную кнопочку в правой панели с емким названием «Overrides», Framer вам сразу предложит несколько таких функций на выбор в файле «Examples». Если же мы хотим что-то диковинное, то можно создать новый файл (но он тоже будет не пустой :).
Благодаря этим маленьким функциям-помощникам мы можем универсализировать поведение на всём нашем проекте, ведь Override мы можем назначать сразу на несколько компонентов.
Что ещё туда можно писать? Да любой код, можно даже параметры анимации, которые очень хорошо описаны в документации. Но сейчас речь не о них.
Как вы могли заметить, все, что мы опишем в этом самом Override будет актуально для компонента с которым мы его связали, но что если мы хотим изменять какой-то другой объект по событию в текущем? Ну как, например, нажать на кнопку и изменить размер панели. Естественно, что и то и другое — разные компоненты.
Здесь нам на помощь приходит Data Object, в прототипе он называется appState и описывается в самом верху.
const appState = Data({
…
})По сути он является глобальным хранилищем всего нашего проекта — этакий склад, в который можно что-то положить из одной функции и забрать в другой. Так мы и поступим с кнопкой и панелью: мы создадим два овеерайда для каждого компонента.
Первый, для кнопки, на которую будем кликать. Он не будет делать ничего, кроме как по клику записывать в наш глобальный «склад» своё состояние: на меня кликнули или откликнули.
Второй, для панели, будет это значение забирать и в зависимости от него изменять свой масштаб. Вот и всё.
А вот что получилось в итоге:
Мы научили компоненты разговаривать друг с другом. Интересной особенностью использования объекта Data будет то, что в нем можно хранить не только простые переменные или значения, но и целые массивы данных. А дальше нам потребуется пример.
В файлике выше, вы найдёте заготовочку приложения, которое выдаёт шутки про Чака Норриса. Если вы запустите превью, то перед вами появится окно с кнопкой, нажатие на которую приведёт к появлению другой шутки (хотя их всего две).
Давайте же наконец начнём. Так вот, массивы. Открыв пример и перейдя в Code Mode, вы увидите нечто такое. В нашем «складе» appState уже лежат некоторые переменные, среди которых есть «quotes» — это массив цитат, в котором лежат всего две не самые смешные.
Даже если бы я был гениальным автором то всё равно, как вы понимаете, забивать массивы ручками не слишком благодарное дело: это ничем не будет отличаться от того же Data в Sketch. Можно, конечно использовать Spider чтобы «воровать» массивы данных, и при этом всё равно эта перспектива видится мне не слишком эффективной.
И вот здесь в лучах софитов появляется сильная сторона Framer X, то, чего пока нельзя сделать где-то ещё — работа с реальными данными через запросы к API (Application Program Interface).
Что это за зверь? Представьте себе, что из вашего любимого приложения полностью исчез визуальный интерфейс. Оно не будет работать? Будет, просто вы не увидите таких привычных вам контролов. Вместо них у вас будет терминал, в который вы будете писать команды. Именно так работали с приложениями раньше. Да и продолжают работать сейчас: бэк-энд разработчикам вообще не нужен GUI, чтобы заставить систему работать — главное, чтобы определённые функции с определёнными параметрами выдавали правильный результат.
Так вот, некоторые такие функции не спрятаны внутри сервиса, а «торчат» во внешний мир. И любой желающий может до них докричаться… если захочет.
А мы хотим, поэтому вместо того, чтобы хранить данные локально и набивать их руками, мы будем работать с API. Обычно, это происходит по средством URL, то есть того адреса, который вы вбиваете в строку хрома, чтобы перейти на ваш любимый сайт. Да, вы правильно поняли, если мы вобьём в адресную строку вот это вот:
То мы действительно обратимся к API и получим от него ответ. Таким образом, если мы отправим запрос по этому адресу из Framer X, то получим ответ, с которым сможем работать. Так давайте сделаем это!
Что тут происходит. Если вам интересно более глубоко погрузиться в этот стаф, то можете воспользоваться современным учебником по JS. А я продолжу по-босяцки. Напомню, куда нужно смотреть:
fetch(“https://api.chucknorris.io/jokes/random")
.then(response => response.json())
.then(APIdata => {
appState.quoteVariant = “rested”
appState.quote = APIdata.value
})Начнем с первой строчки. В ней присутствует уже знакомый нам URL, который ссылается куда-то в Чака Норриса. Но мы заметим, что обёрнут он в функцию fetch. Дело в том, что Framer X должен не только крикнуть в нужный URL, но ещё и получить ответ, то есть данные, которые нам нужны. Но мы не можем быть полностью уверены, что данные придут к нам мгновенно, и мы сможем с ними работать, а потому там есть продолжение.
.then(response => response.json())Оно как раз таки отвечает за действия, которые произойдут после того, как мы точно получим данные. В этом случае—после получения мы попытаемся преобразовать их в JSON формат. По сути JSON — это текст, с которым мы можем работать прямо в коде. Но тогда зачем там второй then?
.then(APIdata => {
appState.quoteVariant = “rested”
appState.quote = APIdata.value
})Дело в том, что преобразование данных в JSON тоже может быть длительным процессом. Так что прошлый then тоже вернёт «обещание» преобразовать данные, но с ними работать пока нельзя. И вот только после того, как преобразование прошло, мы выполним какой-то код. В частности изменим состояние нашей цитаты и запишем новую цитату в наше глобальное хранилище appState.
Сложно? Хорошо, что сложно! Трудности делают нас сильнее. Но продолжим. Данные мы получили, а что дальше? А все тоже самое, чтобы вы делали с простым массивом: считайте значения, проводите манипуляции, ищите, пересылайте… все что душенька пожелает.
В моем случае, я просто каждый раз по нажатию кнопки делаю запрос на API, и вывожу новую шутку, когда та получена.
Но простым выводом данных возможности API не заканчиваются: мы можем по разному формировать запрос, получая только необходимые данные, например, когда нам интересна погода именно в нашем городе. Мы можем отправлять свои данные на обработку и получать результат, например перобразуя записанную речь в текст. Мы не ограничены ничем, кроме своей фантазии.
Хотите узнать больше полезных API? Милости просим на rapidAPI.
Здесь собраны большие коллекции готовых к употреблению API, рассортированных по категориям, где вы сможете найти ресурся для своего нового проекта. Дерзайте и делайте ваши работы ещё более реалистичными.
Ничего не нашли в каталоге? Что ж, мы можем вообще создать свой API, используя сервис realdata.dev. Там всё довольно просто: копируете в поле свои данные в формате JSON (можно опять-же воспользоваться Spider'ом) и можете обращаться к ним из любого прототипа. У Framer, кстати уже есть урок про API.
В общем, дерзайте. Все карты у вас на руках.
Так, первая часть программы подошла к концу. Она касалась, как вы помните, реальных данных в ваших прототипах. И при этом, я напомню, что прототипирование — это процесс моделирования с целью итеративного улучшения —тестирования, проще говоря. Реальные данные есть, а где тестирование, Карл?
Давайте снова обратимся к нашему опыту. Обычно, подобные тесты носят качественный характер: мы создаём скрины с определённым флоу, приводим человека в «стерильные» условия, даём задание и смотрим как он его выполняет, попутно сопя у него над ухом. Согласитесь, подобные условия сложно назвать естественными. Но никак иначе тестировать не получалось, ибо нельзя было дать прототип человеку домой попользоваться. Или провести лонгетюдное исследование со сбором колличественных данных. Теперь это возможно, благодаря компонентному подходу Framer X.
Давайте для начала посмотрим на вторую часть проблемы с лонгитюдным исследованием и колличественными данными. Для этого можно использовать уже, возможно, знакомые вам инструменты Google Analytics или Hotjar. Но сперва…
В отличии от тех же мок-апов в InVision, прототип во Framer X является code-base проектом, который можно прям взять и развернуть в вебе. Как? Когда вы протестируете ваше взаимодействие на замкнутость, проверите настройки всех компонентов и будете готовы к первому раунду тестов, можно сделать следующее:
- Перейдите на стартовый экран вашего сервиса и экспортируйте проект для Web-preview («File → Export Web Preview» или «Opt + Cmd + E»).
- Затем заходим и логинимся на https://www.netlify.com/ (надеюсь аккаунт у вас уже есть).
- Перетаскиваем папку с экспортом в поле для drag’n’drop’a и ждём немного пока всё задеплоится.
4. Всё готово, но теперь вы можете дополнительно настроить URL вашего нового прототипа, а можете даже подключить Git, чтобы сразу видеть изменения непосредственно в Web.
Хух, получилось? Теперь ваш проект можно видеть прямо из веба, поздравляю! А теперь настало время навесить на него такие полюбившиеся нам инструменты. Тем более, что делается это проще простого. (Дальше я буду говорить про Hotjar).
5. Регистрируемся на https://www.hotjar.com/.
6. Добавляем новый сайт (используя URL из Netlify).
7. Копируем ID нашего нового проекта.
8. Во Framer X устанавливаем из магазина компонент Hotjar.
9. Перетаскиваем компонент на первый экран нашего прототипа и вставляем ID нашего сайта в параметры компонента.
10. Done… теперь нужно проростить изменения на наш псевдо-сервачок на Netlify. Для этого снова экспортируйте ваш прототип, как в пункте 1. Затем снова переходите на Netlify, только теперь нужно перейти в проект, вкладку «Deploys» и уже потом перетащить всё в область drag’n’drop.
Бэм! Теперь данные собираются, сессии записываются, мутки мутятся, а у вас появился ещё один инструмент принятия решений — количественные данные и записанные сесссии (доступные в Hotjar). Так что теперь можете смело делиться сслылкой после очной сессии тестирования и смотреть, будет-ли человек пользоваться вашим решением в реальных условиях, и как он будет это делать.
Кстати, всё это мы уже проделывали на нашем мит-апе и есть запись:
Надеюсь это было интересно. Если да, то хлопайте в ладоши (мне это очень приятно) и делитесь ссылочками.
Вдогоночку, напомню, что у меня есть канальчик в телеге, на котором я делюсь всякими интересностями, хотя и довольно редко. Только контент, никакой рекламы :)
Ещё раз, спасибо. желаю вам счастья-здоровья, корабль любви, чугунный мост достатка. До новых встреч.

