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

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

Единственный способ перейти на следующий уровень — прекратить прототипирование и начать разработку продукта. Проблема в том, что может потребоваться гораздо больше времени, усилий и людей, чтобы добраться до сути интерактивного прототипа. Вы не просто реализуете кнопки, но создаете основу для технической архитектуры, определяете базы данных, создаете интеграции и т. д. Чем больше вы внедряете, тем сложнее становится учиться и повторять (то есть выбрасывать работающий код). Большой риск в любом проекте заключается в том, что первоначальная реализация, основанная на ваших ранних предположениях, идет в неправильном направлении, и для осознания этого требуется слишком много времени, и вы застреваете на этом. Это проблема, особенно в аутсорсинговых средах разработки, где это может означать переговоры по контракту с фиксированной ценой, т. е. фиксированный объем и больше никаких итераций или обучения.

Функциональное прототипирование

Альтернативой началу разработки может быть создание функциональных прототипов, то есть реализация основной бизнес-логики в прототипе. Это может быть не обязательно сквозная функциональность, например, интеграция API может быть смоделирована со статическими или случайными ответами. Также объем может быть ограничен, но важно то, что все в прототипе работает так, как ожидается, и пользователь может реалистично взаимодействовать с ним самостоятельно. Это позволяет проводить распределенное количественное пользовательское тестирование, т. е. предоставлять пользователям доступ к прототипу самостоятельно и использовать аналитику для измерения успеха и вовлеченности. В зависимости от ситуации это может означать закрытую бета-версию с некоторыми ранними пользователями или службу удаленного пользовательского тестирования, такую ​​​​как www.usertesting.com, или даже запуск общедоступной альфа-версии MVP.

Однако это проблема разработки продукта, поскольку трудно перейти на уровень функционального прототипирования без значительного увеличения сложности. Добавление конкретных функций в каждом конкретном случае, пытаясь охватить каждый отдельный сценарий реального мира, быстро приводит к раздуванию и путанице продукта. В то же время многие проблемы легко решались с помощью нескольких строк пользовательского кода. Вот почему мы подумали, что создание сценариев в SketchMyApp будет лучшим решением. Мы уже представили систему событий, позволяющую обмениваться данными между различными частями прототипа. Но мы не хотели просто открывать внутренние API, а хотели посмотреть, насколько мы можем упростить и уменьшить комбинаторную сложность разработки. Сколько можно унести, не сломав.

Привет мир!

Первым шагом в разработке обычно является «приложение hello world», т. е. программа-минимум, которая запускается и что-то отображает. В нашем случае нужно

  1. Создайте группу Photoshop с несколькими слоями, представляющими кнопку
  2. Создайте событие для группы под названием «OnTap».
  3. Введите код 'debug("Hello, World"!)’

Когда вы нажмете кнопку, откроется журнал отладки с текстом.

Скрипты в SketchMyApp

Язык сценариев SketchMyApp во многом похож на Javascript, т. е. динамически исполняемый сценарий со свободной типизацией. На практике это означает, что при объявлении классов или переменных очень мало накладных расходов, вы можете просто присваивать значения переменным, и все изменения в коде автоматически применяются в режиме реального времени.

Пример: примеры сценариев

var1 = 2 // создаем переменную var1 и присваиваем ей номер 2
var2 = 3*var1 // создаем переменную var2 и присваиваем ей номер 6
var3 = «какой-то текст» // создаем строковую переменную< br /> var4 = { "a", "b", "c" } // создаем массив из 4 элементов
var5 = { number=var2, text=var3, array=var4 } // создаем таблицу < br /> if (var2 == 5) then
debug("var2 равно 5")
else
debug("var2 не равно 5") // условие ложно, так что получается display
end
for ind, значение в массиве var4 do
// ind получает значения 1,2,3 и значения «a», «b», «c»
end
для ключа, значение в таблице var5 do
// ключ получает значения number,text,array
end
while (var1 › 0) do
var1 = var1– 1 // цикл дважды
конец

То, как вы пишете код, — это создание событий (или, скорее, их обработчиков) для элементов Photoshop. Когда что-то происходит, например, пользователь касается элемента или запускается приложение, запускается ваш код для этого события. Весь код автоматически применяется в режиме реального времени в настольном приложении SketchMyApp Designer, т. е. не требуется никакой внешней среды разработки или компиляции приложения. Вы просто меняете код, и все обновляется автоматически.

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

Манипуляции с объектами

