← Открыть примерEclipse Library ↗

Интерактивный портрет Erida Vice: раскрываем лицо под маской с помощью Codex

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

Дата проверки: 7 октября 2026. Версия материала: 1.1. Тип: практический guide. Редакционный статус: verified — проверен описанный прототип и обозначены ограничения. Автор реализации и редакционного материала: Eclipse Forge.

Открыть интерактивный пример · Красиво оформленное руководство · Скачать полный промпт · Скачать код примера ZIP — без изображений.

Изображения Эриды не входят в материалы для скачивания. ZIP содержит только код, руководство, универсальный промпт и README. Для повторения добавьте собственную совмещённую пару портретов. Сам интерактивный пример показывает Эриду.

Исходная идея — пользовательский материал «Create an Interactive Mask Reveal with Astra». URL публикации и автор в переданном материале отсутствовали; происхождение не приписываем OpenAI. Изображения подготовлены пользователем вне этого рабочего сеанса. Промпты изображений ниже — шаблоны для повторения, а не восстановленный журнал той генерации. Наш вариант использует два отдельных изображения, доступную кнопку и ограничение области раскрытия.

Модуль 1. Что мы собираем

Урок 1. Результат и границы

На первом экране сайта находится портрет персонажа в маске. Движение мыши стирает маску мягкой кистью: под ней виден тот же персонаж без маски. След исчезает на 95% приблизительно за 1,1 секунды после последнего прохода, а через 1,8 секунды очищается полностью. Кнопка «Показать лицо» открывает лицо до следующего нажатия; «Сбросить» и Escape возвращают маску.

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

Это браузерная реализация на HTML, CSS и JavaScript / Canvas 2D. Во время движения курсора AI-вызовы не выполняются. Название Astra из исходного материала не является зависимостью реализации. Платные API, внешние CDN, библиотеки анимаций и WebGL для этого примера не потребовались.

Модуль 2. Подготовка изображений

Урок 2. Сначала одно утверждённое лицо

Выберите портрет, который будет источником identity. Для нового персонажа удобны почти анфас, ровная голова, камера на уровне глаз, мягкий нейтральный свет и спокойный фон. Хорошо видны глаза, нос, подбородок и контур лица. Для Эриды используем уже выбранное лицо: новая генерация не должна заменять её геометрию.

Пример промпта для создания базового портрета, если утверждённого изображения ещё нет:

Создай оригинальный фотореалистичный эталонный портрет моего взрослого
вымышленного персонажа. Его имя, возраст 18+ и особенности внешности:
[ВСТАВЬТЕ ОПИСАНИЕ СВОЕГО ПЕРСОНАЖА].

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

Лицо должно быть оригинальным, без копирования конкретного человека.
Не добавляй текст, логотипы, декоративные рамки, дополнительные руки
или предметы. Если приложен утверждённый identity reference,
сохрани его лицо вместо создания нового.

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

Урок 3. Второй кадр — редактирование первого

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

Полный промпт для второго изображения:

Отредактируй приложенный утверждённый портрет моего персонажа.
Добавь оригинальную матовую чёрную маску на нижнюю часть лица:
она закрывает нос, рот и подбородок, оставляя глаза открытыми.
Материал выглядит физически правдоподобно. Дизайн маски:
[ВСТАВЬТЕ СВОЙ ДИЗАЙН, СООТВЕТСТВУЮЩИЙ ПЕРСОНАЖУ].

Сохрани лицо под маской и всё вне области маски: положение головы,
глаза, брови, волосы, тело, одежду, фон, освещение, перспективу,
масштаб лица и кадрирование. Не создавай новый портрет и не меняй
выражение. Маска — единственное смысловое изменение изображения.

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

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

В наших портретах положение головы совпадает, но байты и отдельные детали вне маски различаются. В нормализованном сравнении 280 × 350 средняя абсолютная RGB-разница вне исключённой области маски — примерно 4,1 из 255. Это диагностическое измерение, не доказательство идеальной identity. Поэтому раскрытие ограничено эллипсом лица, а волосы и фон остаются верхним изображением.

Урок 4. Большие оригиналы и лёгкий веб-набор

Предоставленная обычная пара имеет размер 1122 × 1402, около 2,1 МиБ на изображение. Увеличенная пара — 4488 × 5608: 115,1 и 113,9 МиБ. Такие оригиналы пригодны как рабочие исходники, но не входят в загрузку страницы и публичный ZIP.

