Движок и визуал — только по просьбе (references/engine.md)

Источник: ds-internal/presentations/component-video-skill/references/engine.md — справочник скилла astra-component-video

Всё здесь меняет стиль всех роликов. Делать только по прямой просьбе пользователя и после правки прогнать самопроверку на образцах.

Исходник шаблона — репозиторий astra-doc, папка ds-internal/presentations/component-video. Пакет скилла собирается из неё скриптом pack.py в соседней component-video-skill. Правка, сделанная только в копии у себя, расходится с остальными исполнителями: её надо перенести в исходник и пересобрать пакет.

Как устроен движок

engine/astra-video.js:

nb(text)неразрывные пробелы по русской типографике: после коротких предлогов и союзов, перед тире, между числом и словом; связанная пара поднимается одной маской
masked, words, rise, sink, appear, fadeUp, morphслова в маске и их выезд, появление карточек, смена картинки через размытие
voiceAt(key, t0), onBeats(v, items, fallback)фразы голоса подряд от начала части и метки voice; моменты появления элементов с beat
squircle(w, h, inset)контур сглаженного угла Astra Fintech для обрезки ячеек
bezier(x1, y1, x2, y2)кривая как в CSS и прототипе Figma, без плагинов GSAP
cue(type, t, extra)метка для музыки
wave(t, x, y, { amp, width, speed, life })кольцо по точкам фона от места действия; по умолчанию 1, 70, 900 px/с, 1,6 с
gradField(), dotField(), fogField()фон: живой градиент, сетка точек, туман
SCENES.<тип>типы сцен
buildTimeline()интро 0–2,2 с, обложка 2,2–5,6 с, сцены, финал 3,5 с

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

Плавные градиенты считаются в 480×360 с дизерингом — иначе в 8-битном MP4 идут полосы.

Новый тип сцены

SCENES.<тип> = {
  build(s, i, box) { /* разметка внутри box; s — объект сцены из данных */ },
  play(s, i, t, box) {
    /* анимация на таймлайне tl с момента t */
    return { t: /* конец сцены */, exit: (at) => { /* уход сцены */ } };
  },
};
  • Размеры — в пикселях кадра 1440×1080; верх и низ заняты шапкой и подвалом.
  • Под голос: play(s, i, t, box, v) получает v — фразы сцены; моменты элементов — onBeats(v, items, (k) => <момент без голоса>). Сцена с голосом кончается с последней фразой плюс hold, это делает движок.
  • Тексты на экран — только через masked() и words(): они ставят неразрывные пробелы.
  • На каждое главное действие — cue() и рядом wave() в той же точке. Уже озвученные типы меток: toggle (щелчок), step, column, row, phone, tap, zoom, transition с { d } (свист длиной в переход). Новый тип метки без ветки в tools/synth_music.py пройдёт без звука.
  • Обязательные поля сцены — в REQUIRED в tools/build.mjs; поля и длительность — в references/scenes.md.

После правки:

  1. node tools/selftest.mjs — старые образцы обязаны совпасть: метки, музыка, кадры;
  2. образец нового типа — файл в videos/, node tools/build.mjs <образец> --no-render;
  3. эталон заново — node tools/selftest.mjs --record, только когда старые образцы совпали.

Визуал из Figma

Источник стиля — файл OX1roJ1cq7uzb7nSe4fUov, секция «Видео структура» 1:1123, кадры 1280×1024: «Превью» 9:62 (интро), «Компонент» 1:1011 (обложка), «Слайд» 1:900 (сцены), «Итоговая страница» 9:53 (финал).

  1. Числа — из узлов, не со скриншота. Через use_figma на чтение: у слоёв opacity, blendMode, fills, effects; у текстов characters, fontSize, lineHeight, координаты. Параметры шейдера сетки — fills[0].properties, имена — в propertyMetadata.
  2. Перевод в кадр ролика: кегли и отступы × 1,125 (1280 → 1440). Фон во всех кадрах — Gradient → Grid (шейдер, режим Screen) → Color Brand Mask #6E4DC4 (режим Color); в движке .grad-canvas → .grid и .dots → .tint.
  3. Цвет — замером. get_screenshot(…, maxDimension: 1280) и снимок того же момента; средний цвет в десяти точках: углы, середины краёв, диагональ. Параметры слоя не всегда равны кадру: точка сетки в шейдере белая на 50 %, а в кадре поднимается над фоном на ~14 единиц из 255 — поэтому в движке 14 %.
  4. После правки — самопроверка и снимки интро, сцены и финала рядом со скриншотами Figma.