alchemistry

Карта превращений

Полная схема проекта: что из чего делается и в каком порядке. Данные —
data/alchemy.json, рисуется браузером, без сторонних библиотек.

Слева то, что покупают в магазине. Всё, что правее, — крафт, даже если это
первый шаг. Левее — значит раньше по времени. Крафт в магазинную колонку не
встаёт: капли делаются из кувертюра, поэтому правее какао; печенье самое правое,
оно идёт после всего. Кокосовый корж, у которого на схеме нет ни одного входа,
стоит в первой колонке крафта — его ингредиенты просто не показаны.

Пунктирная рамка — сырьё, сплошная — крафт. Предметы не перетаскиваются: схема
держит осмысленный порядок.

Управление

ДействиеКак
Выбрать узел, повторно снять выделениеЛевая кнопка или Enter
Предпросмотр цепочки без перестройкиНаведение на предмет
Загорать связь и оба её концаКлик по стрелке
Показать всю цепочку с перестройкойКлик по узлу
Отменить выделениеEsc или «Отменить выделение»
Двигать схемуПравая кнопка
Вписать в кадр то, что показаноСредняя кнопка или «Всё сразу»
Зум и детализация подписейКолесо, лупы, поле процента
Скрыть боковую панель и вернутьСтрелка слева от панели
Показать одну роль«Только сырьё» / «Только готовые», повтор снимает
Справка поверх схемы«Как читать»

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

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

Масштаб

Три кнопки по центру сверху: отдалить, процент, приблизить. Процент — поле
ввода, а не подпись: кнопки дают только шаг, а нужно и 85 %, и 175 %. Принимаются
85, 85 % и 60,5.

Отсчёт от «вся схема в кадре», поэтому 100 % — ровно то, что делает «Всё сразу».
Единица масштаба у схеме своя и от размера окна не зависит, так что «100 %» на
двух экранах значили бы разное.

Колесо работает и над полем, и число едет вместе с картинкой. Клик в другое
место масштаб не сбрасывает: поле применяется, только если его правили.

Три состояния узла

МасштабЧто видно
мелкопросто прямоугольник, без надписей
средненазвание во весь прямоугольник, кегль один на все узлы
крупноназвание сверху, слева время готовки, справа срок хранения

Надпись в два-три десятка знаков на мелком плане сливается в кашу и перекрывает
рамки соседей, поэтому на самом отдалении её нет вовсе. На среднем плане длинные
названия обрезаются по символам, а не по словам: «Шоколадное мороженое» →
«Шоколадное морож…». По словам три шоколада стали бы тремя одинаковыми
«Шоколадное…», и различать их осталось бы только по рамке.

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

Выбранный узел

Залит целиком бежевым, подписи внутри темнеют и становятся жирными. Три
переменные: --sel-bg — заливка, --sel-ink — название, --sel-dim — время,
срок и иконки.

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

Рамки не хватало. У выбранного узла и у участников его цепочки рамка горит
одинаково — отличалась только толщина, а толщина на мелком плане не видна вовсе,
там и frameBoost держит её в одном пикселе. Заливка отличается при любом зуме.

Мелкие подписи в выбранном узле: жирность 700, прозрачность 1, иконки толще
2,6. Не только цветом: тонкая подпись на светлой заливке терялась, даже когда
цвет был правильным. Название узла в выбранном виде тоже 700, а не 600: на том же
фоне 600 выглядели тоньше подписей под ними, и узел назывался менее жирным, чем
время готовки под ним.

Значения для невыбранного состояния ставятся явно, а не «не выставляются»:
иконка рисуется с прозрачностью .7 при создании, и без явного снятия на
выбранном узле она осталась бы бледной, а жирность пришлось бы ставить в
два места.

У участников цепочки заливки нет намеренно: иначе «выбранный» не отличить от
«входит в цепочку выбранного», а это разные вещи. Снимается по Esc, по
повторному нажатию на узел и кнопкой «Снять выделение».

Что стоит в рамке

Слева время готовки, справа срок хранения. Условия («16–18 °C, темно», «Зип-пакет

Срок на схеме всегда минимальный: «6–12 мес» занимает столько же места, сколько
«6 мес», а полный диапазон остаётся в статье и в самих данных. Если у изделия
есть условия, но никто не измерял срок, рамка остаётся почти пустой — так и у
шоколадного мороженого. Писать срок от соседей нельзя: пустая рамка честнее
выдуманного числа.

Боковая панель

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

Состояние помнится в localStorage: панель это расположение, а не отметка о
сделанной работе. На узком экране панель уходит вниз, поэтому и стрелка уезжает
в верхний угол и смотрит вниз, а возвращается вверх.

Пунктирные стрелки

Пунктир — не украшение, а утверждение: этот слой можно заменить. Сплошная
стрелка — обязательный слой. Пунктир стоит только там, где замена описана, иначе
он врёт в другую сторону — читается «обязательно», а на самом деле нет.

Пунктирная стрелкаПочему заменяема
Вафля-корж, безе, кокосовый корж → Твикстри варианта одного слоя
Сгущённое молоко → Мягкая карамельвместо сливок, путь Б
Молочный и горький шоколад → Горячий шоколадделается и так, и так

В обзоре и при выборе узла пунктир снимается: подсвеченная связь сплошная. Иначе
в цепочке Горький → Горячий шоколад горел бы пунктиром, а читалось это как
«можно не брать», хотя горячий шоколад делают и из молочного, и из горького, и
ни один не лишний. В разборе варианта наоборот: пунктир остаётся, но красится в
акцент — это единственное место, где по стрелке видно, что слой заменяемый.

Подсвеченные стрелки всегда на переднем плане, иначе их перечёркивают серые.
Поднимаются они внутри слоя рёбер, поэтому рамки узлов поверх остаются на месте.

Варианты изделий

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

На странице блюда варианты переключаются кнопками. На схеме при наведении на
изделие с вариантами под узлом выпадает их список; при выбранном узле варианты
перечислены в панели.

Наведение на вариант отвечает на два вопроса: чем этот вариант заменил слой по
умолчанию и что в нём обязательно. Выбранная замена становится сплошной,
остальные заменяемые остаются пунктирными — и все входы в изделие горят оранжевым,
включая пунктирные. Иначе сплошную замену не отличить от серых стрелок, ведущих
мимо варианта.

Разбор варианта смотрит на то же замыкание, что и обычное наведение: горит вся
цепочка, до сырья в первом столбике. Раньше горели только связи прямо в изделие,
и читалось так, будто сырьё в варианте не участвует.

В data/alchemy.json это поле variants у узла, флаг alt у ребра и pick у
варианта: узел, которым вариант заменяет слой по умолчанию. Расхождение схемы и
статьи ловит python tools/check_variants.py.


Логика проекта — docs/base/alchemy.md.