Для сайта подготовлены WebP-производные из увеличенных портретов. Это изменение размера и кодирования; лицо и композиция дополнительно не редактировались. Метаданные оригиналов не переносятся.

Вариант Размер одного изображения Лицо Маска Пара
Компьютер 1440 × 1799 275,0 КиБ 277,1 КиБ 552,1 КиБ
Телефон 720 × 900 64,4 КиБ 66,4 КиБ 130,7 КиБ

Это размеры файлов. Декодированная память больше: одна RGBA-копия 1440 × 1799 занимает около 9,9 МиБ, две — около 19,8 МиБ. К этому добавляются рабочие Canvas и внутренние буферы браузера. Сжатие файла не устраняет расходы на декодирование.

Начальная загрузка использует мобильную пару при ширине viewport до 600 px. При последующем изменении размера остаётся уже загруженная пара; это не механизм постоянного подкачивания новых версий. PNG-оригиналы сохраняем локально. Размеры и SHA-256 собственных веб-файлов полезно записать в локальный manifest; набор портретов Эриды для скачивания не предоставляется.

Модуль 3. Как работает раскрытие

Урок 5. Слои и область лица

Нижний слой — обычное изображение без маски. Передний Canvas показывает портрет в маске. Скрытый Canvas хранит белые мягкие отпечатки кисти. Передний слой вырезает накопленную форму через destination-out, и пользователь видит нижнее изображение.

Объединять портреты в один перевёрнутый спрайт необязательно. Для двух отдельных файлов проще проверить совпадение кадра и избежать ошибок обрезки. Все слои должны использовать одно преобразование координат.

Параметры текущего примера относительно полного изображения:

const face = { x: 0.502, y: 0.444, rx: 0.205, ry: 0.16 };
const brushRadius = canvasWidth * 0.062;

x/y — центр эллипса; rx/ry — горизонтальный и вертикальный радиусы. Меняйте их по фактическому портрету. Кисть может двигаться по всей области изображения, но прозрачность переднего слоя ограничена лицом. Кнопка раскрывает весь эллипс, сохраняя верхний фон и волосы.

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

Урок 6. Непрерывный след и восстановление

Между последней и текущей точкой кисть делает дополнительные отпечатки. Шаг ограничен четвертью радиуса: быстрый проход не должен оставлять разрывы. Если getCoalescedEvents() доступен, обрабатываются накопленные точки; иначе используется обычное событие.

Затухание зависит от прошедшего времени, а не от количества кадров:

const heal95Ms = 1100;
const tau = heal95Ms / Math.log(20);
const eraseAlpha = 1 - Math.exp(-dt / tau);

dt и tau здесь в миллисекундах. Через 1100 мс остаётся около 5% следа. Если поставить tau = 1100, через это время останется около 37%; это другое поведение. Через 1800 мс без нового отпечатка наш цикл очищает остаток и прекращает работу.

Свечение необязательно. У нас отдельный Canvas окрашивает след через source-in, затем вычитает эллипс лица. Оставшееся свечение выводится за пределами лица через screen и небольшой blur. В спокойном режиме оно скрыто. Если устройство работает медленно, первым кандидатом на отключение будет именно этот декоративный слой.

Модуль 4. Мышь, телефон и клавиатура

Урок 7. Управление без помех странице

На компьютере кисть работает от движения мыши по портрету. Кнопки, ссылки и навигация находятся вне области рисования. Canvas не перехватывает указатель: pointer-events: none.

На телефоне pointerdown запоминает активный pointerId; движение рисует только для него. pointerup, pointercancel и потеря захвата завершают рисование. CSS touch-action: pan-y pinch-zoom оставляет браузеру вертикальную прокрутку и pinch zoom. Поэтому свободный вертикальный мазок может превратиться в прокрутку — это осознанный компромисс. Полное раскрытие доступно кнопкой.

Не включайте touch-action: none на всём первом экране: это может заблокировать привычную прокрутку и масштабирование. Увод пальца не должен оставлять рисование активным.

Урок 8. Доступная альтернатива

