Два убранства — золото и серебро
Тема распространяется на все представления через Environment и переключается мгновенно. Для каждого убранства отдельно проработаны даже стиль циферблата, стрелок и цифр.
Золото — охотничьи часы
Тёмно-лазурная эмаль × позолоченные римские цифры (запись IIII) · центральный герб с полумесяцем и восьмиконечной звездой
Гравированный корпус из старого золота (состаренной латуни). На отметке 6 часов — маленькое окошко ближайшего урочного часа
#8F7028
Лазурь #101838
Золочение #D9B45C
Лунное золото #F2DC96
tint #A67C2E
Серебро — железнодорожные часы
Белый циферблат · жирные арабские цифры · стрелки-палочки
Секундная стрелка, по обычаю железнодорожных часов, окрашена в красный
#9CA3AE
Белый фарфор #FAFAF7
Чёрное железо #1A1C22
Красный #B02E2E
tint #44546A
Установить время стрелками
DatePicker здесь не используется. Вместо жеста заводки головки время звучания определяется перетаскиванием самих стрелок циферблата. Циферблат ниже можно перетаскивать по-настоящему.
До полудня7:30
- Угол → время: преобразование — координаты перетаскивания переводятся в угол через atan2, минутная стрелка квантуется шагом 6°, часовая — 30° (вынесено в чистую функцию
ClockAngleMath, покрытую тестами). - Согласованность — при повороте минутной стрелки часовая следует за ней со скоростью 0,5°/мин. При переходе через 0 минут час переводится вперёд/назад (определяется по переходу 45→15 минут).
- Тактильность — на каждый шаг в 1 минуту срабатывает .sensoryFeedback(.selection), возвращая пальцу ощущение щелчка шестерёнки.
- Выбранная стрелка — на кончике стрелки отображается латунное кольцо (рукоятка), показывающее, какая стрелка сейчас управляется.
- Подтверждение — сохраняется табличкой «Установить это время». Преобразуется в Alarm.Schedule.relative из AlarmKit.
Муть часа — ночная тьма и рассвет
Чем глубже ночь, тем сильнее циферблат мутнеет тёмно-лиловым, точно сосуд души. В час рассвета муть очищается светом. В час заката на циферблате проступает и сияет созвездие текущего сезона. Проведите ползунок ниже, чтобы обойти сутки целиком.
21:00Вечер
- Муть — с 16 часов к вечеру от края циферблата начинает наполняться тёмно-лиловая муть, достигая максимума с 23 до 4 часов. Благодаря многослойному градиенту со смешением «умножение» цвет слоновой кости словно оседает на «дно сосуда».
- Очищение на рассвете — с 4 до 6 часов свет сверху (смешение «экран») растворяет муть. Главные часы на странице непрерывно живут этим циклом, синхронизированным с реальным временем.
- Созвездие сезона — на закате (±2 часа) золотом проступает созвездие текущего сезона. Весна = Лев / лето = Скорпион / осень = Кассиопея / зима = Орион. Ночью остаётся слабым свечением.
- Реализация на SwiftUI — коэффициент времени вычисляется через
TimelineView(.everyMinute)и отражается в отрисовке Canvas с режимами «умножение»/«экран» и в непрозрачности контура созвездия.
Крышка двенадцати чертогов — герб созвездия, сменяющийся ежемесячно
В центре крышки вставлена тёмно-лазурная эмаль, и с каждой сменой месяца чертог (созвездие) этого месяца заново вырезается золотом — вместе с полумесяцем и старинным японским названием месяца. Крышка главных часов на странице несёт узор текущего месяца.
Кружащиеся созвездия — · звёзды обладают глубиной и кружатся в пространстве непрестанно. Проведи пальцем — и добавится инерция вращения
Тон замысла следует антикварным карманным часам в стиле «лазурная эмаль × старое золото» (справочный материал: design-refs/ref-watch.jpg). Линии созвездий — стилизованная упрощённая форма. В SwiftUI узор, сменяющийся по месяцам, выбирается через Calendar.current.component(.month) и отрисовывается на Canvas золочением.
Арканы — таинство двенадцати чертогов
Проведи по циферблату круговым движением и заведи на двенадцать витков — явятся чары. Ночью — Арканы (12 видов чертогов), днём — Солнечные искусства (6 видов), при сомкнутой крышке — Печати (6 видов): всего в самом приложении 24 вида из трёх систем. На этой странице можно опробовать семь избранных из них.
Магия при открытой крышке
Магия при сомкнутой крышке (в приложении — Печать)
Час звучания (при срабатывании колокола-вестника)
Когда наступает урочный час, весь экран озаряется золотым мерцанием, и разворачивается магический круг с надписью «Урочный час настал!».
- Определение завода — отслеживается суммарный угол вращения вокруг центра циферблата, и каждые 2π засчитывается один виток. Загорается ромб магического круга. Если оставить в покое на 4 секунды, завод рассеется.
- Очищение светом рассвета — Очищает муть светом. Циферблат принудительно переходит в состояние рассвета, и проносится золотая вспышка.
- Буря созвездий — Созвездие сезона вспыхивает пламенем, и звёзды разлетаются от часов.
- Возврат времени — Стрелки стремительно идут вспять, и магический круг вращается в обратную сторону.
- Барьер лилового грома — Тёмно-лиловая вспышка и удар. Магический круг обращается в лиловый.
- Багряное пламя — Искры взмывают в трёхмерном пространстве вокруг часов (частицы с перспективной проекцией и мерцанием).
- Водоворот лазурных волн — Рябь расходится под ногами, и брызги чертят дугу, увлекаемые тяготением.
- Кольцо шквального ветра — Потоки ветра кружат вокруг часов, огибая их спереди и сзади, и напор ветра раскачивает часы.
- Реализация на SwiftUI — определение вращения основано на накоплении
atan2(добавлено в ClockAngleMath), магия унифицирована протоколомSpellEffect, а настройки гнёзд хранятся в UserDefaults. При звучании определяется состояние alerting в AlarmKit, и через fullScreenCover свершается великое явление.
Устройство экранов
Главный экран — всегда часы. Список, редактирование и таймер выстроены как рабочая изнанка крышки: гравированные таблички на той же фетровой основе.
Ты, освободи урочный час!
Ближайший урочный час — завтра, 7:30 до полудня
Долгое нажатие переключает тему
Главный экран (RootView)
Колокол-вестник
До полудня7:30
Будни · отсрочка 9 минут
До полудня9:00
Выходные
После полудня10:15
Только один раз
Список (AlarmListView)
Установить время
До полудня7:30
Метка — «Утренний чай» · отсрочка 9 минут
Установить это времяРедактирование (AlarmEditorView)
Таймер
Таймер (TimerView)
Live Activity / Dynamic Island
Таймер и секундомер живут на экране блокировки и в Dynamic Island. На чёрном фоне с одним лишь штрихом латуни они сохраняют дух карманных часов даже внутри системного интерфейса.
POCKETCHIME
Таймер для чая
4:23
Экран блокировки — на основе Text(timerInterval:)
Dynamic Island (compact) — циферблат слева, оставшееся время справа
Типографика и цвет
Шрифт — системная антиква (New York / Hiragino Mincho). Цифры набираются моноширинными знаками, а латинские подписи — с широким трекингом, придающим вид гравированной надписи.
10:09
Установить время
Открой крышку — и начнётся день. Заведи стрелки и жди урочного часа.
RAILROAD GRADE · EST. 2026
| Фетровая основа (фон) | #24331F → #0B110A | |
| Цвет туши (текст) | #EFE6CD | |
| Латунь (акцент) | #C9A24B | |
| Багрянец (секундная стрелка, предупреждение) | #A03A2A | |
| Сталь (серебряная тема) | #AEB6C2 |
| Замысел | Реализация (согласно DESIGN.md) |
|---|---|
| Открытие и смыкание крышки | rotation3DEffect(axis:(0,1,0), anchor:.leading) + spring 1.3s |
| Ход стрелок | Непрерывный привод через TimelineView(.animation) |
| Перетаскивание стрелки | ClockAngleMath (чистая функция на atan2, покрыта модульными тестами) |
| Отсрочка | secondaryButtonBehavior: .countdown + postAlert 9 минут |
| Отображение оставшегося времени | Live Activity на основе AlarmAttributes<PocketWatchMetadata> |
| Распространение темы | Единообразие вплоть до виджета через tintColor и metadata.themeName |