
В данный момент я работаю над дизайн-системой крупного SDUI-проекта и в этой статье хочу поделиться своим опытом реализации хаптика в наших приложениях: разобрать проблемы, с которыми вы, возможно, столкнётесь, и прийти к консистентному решению на трёх платформах: iOS, Android и мобильном вебе.
В этой статье я пошагово разберу путь от хаоса («каждая платформа делает что-то своё») к единой системе хаптик-пресетов, которую дизайнер настраивает в Figma, а разработчик получает в JSON.
Но для начала давайте коротко проговорим, что такое хаптик.
Хаптик — это технология тактильной обратной связи, применяемая в мобильных устройствах, игровых контроллерах и носимой электронике, для усиления пользовательского опыта через ощущение прикосновения. Вместо того чтобы ограничиваться только визуальными или звуковыми сигналами, интерфейс «отвечает» пользователю физическим откликом — лёгкой вибрацией, импульсом или микродвижением.
Для современных приложений это уже давно стало нормой, а для пользователя — неотъемлемой частью привычного опыта. Но когда начинаешь копать, выясняется, что у платформ совершенно разные подходы к тактильной отдаче, а готового кроссплатформенного решения нет.
Где и зачем нужен хаптик
Прежде чем выбирать пресеты, стоит определить, в каких сценариях хаптик действительно работает. Я собрал фактуру с помощью Mobbin и сгруппировал кейсы по типу взаимодействия — от этой группировки потом удобно привязывать конкретные пресеты.

Тап / нажатие — кнопки, ячейки, баннеры. Хаптик здесь подтверждает действие и создаёт ощущение «физической» кнопки. Пользователь не гадает, нажал он или нет — он это чувствует. Например, отправка сообщения в Telegram или лайк в Instagram.
Свайпы — жесты по карточкам, шторкам, табам. Тактильный сигнал обозначает достижение порога: «ещё немного — и карточка улетит». Помогает управлять жестом, не глядя на экран. Классический пример — свайп в Tinder.
Драг / перетаскивание — сортировка списков, перемещение элементов. Хаптик создаёт иллюзию веса и сопротивления, подтверждает фиксацию объекта на новом месте. Например, перетаскивание виджетов на рабочем столе iOS.
Ошибки и ограничения — попытка ввести недопустимое значение, невалидная форма. Мгновенная обратная связь без чтения текста — пользователь понимает, что что-то пошло не так, ещё до того, как увидел сообщение. Паттерн универсален и снижает когнитивную нагрузку.
Успех / подтверждение — завершение оплаты, отправка формы, достижение в игре. Эмоциональное подкрепление и чёткая точка завершения действия.
Скролл и пределы контента — bounce-эффект при достижении конца списка. Пользователь чувствует границу, даже не глядя на экран.
Лонгтапы — вызов контекстного меню, раскрытие дополнительных действий. Хаптик подтверждает, что долгое нажатие зарегистрировано.
Игры и геймификация — более глубокое погружение, замена визуального фидбека тактильным, усиление эмоций при достижениях.
Анимации и переходы — делают анимацию «осязаемой», подсвечивают ключевые точки. Часто встречается в анимациях онбординга.
Что предлагают платформы
Это ключевой момент, от которого зависит вся дальнейшая архитектура.
У Google нет единой философии использования тактильной отдачи. Есть набор констант (KEYBOARD_TAP, LONG_PRESS, CLOCK_TICK и т.д.), но за ними не стоит смысловая модель — это скорее перечисление аппаратных возможностей.
У Apple — другая история. Хаптики разделены на три семантических типа, и различаются они не силой удара, а смыслом события, которое обозначают:
- Impact — физическое взаимодействие с элементом (тап, свайп, фиксация)
- Selection — переход между дискретными значениями (пикер, сегменты)
- Notification — результат события, не требующий касания (успех, ошибка, предупреждение)
Именно эту семантику мы взяли за основу. Далее я опираюсь на нейминг Apple — это будет важно при мэтчинге между платформами.
Impact — физическое взаимодействие с элементом
Хаптик типа Impact используется в моменты физического взаимодействия элементов интерфейса — например, когда пользователь тапает на эллемент интерфейса, карточка фиксируется на позиции или жест достигает порога действия. Такой отклик имитирует ощущение контакта и делает поведение интерфейса более материальным.
Для этого используются уже готовые преднастроенные паттерны:
Light — Кратковременный низкоинтенсивный импульс.

Medium — Кратковременный импульс средней интенсивности.

Heavy — Кратковременный импульс высокой интенсивности.

Soft — Импульс с пониженной амплитудой и сглаженным фронтом.

Rigid — Импульс с высокой амплитудой и резким фронтом.