Кнопка — обычный <button> с aria-pressed; Enter и Space переключают состояние. Видимый фокус помогает понять текущий элемент. У портрета есть описание, а у динамического статуса — редкие сообщения о загрузке, ошибке и открытии лица. Движения кисти не озвучиваются покадрово.

Стрелки на сфокусированном портрете двигают виртуальную кисть; Escape сбрасывает результат. Портрет обозначен группой, а не role="slider": стандартный slider выбирает одно значение из диапазона, тогда как здесь две координаты и декоративное рисование.

Настройка prefers-reduced-motion отслеживается через matchMedia и реагирует на изменение без перезагрузки. В спокойном режиме остаётся кнопка, кисть и свечение выключаются. Короткое изменение прозрачности допускается; крупные движения не добавляются.

Модуль 5. Запуск готового примера

Урок 9. Быстрый запуск

  1. Скачайте erida-reveal.zip.
  2. Распакуйте код и прочитайте README.md. Изображений в архиве нет.
  3. Подготовьте свои портреты по модулю 2. Создайте папку assets рядом с index.html и добавьте face.webp, masked.webp, face-small.webp, masked-small.webp. Если меньшая пара ещё не готова, временно скопируйте свои основные файлы под именами с -small.
  4. Проверьте размеры пары и настройте область лица в коде под свой кадр. Откройте index.html: после загрузки своих изображений кнопки становятся доступны.
  5. Проведите по маске, дождитесь восстановления и попробуйте кнопку.
  6. Откройте guide.html для локальной копии руководства и prompt.txt для полного поручения Codex.

Структура пакета:

erida-reveal/
  index.html
  guide.html
  prompt.txt
  README.md

Добавьте самостоятельно (этих файлов нет в ZIP):

  assets/
    face.webp
    masked.webp
    face-small.webp
    masked-small.webp

Если браузер ограничивает локальные файлы, используйте localhost. Следующие команды — Windows PowerShell; требуется уже установленный Python 3. Сначала python --version должен показать версию. Если команда отсутствует, остановитесь: установка Python не является частью примера.

python --version
$eridaDemoFolder = Join-Path $env:USERPROFILE 'Downloads\erida-reveal'
Set-Location -LiteralPath $eridaDemoFolder
python -m http.server 4191 --bind 127.0.0.1

Откройте http://127.0.0.1:4191/index.html. Для остановки нажмите Ctrl+C в той консоли, где запущен сервер. Если порт занят, выберите свободный порт и поменяйте адрес. Сервер запускается только на loopback.

Урок 10. Перенос в свой проект

Передайте Codex текущий репозиторий и два изображения. Сначала пусть он прочитает действующие инструкции, определит framework и место компонента. Для HTML-примера сборка не нужна; в React/Vue логика должна жить в lifecycle компонента с очисткой обработчиков и наблюдателей при уничтожении.

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

Код готового примера использует системные шрифты. Для включения в продукт используйте его действующую дизайн-систему. Стиль Erida Vice не должен автоматически менять всю библиотеку или рабочий интерфейс Ultron.

Модуль 6. Полный промпт для Codex

Ниже адаптированное поручение для повторения нашего результата. Оно описывает результат и проверки; одинаковый текст не гарантирует побайтово одинаковую реализацию. Скачать отдельно.

Задача: интерактивный портрет моего персонажа с раскрытием лица под маской.

Сначала прочитай действующие AGENTS.md и инструкции текущего проекта.
Подтверди checkout, текущую ветку, Git state и существующий frontend.
Сохрани чужие изменения. Новую ветку, commit, push и deploy выполняй
только по отдельному прямому поручению пользователя.

Результат: отдельный hero-блок с портретом моего взрослого вымышленного
персонажа. Имя и внешность задаются моими материалами. Посетитель проводит по маске мягкой
кистью, открывая то же лицо без маски. Затем маска восстанавливается.
Кнопка полностью открывает лицо и возвращает маску.

Материалы:
- face.webp — утверждённый портрет без маски;
- masked.webp — его отредактированный вариант с маской;
- face-small.webp / masked-small.webp — меньшая совмещённая пара.
Используй предоставленное лицо. Новую identity не генерируй.
Проверь одинаковые размеры, положение головы, глаза, crop и фон.
Если совпадение недостаточно, сообщи конкретное расхождение.
Исходники в сотни мегабайт сохрани без изменения локально;
для сайта создай лёгкие WebP-производные и измерь их размер.
Не публикуй огромные оригиналы автоматически.
Используй только мои собственные или лицензированные изображения.
Не загружай и не копируй портреты Эриды из демонстрации Eclipse Library.
Скачиваемый код примера намеренно не содержит изображений персонажа.

