Попробовать онлайн О проекте
Foldscape Memories (внутри репозитория также называется Nature Memories · Duo) — интерактивный сайт, который разворачивает фотографии из путешествий в трёхмерные воспоминания; он построен на React, Three.js, GSAP и Vite. Представление устройства выросло из более ранней браузерной реплики складного iPhone Duo, сделанной автором (SkentSun / iPhone Duo Depth Lab), — полного макета с внутренним и внешним экранами, семью позами и двумя отделками, где всё анимировано, — а этот проект добавляет поверх него слой воспоминаний.
Главная страница открывается закрытым устройством и одной фотографией. Прокрутите — и снимки-кандидаты входят справа по цилиндрической траектории и растворяются через край внешнего экрана; нажмите Open memory, и устройство за пять секунд раскроется и опустит камеру, пока место с фотографии поднимается из экрана. Пока воспоминаний пять: Round Island Light, красный парусник во льдах Гренландии, прибрежный дом Kálfeyri в Исландии, Санторини и замок Осака. Перетаскивайте, чтобы облетать, прокручивайте, чтобы приближать, а Rewind складывает фотографию обратно по тому же таймлайну. Отдельная Wallpaper Studio в правом верхнем углу одевает внутренний и внешний экраны в загруженное изображение или видео и генерирует глубину в браузере.
Фотографии и GLB-модели всех пяти случаев поставляются вместе с репозиторием, так что для просмотра API-ключ не нужен; опциональная генерация глубины в браузере скачивает модель инференса по требованию. Сайт развёрнут на Vercel (выход сборки dist/client) под лицензией MIT, а официальная модель Apple и ассеты обоев объявлены отдельно в THIRD_PARTY.md и исключены из этой лицензии.
Ключевые моменты
- Главная страница — круговая фотогалерея: прокручивайте, перетаскивайте или используйте стрелки, и каждый снимок движется по цилиндрической траектории к краю устройства и растворяется во внешнем экране; обратная прокрутка повторяет тот же путь назад и может остановиться в любой точке.
- Open memory сначала переносит выбранный снимок на устройство и ждёт загрузки его сцены, затем пять секунд раскрывает устройство, опускает камеру и подстраивает масштаб, после чего начинается медленный автооблёт со скоростью 4°/с; перетаскивание вращает, прокрутка масштабирует, а Rewind прогоняет таймлайн назад до закрытой фотографии.
- Пять воспоминаний — Round Island Light, красный парусник во льдах Гренландии, прибрежный дом Kálfeyri в Исландии, Санторини и замок Осака — каждое состоит из фотографии и GLB-сцены, поставляемых вместе с репозиторием, так что для просмотра не нужен API-ключ.
- Wallpaper Studio (?view=wallpaper) заменяет обои внутреннего и внешнего экрана загруженным изображением или видео, вычисляет в браузере быструю карту глубины и уточняет её небольшой моделью для параллакса и глубины резкости, следующих за курсором; две отделки — Star White и Night Sky; звук по умолчанию выключен, а после включения это процедурный шум побережья и оригинальный эмбиент-аккорд; режим уменьшенного движения отключает движение сцены, автооблёт и инерцию.
Технический разбор
3D-ассеты · Пять GLB-сцен воспоминаний и складное устройство, переработанное из модели Apple
Каждое из пяти воспоминаний — фотография плюс GLB-сцена (lighthouse-memory-v2.glb весит около 25 МБ), хранящаяся в public/scenes; во время работы обложкой служит только верхняя половина снимка, а README отмечает, что для просмотра API-ключ Tripo не нужен — он требуется лишь при создании ассетов.
Складное устройство сделано из официального USDZ iPhone Duo от Apple: scripts/prepare-model.mjs управляет Playwright, загружает USDZ на dev-странице, называет подвижную и неподвижную половины folding-half / stationary-half, заменяет материалы внутреннего и внешнего экранов на сменные белые поверхности и экспортирует бинарный GLB через GLTFExporter (текстуры ограничены 512). Перекрашивать разрешено только металлическую рамку — экраны, стекло, объективы и детали шарнира неприкосновенны, — а THIRD_PARTY.md исключает ассеты Apple из лицензии MIT репозитория.
Путь фотографии · Один прогресс GSAP управляет галереей, физическим снимком и внешним экраном
Круговая галерея — это Circular Gallery от React Bits, перенесённая с OGL на Three.js: она сохраняет сетку с разбиением 100×50, синусоидальное колебание вершин в зависимости от скорости и сэмплирование изображения с закруглёнными углами, а затем расширяет дугу до цилиндрической траектории с глубиной и ориентацией, разделяя одну PerspectiveCamera с устройством. GSAP Observer берёт на себя колесо, указатель и касания вместе с порогом перетаскивания, а Timeline выстраивает путь как approach → receive-and-melt → settle; новый ввод прерывает текущую анимацию, а перетаскивание может проигрывать её в обратную сторону.
Очередь снимков, сетка физической фотографии и реальное изображение внешнего экрана движутся одним прогрессом с совпадающими текстурными координатами на краю экрана: внешняя сетка обрезается там, где входит в экран, а экран дорисовывает соответствующую часть изображения. Переходы обложки используют ветку Melt из Morph Slider (intensity 0.95 / scale 4.9 / aberration 0.35), где uTime управляется прогрессом пути, а не системными часами — именно это делает возможными перемотку и стоп-кадры.
Портал экрана · Видимость определяет только реально движущаяся крышка
Сцена остаётся построенной на полностью развёрнутой плоскости и никогда не пересобирается и не масштабируется покадрово; сколько видно, определяет угол между подвижным левым экраном и неподвижным правым — при открытии сначала освобождается пространство над правым экраном, а левая половина проявляется, когда крышка проходит вертикаль и приближается к плоскому положению. Остановите крышку — картинка замрёт; перемотка проходит тот же объём в обратную сторону. Временные срезы в местах пересечения крышки со сценой триангулируются по реальным пересечениям сетки с пространственным отсеиванием, кэшируются для неизменных плоскостей с переиспользуемыми GPU-буферами, заливаются бледным льдом или нейтральным камнем и скрываются в закрытой и открытой крайних точках; подход со стенсилом отвергли, потому что у поставленных сеток открытые границы. Отражение воды слева проявляется только вблизи плоского положения, чтобы не было наклонённого двойного силуэта.
Оптимизация запуска от 16.09.2026 перенесла эту геометрическую обрезку у шарнира в module worker: раньше каждая из пяти сцен требовала 1–1,6 с синхронной подготовки, теперь главный поток тратит лишь 8–29 мс на восстановление transferable-буферов; только что смонтированные сцены применяют текущее состояние сгиба до рендера, камеры отражения воды видят только природную сцену, а не телефон и галерею, а пресеты и ИИ-воркер Wallpaper Studio загружаются лишь при входе в этот вид.
Wallpaper Studio · Оценка глубины в браузере и оптика складывания
Загруженное изображение сначала получает быструю карту глубины, затем небольшая модель уточняет её (@huggingface/transformers работает в depth.worker.js; ИИ-воркер создаётся только тогда, когда вы действительно нажимаете «сгенерировать»); передний план и фон смещаются и размываются по разнице глубины, так что при движении курсора у картинки появляется настоящее пространство. Пять предустановленных обоев поставляются с заранее сгенерированными картами глубины 512×288, а видео-пресет использует карту своего постер-кадра. Слои внутреннего и внешнего экрана собираются во время работы из JSON-раскладок и 20 отдельных SVG-иконок в прозрачные GPU-текстуры, поэтому замена одной иконки никогда не означает перерисовку всего экрана.
Само складывание живёт в параметрах: коэффициенты радиуса размытия 3,5 и 1,8 для внутреннего и внешнего экрана, поэтому при закрытии крышки внешний экран размывается первым; шарнир полностью сложен на 96 %, а последние 4 % оставлены экрану, чтобы «сесть» в фокус; яркость приглушается по синусоиде в зависимости от позы, темнее всего около 90°; а боковой параллакс проецирует вершины экрана на «полностью развёрнутую виртуальную плоскость» перед сэмплированием, так что геометрия складывается, а обои скользят, будто по плоскому стеклу перед вами, никогда не искажаясь в трапецию.