Selection — изменение текущего значения
Хаптик типа Selection используется при переходе между дискретными значениями — например, при прокрутке пикера или переключении сегментов. Короткий тактильный «тик» сопровождает каждую смену выбранного варианта и помогает пользователю ощущать шаги интерфейса.
Apple предлагает один преднастроенный паттерн:
SelectionChanged — одиночный короткий импульс, предназначенный для подтверждения изменения значения.

Notification — результат события
Хаптик типа Notification применяется для обозначения результата события — успеха, предупреждения или ошибки. Такой отклик усиливает статус сообщения и помогает пользователю быстрее распознать характер происходящего. Не требует физического взаимодействия пользователя с интерфейсом.
Apple предлагает три преднастроенных паттерна:
Success — Последовательность из 2-х импульсов, сигнализирующая об успешном завершении операции.

Warning — Последовательность из 2-х импульсов средней интенсивности, обозначающая предупреждение.

Error — Последовательность из 4-х импульсов с акцентированной интенсивностью, обозначающая ошибку.

Кастомный хаптик
Для нашего приложения нам также понадобился кастомный хаптик с гибкой настройкой — например, для сложных Lottie-анимаций.
Важная оговорка: тактильная отдача воспроизводится вибромотором устройства. У Apple вибромоторы стандартизированы, а на Android-устройствах можно встретить совершенно разные моторы, часть которых может не поддерживать параметр интенсивности. При тестировании лучше использовать устройство, в котором вы уверены — мы тестировали на OnePlus 15, и результаты с iPhone совпали практически идеально.
Для упрощения JSON-схемы (что важно для SDUI-приложения) мы сократили параметры вибромотора до трёх основных:
- Delay — задержка перед началом вибрации в миллисекундах (отсчитывается от нуля)
- Duration — длительность вибрации в миллисекундах
- Intensity — интенсивность вибрации от 0 до 1
Нейминг выбран не случайно — мы ориентировались на для мобильного веба.
Мэтчим платформы
Изначально я планировал сопоставить пресеты Apple напрямую с пресетами Google:
Однако при тестировании стало понятно, что прямой маппинг не работает: Google-константы подбирались по формальному сходству названий, но тактильные ощущения на устройстве не совпадали — интенсивность, длительность и «характер» вибрации отличались настолько, что пользователь получал бы принципиально разный опыт на iOS и Android. Поэтому мы решили переписать пресеты для Android на основе наших кастомных параметров.
Apple не раскрывает точные настройки своих пресетов, но дает понятную графику, которую несложно перевести в численные значения относительно наших параметров (Delay, Duration, Intensity).
В итоге получились следующие значения:
Impact-пресеты
Selection
Notification-пресеты (составные)
Success (2 импульса):
Warning (2 импульса):
Error (4 импульса):
Мэтчим код с компонентом в Figma
Мне кажется важным, чтобы структура компонентов в коде и Figma была максимально синхронизирована. Это особенно полезно, если вы хотите оптимизировать взаимодействие «дизайнер — разработчик», например, с помощью плагинов, которые умеют читать компоненты и конвертировать их в JSON-схему.
У нас в коде структура Haptic представляет собой OneOf-параметр, состоящий из набора пресетов и кастомного хаптика. В Figma я реализовал это через swap instance-параметр, где дизайнер выбирает тип хаптика.

Если выбран пресет — всё просто. Если кастом — появляются дополнительные параметры:
Patterns: Array { Pattern }
Массив хаптиков для создания более сложной тактильной отдачи. В Figma реализован через варианты и выглядит так:

И три параметра для каждого паттерна из массива, которые я реализовал через скрытые параметры Text:
- Delay: Integer — задержка перед началом вибрации
- Duration: Integer — длительность вибрации
- Intensity: Number — интенсивность от 0 до 1
В Figma выглядит так:

Итого
Мы получили единую систему хаптик-пресетов, которая:
- Семантична — основана на смысловой модели Apple (Impact / Selection / Notification), а не на аппаратных константах
- Кроссплатформенна — одинаково ощущается на iOS и Android благодаря кастомным параметрам вместо прямого маппинга платформенных API
- Расширяема — кастомный хаптик через Delay / Duration / Intensity покрывает нестандартные сценарии (Lottie-анимации, игровые механики)
- Синхронизирована с дизайном — компонент в Figma зеркалит структуру кода и конвертируется в JSON
Из ограничений: поддержка хаптика в мобильных браузерах пока значительно уступает нативным платформам. Для веба мы используем упрощенный набор паттернов из тех же параметров, но без Intensity — это компромисс, а не полноценный паритет с нативными платформами, но общая структура пресетов позволяет хотя бы сохранить консистентный нейминг и логику.
Приятной тактильной отдачи!
was originally published in on Medium, where people are continuing the conversation by highlighting and responding to this story.