Используй существующий framework и дизайн-систему. Для отдельного
примера достаточно HTML/CSS/JavaScript и Canvas 2D. Не добавляй
библиотеки, сервисы и AI-вызовы без технической необходимости.

Механика:
1. Нижний слой — портрет без маски; передний Canvas — портрет в маске.
2. Отдельный offscreen Canvas хранит мягкие белые отпечатки кисти.
3. Интерполируй путь с шагом не больше четверти радиуса кисти.
4. Передний Canvas каждый кадр вырезает trail через destination-out.
5. Ограничь раскрытие областью лица. Волосы и фон должны оставаться
   стабильными. Все слои используют общие координаты и размеры.
6. Настрой исчезновение 95% следа за 1100 мс:
   tau = 1100 / Math.log(20);
   eraseAlpha = 1 - Math.exp(-dt / tau);
   dt и tau в миллисекундах. Через 1800 мс без движения очищай остаток
   и останавливай цикл. Скорость не должна зависеть от частоты кадров.
7. Свечение — необязательный отдельный слой: trail окрашивается через
   source-in, область лица вычитается destination-out. Умеренный blur
   и screen. Предусмотри выключение декоративного слоя.

Пример стартовых параметров; проверь их по моему портрету:
face = { x: 0.502, y: 0.444, rx: 0.205, ry: 0.16 };
brushRadius = canvasWidth * 0.062;
accent = '#b96f85'.
Проценты относятся к полному изображению. Для нового кадра проверь их
заново. Установи общий aspect ratio из фактического исходника.

Управление:
- мышь рисует при движении по портрету;
- getCoalescedEvents применять только при наличии API, иначе [event];
- кнопки, ссылки, поля ввода и навигация не запускают кисть;
- touch: активный pointerId от pointerdown, завершение при pointerup,
  pointercancel и lostpointercapture; сохраняй вертикальную прокрутку
  и pinch zoom. Для этого примера допустим pan-y pinch-zoom и
  горизонтальное рисование, а полное раскрытие доступно кнопкой;
- обычный button «Показать лицо / Вернуть маску» с aria-pressed;
- отдельный «Сбросить» и Escape восстанавливают маску;
- необязательная виртуальная кисть стрелками на сфокусированном
  портрете с ограничением координат. Не обозначай 2D-кисть slider;
- видимый фокус, понятное описание портрета, редкие объявления
  состояния. Не отправляй screen reader сообщения каждый кадр.

Состояния:
Статичный портрет сразу доступен. До загрузки и проверки обеих картинок
интерактивные кнопки disabled. Предусмотри loading, ошибку, тайм-аут
и реальную повторную загрузку. Устаревший ответ не должен менять новую
попытку. Если JavaScript/Canvas недоступен, оставь изображение и ссылку
на портрет без маски. Не сообщай успех до реальной готовности.

Доступность и ресурсы:
Учитывай prefers-reduced-motion через matchMedia и change. В этом режиме
используй статичное переключение кнопкой, без кисти и свечения.
Короткая прозрачность допустима. Ограничь devicePixelRatio до 2 и
ширину backing Canvas до 1440. Используй ResizeObserver и
IntersectionObserver. Один rAF-цикл работает только во время следа.
Останавливай его при скрытии страницы, потере фокуса и уходе портрета
за экран. Уничтожение компонента отменяет rAF, слушатели, наблюдатели
и загрузочные ответы. При возврате из history/BFCache восстанови
работоспособность. Не добавляй телеметрию и внешние сетевые запросы.

Для повторяемой визуальной проверки добавь t=<секунды> с фиксированным
состоянием следа без rAF и reduce=1 для спокойного режима.
Публичная основная ссылка не должна принудительно включать QA-режим.