Одним из основных случаев использования сценариев будет манипулирование элементами Photoshop. Например, чтобы переместить группу, у вас есть функция

двигаться (х, у [, время, задержка])

где x и y — координаты перемещения относительно размера объекта, а время и задержка — необязательные длительность перемещения и задержка в секундах, т. е.

  • move(0,0) немедленно перемещается в исходное положение Photoshop
  • move(0.5,0,1) перемещается вправо на 50% ширины за одну секунду
  • move(0, 0,7, 0,4, 0,2) перемещается вверх на 70% высоты за 0,4 секунды после задержки в 0,2 секунды

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

непрозрачность(альфа[, время, задержка])
масштаб(масштаб[, время, задержка])
масштаб(x_масштаб, y_масштаб[, время, задержка])
фильтр(метод[, время , задерживать])

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

Событие: OnTap

x = randomFloat(-0.2, 0.2) // перемещается на +-20% по горизонтали
y = randomFloat(-1.5, 1.5) // перемещается на +-150% по вертикали
o = randomFloat(0.6, 1) // от 60 до 100% непрозрачности
move(x, y, 0.4)
opacity(o, 0.4)

Настойчивость и общение

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

setPreference(ключ, значение)
переменная = getPreference(ключ)

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

setGlobal(ключ, значение)
переменная = getGlobal(ключ)

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

Событие: OnTap

is_pressed = getPreference("isPressed")
if (is_pressed) then
move(0, 0, 0.2)
zoom(1, 0.2)
opacity(0.83, 0.2)< br /> else
move(0, -0.028, 0.2)
zoom(0.993, 0.2)
opacity(1, 0.2)
end
is_pressed = not is_pressed
setPreference("isPressed", is_pressed)

Подключение к Интернету

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

  1. Создайте SmartContent WebImage, который может отображать изображение с URL-адреса.
  2. Создайте событие для вызова Flickr API
  3. Создать событие для анализа ответа API Flickr на предмет URL-адреса изображения.
  4. Отправить URL как событие в WebImage

Для использования веб-ресурсов существуют методы http, которые принимают URL-адрес, событие обратного вызова, тело при необходимости и, возможно, заголовки.

httpGet(url, callback_event[, заголовки])
httpPut(url, callback_event[, body, заголовки])
httpPost(url, callback_event[, body, заголовки])

Flickr Public Feed API позволяет искать изображения по тегам и получать список результатов в формате JSON. Сначала нам нужно вызвать это и указать имя события обратного вызова, которое получит результаты.

Событие: OnTap

url = «https://api.flickr.com/services/feeds/photos_public.gne?format=json&nojsoncallback=1&tags=cat'
httpGet(url, imageSearchResult)

Событие обратного вызова получит код состояния http и ответ API в качестве параметров, и нам нужно

  1. Убедитесь, что код состояния равен 200 для успешного HTTP-запроса.
  2. Декодировать ответ JSON
  3. Убедитесь, что в ответе есть список результатов, и выберите один случайным образом.
  4. Отправить URL-адрес изображения в WebImage как событие

Вы можете общаться, создавая/отправляя события либо тому же объекту для передачи части данных, либо другому объекту для запуска некоторых действий.

sendEvent([object_id], event_name, параметры, задержка)

Событие: imageSearchResult

if (event.status == 200) then
result = jsonDecode(event.response) // ответ представляет собой декодированный текст JSON

if (result и result.items) then
item_count = arrayLength(result.items) // сколько результатов у нас есть
random_index = randomInt(1,item_count) // выбираем случайным образом
random_item = result.items[random_index] // получить элемент из таблицы
url = random_item.media.m // получить URL элемента

if (url) then
sendEvent("page_http-pic", "onseturl", url) // отправляем событие в webimage для установки URL
end
end
end

Выводы

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

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

И именно поэтому мы будем рады получить от вас обратную связь! Имеет ли это смысл? Это то, что вы могли бы использовать, или это просто глупая идея смешивать Photoshop и код? Хотели бы вы использовать его для создания более богатых прототипов или создания приложений? Чем это должно быть полезно? Добавьте комментарий или напишите продолжение или отправьте нам электронное письмо по адресу matias AT sketchmyapp DOT com, мы будем рады услышать ваше мнение!

SketchMyApp – это решение для быстрого прототипирования, которое превращает проекты Photoshop в интерактивные приложения. Артборды автоматически становятся страницами в режиме реального времени, и дизайнеру просто нужно добавить навигацию и анимацию. Для получения дополнительной информации посетите http://sketchmyapp.com.