По любви · Android × Figma · 11.09.2026
Последний раздел приложения — таб «Профиль» и всё, что из него открывается: удаление аккаунта, настройки, почта, обращение в поддержку, FAQ, правила, редактирование анкеты и превью «Моя анкета». Десять экранов, собранных из данных нод: переменных, стилей, матриц заливок, скруглений со сглаживанием Figma и эффектов размытия. Каждый кадр снят на устройстве в честном масштабе ×3 (1170×2532) и сведён с рендером; кадры выше экрана — по частям с прокруткой. Главная находка партии — фоновое размытие в Figma смотрит только на то, что лежит под самим слоем, и ядро нормируется у его края: подложка «с запасом» делает кнопку удаления заметно светлее. Вторая — про меру: сплошная проверка чернил снова нашла пропавший текст там, где геометрия зелёная. Это продолжение артефактов по кадрам S01–S10, S11–S20, S21–S30, S31–S40 и S41–S50.
После первой сдачи владелец посмотрел эти же кадры и сказал: где-то не хватает теней, где-то они лишние, а тексты расходятся цветом. Это оказалось правдой — и показало дыру в самой мере: число, по которому мы закрываем кадр, не видит ни краски текста, ни его кегля, потому что текстовые блоки в нём замаскированы. Завели три сплошные проверки — «каждый текст ноды есть в раскладке», «цвет чернил блока: нода, рендер и снимок рядом» и радиальный профиль тени — и починили девять вещей. Они собраны ниже, во втором разборе.
Смотровая
Тяните шторку, чтобы совместить макет и приложение. «Карта» показывает, где остаётся расхождение по геометрии: синим закрыты системный статус-бар, полоска home, клавиатура и диалоги разрешений iOS — их рисует Android, они в сравнении не участвуют (спека 6.4).
Числа
Полное — доля пикселей, отличающихся сильнее ΔE 6 вне масок. Без текста — то же с исключёнными текстовыми блоками. ±1 px — пиксель считается расхождением, только если не совпал ни с одним пикселем рендера в окне ±1: сдвиг растра на долю пикселя не есть ошибка вёрстки. Геометрия — два последних вместе, то есть чистая форма, положение и материал; по ней и выносится вердикт. Шкала показывает геометрию относительно порога 0,3 %.
| Экран | Кадр | Состояние | Полное % | Без текста % | ±1 px % | Геометрия % | Шкала до порога 0,3 % |
|---|
Разбор
Каждая строка — расхождение из реестра ловушек спеки: что показала нода, что делало приложение и сколько это стоило в числах.
Кнопка удаления фотографии — пилюля 44×44 с BACKGROUND_BLUR радиуса 20 и
двумя заливками с наложением. Если размывать подложку «с запасом» вокруг узла, как делает
любой обычный гаусс, пилюля выходит светлее рендера на девять единиц из 255. Figma
сворачивает ядро по прямоугольнику самого слоя и нормирует его у края: пиксели
снаружи в свёртку не идут вовсе. На пяти пилюлях одного кадра ошибка падает вдвое —
rms 0,024 против 0,013 в долях яркости. Сигма при этом прежняя, радиус × 0,410.
Корзина, карандаш, карточки и обновление существуют в двух весах. Инстанс называется
одинаково — 24 / trash, — и отличить лёгкий от тяжёлого по имени нельзя: вес
лежит в имени компонента (type / weight=heavy), то есть на уровень
выше. По лёгкому ресурсу корзина в пилюле удаления давала 12 % расхождения на своём
прямоугольнике — линии тоньше на треть.
Затемнение ячейки фотосетки в ноде 122×128 при самой ячейке 116,67×128 — на 5,33 dp
шире и с прямыми углами; плашка «Проверяем» — 117 при той же ячейке. В рендере этого не
видно: ячейка режет содержимое clipsContent вместе со своим скруглением 16.
Нарисованные «как в ноде», они вылезали за ячейку полосой и квадратили углы.
Мастер панели 375 широкий, кадр 390: рендер пересчитывает положение детей по их constraints, и центральный блок уезжает вправо. Раньше сдвиг мерили по буквам заголовка и получали «около 7,33». Теперь нашёлся чистый измеритель — полоса заполнения анкеты: у неё нет глифов, только геометрия. Центр её массы на семи рендерах стоит ровно на +7,006 dp, а подгонка формы с шагом 1/10 dp даёт вилку 7,0…7,3. Арифметическая половина разницы ширин — 7,5 — втрое хуже по ошибке.
У поля обращения подпись и подсказка приходят свойствами компонента, а сам набранный
текст лежит отдельной нодой внутри блока text-box: у пустого поля она скрыта,
у заполненного — 326×140 при поле 366×108. Обрезчик режет блок снизу, поэтому первая
строка уходит под верхнюю кромку и в рендере срезана пополам. Фикстура брала только
подсказку — текста на снимке не было вовсе, а геометрия этого не видит: текстовые
блоки в ней замаскированы, число 0,074 % выглядело закрытым. Нашла сплошная проверка
чернил.
Вторая проверка
Всё это стояло при зелёной геометрии: метрика маскирует текстовые блоки, а мягкая тень в порог не попадает. Ниже — девять находок и меры, которыми их теперь ловят.
В карте генератора было 10 стилей из 14. Отсчёт «10 секунд до удаления аккаунта» набран TT Runs 500 30/32, такого id в карте не было — и число рисовалось Manrope 14/18, вчетверо мельче. Геометрия кадра при этом 0,004 %: цифра в ней замаскирована как текст. Карта достроена до всех четырнадцати стилей кита, незнакомый id теперь кричит, а у текста без общего стиля берётся ближайший токен той же гарнитуры и веса.
Генератор искал центральный блок панели по точному имени мастера, а в половине кадров он
называется с суффиксом — x / Panel Header / Middle / 1. Title. Промах по имени
— и «Настройки», «Часто спрашивают», «Правила сообщества» не рисовались вовсе. Ищется по
началу имени, а принадлежность текста блоку — по множеству id поддерева, а не по
составному id инстанса.
«Выйти» внизу таба профиля искалась перебором всех узлов с именем button, а
на кадрах со шторкой её собственная кнопка называется так же и лежит в дереве позже —
побеждала она. На четырёх кадрах «Выйти» исчезала. Узлы шторки исключаются по множеству id
её поддерева.
Значки вынуты чёрными и красятся на месте, а картинки — со своими красками:
pic-attention это терракотовый круг и светлый восклицательный знак. Общий обход
красил её краской первого вектора, и знак пропадал: в шторке оставался просто круг.
Тонируются только значки.
У неактивной кнопки шторки рамка содержимого стоит с прозрачностью 0,5, а подпись под ней — сплошной Dark Beige. Бралась краска самой ноды, и подпись выходила вдвое темнее рендера: 158,128,117 против 203,185,179. Теперь генератор считает произведение прозрачностей всех предков.
На четырёх кадрах превью своей анкеты в панели нет кнопки «назад», но есть правый текст. Экран карточки рисовал стрелку всегда и правый текст никогда: лишняя стрелка и пропавшее слово. И то и другое теперь читается из ноды.
У кружка 96 на шестнадцати кадрах висит DROP_SHADOW радиуса 32 при 30 %
— единственная тень во всём файле, кроме клавиатуры iOS. Мы её нарисовали — и стало хуже на
всех шестнадцати кадрах. Радиальный профиль объяснил почему: отношение рендера к снимку без
тени равно 1,000 уже с 80 dp от центра и нигде не опускается ниже единицы, то
есть экспорт эту тень не рисует. Кадр берётся как есть.
Высокие кадры снимаются частями: рендеру срезают верх, и панель в нём уже за краем экрана — а мы рисовали её на прежнем месте. Один кадр из-за этого вышел за порог.
Ячейка «Сообщества» несёт инстанс с пустым именем 24 — по имени не опознать,
берётся по id компонента. Той же сплошной проверкой нашлись подсказки полей ввода на
кадрах прошлых десятков: «Люблю шоколадное мороженое» и «Напиши, что думаешь» не
рисовались вовсе, при зелёной геометрии. И состояния кнопок: «Готово» на трёх кадрах
фильтров было неактивным вместо активного, кнопка записки — наоборот.
Собрано
Кроме состояний уже готовых экранов, в этой партии впервые собраны три больших экрана — из нод, а не с картинки.
Шестерня и карандаш по краям, аватар 128 с двумя дугами заполнения и процентом, переключатель видимости анкеты, карточка верификации с четырьмя чипами, карточка подписки, блок «Добавь почту», пять ячеек-ссылок и снек. Тот же экран служит подложкой удалению профиля (затемнение, шторка, системный диалог и отсчёт на терракоте), добавлению почты и обращению в поддержку — шторкам с полями ввода.
Экран правки анкеты — не набор блоков кита, а полсотни разных узлов в столбце: строки «заголовок — значение», карточки ответов, открывашки, чипы, сетка фотографий с кнопками удаления, пунктирные подсказки, шторки. Писать под каждый свой блок — переписать половину кита ради одного экрана, поэтому кадр собран списком примитивов в порядке обхода ноды: прямоугольник, значок, растр, текст. Порядок списка равен порядку отрисовки Figma, поэтому затемнение честно закрывает всё, что нарисовано до него.
Три справочных экрана устроены одинаково: панель и столбец блоков, стоящих абсолютно по своим рамкам. Они собраны общим экраном — списками прямоугольников, значков и текстов, у каждого своя заливка, обводка, скругление и стиль из ноды.
Четыре кадра превью оказались той же карточкой анкеты, что показывает лента: та же фотография 366×627 с градиентом, пейджером и кружком видео, те же чипы и открывашки — только панель «Моя анкета» вместо таббара и кнопка «Пожаловаться» вместо записки. Карточке хватило одного нового поля — плашки «Проверяем эту фотографию» с размытой подложкой.
Вопросы
Здесь не ошибки вёрстки, а места, где макет спорит сам с собой или с собственным рендером. Мы делаем как в рендере и передаём пару дизайнеру.
| Что | Где | Как сейчас |
|---|---|---|
| Два кадра названы «editing-profile» | 4333:22836 · 6848:13362 |
по содержимому это настройки: панель «Настройки» и «Готово», секции «Уведомления» и «Контент», у второго ещё и шторка «Отключить продление подписки?» |
| Затемнение ячейки фотосетки | Rectangle 7424 |
122×128 при ячейке 116,67×128 — на 5,33 dp шире неё и с прямыми углами; держится только на обрезке ячейкой |
| Плашка «Проверяем» | error-message |
117 в ширину при той же ячейке 116,67 — тот же случай |
| Центральный блок панели | progress-cell · 2822:15113 |
рендер сдвигает его на +7,0 dp, а не на половину разницы ширин мастера и кадра (7,5); у правых элементов сдвиг ровно 15 |
| Счётчик поля обращения | 5009:17480 |
показывает «4 / 200» при 246 набранных знаках; на соседнем кадре тот же счётчик — «0 / 1000» |
| Опечатка в карточке подписки | 6876:24956 |
«Узнай, кто поставл лайк твоей анкете» |
| Опечатка в отсчёте удаления | 4333:22086 |
«…секуд до удаления аккаунта» |
| Подсказка поля обращения | I6914:12656;3258:23908 |
в ноде «Опиши ситуацию», в строках приложения — «Проблема или предложение» |
Границы
Форма зелёная — это половина работы. Вот честный остаток.
| Что | Почему | Что нужно |
|---|---|---|
| Поведение всех десяти экранов | трасса запросов против карт Flutter не снята ни по одному экрану | файловый лог запросов в debug-сборке и инструмент разбора |
| Экраны в приложении | все собраны и снимаются раскладкой, но в навигацию не включены: таб профиля, настройки, FAQ, правила, редактирование и превью в бою пока прежние | заменить прежние экраны и переснять кадры |
| Зазор между абзацами | у FAQ и правил в стиле Figma стоит paragraphSpacing, которого Compose не
знает: блок из трёх абзацев выходит короче и центрируется в рамке ноды. Пробовали пустой
абзац нужной высоты и прижим к верху — оба хуже по полному числу |
своя раскладка абзацев; геометрия при этом 0,002…0,005 % |
| Тон внутри размытых пилюль | сигма подобрана по рендеру, остаток около трёх единиц из 255 — это «похоже», а не «совпадает» | точная формула ядра Figma; на метрику при пороге 0,3 % не влияет |
| Тень кружка видео | в макете она есть, в экспорте её нет — мы повторяем экспорт, а не макет | вопрос дизайнеру: тень нужна или её убрать из ноды |
| Сплошные меры по всему проекту | «текст ноды есть в раскладке» надёжно работает только там, где кадр целиком пишет генератор; у собранных руками экранов подписи ищутся в исходниках и совпадение неточное | прогонять меру чернил по блокам — она не зависит от того, где лежит строка |
Кадр «maintenance alert» 12915:41086 |
лежит на табе профиля, но раскладка у него своя — другая шапка, другие блоки | собрать отдельно вместе с остальными кадрами обновления |
| Низ четырёх высоких кадров прошлых десятков | у них не записаны части прокрутки — нижняя полоса не сверялась ни разу | добавить части и переснять: 1349:13058, 1601:18880,
2998:14491, 3342:8104 |