Проверка:
Проверь реальный путь в браузере, а не только сборку. Мышь, быстрый
мазок, восстановление, idle, кнопка, Enter/Space/стрелки/Escape,
фокус, desktop/mobile, DPR 2, resize, touch cancel и прокрутка,
reduced-motion при загрузке и переключении, ошибка картинки и retry,
статичный fallback без JavaScript/Canvas, остановка вне экрана.
Осмотри screenshots normal/reduced и desktop/mobile. Проверь консоль,
внешние запросы, контраст и CSP. Для inline-кода примера предпочти
точные CSP-хеши. Укажи браузер, реально пройденные сценарии и ограничения.
Не выдавай эмуляцию телефона за проверку на физическом устройстве.

Перед публикацией подготовь подробное руководство с этим полным
промптом, описанием подготовки изображений, параметрами, ошибками,
источниками, результатами проверки и ZIP кода примера.
Не включай изображения персонажа в скачиваемый ZIP без отдельного
разрешения владельца. Добавь README с инструкцией подставить свои файлы.
Сначала практическая реализация и проверка, затем руководство.
Встраивание в продукт, commit/push и production — отдельные статусы.

Модуль 7. Проверка результата

Урок 11. Что проверять до публикации

В этом примере выполнены 21/21 браузерных сценариев в изолированном Chromium 151.0.7922.34: мышь и фактические пиксели Canvas, непрерывность следа, затухание и idle, кнопки, клавиатура, reduced-motion и его переключение, freeze-harness, resize, мобильные ассеты, имитация touch-прокрутки через DevTools Protocol, offscreen, fallback coalesced events, отказ изображения и retry, отсутствие Canvas/JavaScript, DPR 2 и отсутствие сторонних запросов. Снимки desktop/mobile и normal/reduced-motion визуально просмотрены.

Это проверка в Chromium и эмуляция мобильных взаимодействий. Safari, Firefox, реальный телефон, отдельный экранный диктор, полный GPU frame timing и производительность на слабых устройствах не подтверждены. Реальное переключение окна ОС и скрытие вкладки не выдаём за пройденные сценарии на основании наличия обработчиков. Производственная доступность проверяется после публикации отдельно.

Для воспроизводимого снимка доступны index.html?t=0.2 (фиксированное состояние следа через 0,2 с) и index.html?t=0.2&reduce=1 (спокойный вариант). Эти параметры нужны для проверки, а не для основной публичной ссылки.

Урок 12. Типичные ошибки

Симптом Вероятная причина Исправление
При раскрытии прыгают глаза Разные лица или crop Исправить пару портретов
Меняются волосы и фон Различия ассетов раскрываются за пределами лица Ограничить область и пересоздать маску из основы
Быстрый курсор оставляет точки Нет интерполяции Добавить промежуточные отпечатки
На телефоне нельзя прокручивать Слишком широкое подавление жестов Сохранить pan-y / pinch zoom и кнопку
Эффект не восстанавливается за секунду Перепутаны постоянная времени и время исчезновения Рассчитать tau из желаемых 95%
CPU работает в покое rAF назначается постоянно Остановить цикл после восстановления
Новый портрет не совпадает после resize Разные преобразования слоёв Общий размер и координаты
Кнопка обещает успех при ошибке загрузки Состояние не связано с готовностью изображений Отключить управление до подтверждённой загрузки

Модуль 8. Источники, условия и история

Первичные технические источники, проверенные при подготовке материала:

Эрида — персонаж Eclipse Forge; её изображения используются для просмотра интерактивной демонстрации. Они исключены из скачиваемого ZIP и не предоставляются как исходники для повторения гайда. Для своего персонажа используйте собственные или лицензированные изображения; промпты описывают универсальный механизм, а не внешность Эриды. Редакционный материал принадлежит Eclipse Forge; внешние источники сохраняют собственные условия.

История: 2026-10-07, v1.0 — создан практический пример на двух портретах Эриды, подготовлены WebP, проведены браузерные проверки, добавлены руководство, промпты и ZIP. Связанные социальные публикации: не создавались. Проверенная реализация не является обещанием роста конверсии или монетизации.

2026-10-07, v1.1 — по просьбе владельца удалены изображения Эриды из скачиваемого архива и прямая ссылка на manifest её ассетов; промпты сделаны универсальными. ZIP содержит только код и документацию. Для запуска требуется добавить свои изображения. Интерактивная демонстрация сохранена.

Следующий шаг: пользовательская оценка ощущения раскрытия, затем проверка на реальном телефоне и в Safari/Firefox. Изменение самого лица и других характеристик персонажа требует отдельного решения.