Анимация по ключевым кадрам¶
play_keyframes() анимирует конструкцию по таймлайну в виде JSON или dict.
Используйте этот метод, когда нужна воспроизводимая анимация «состояние в момент
T», которую можно создать в интерфейсе, сохранить как JSON, показать в точке
каретки и отрендерить в видео.
Минимальный формат¶
scene.loadGGB("scene.ggb", style="style.json", export={"size": {"width": 800, "height": 600}})
scene.play_keyframes({
"version": 2,
"keyframes": [
{"t": 0, "values": {"A": [0, 0], "x": 35}},
{"t": 2, "values": {"A": [4, 2], "x": 110}, "easing": "smooth"},
{"t": 4, "values": {"A": [0, 0], "x": 35}},
],
})
Время ключевого кадра задаётся в секундах и должно строго возрастать. Первый кадр применяется до начала воспроизведения, поэтому первый отрендеренный кадр соответствует таймлайну, а не обязательно сохранённому состоянию редактора GeoGebra.
"version": 2 включает текущий формат. Если версия не указана, используется
устаревший v1: обычная анимация значений остаётся полностью совместимой, но v1
не поддерживает треки стилей, эффекты видимости, камеру и события.
Что можно анимировать¶
Перед созданием таймлайна вызовите scene.get_independent_elements(). Метод
возвращает свободные входы, которыми можно управлять через values.
Для сцен, загруженных из GeoGebra:
- свободные точки:
[x, y]; - точки на траектории:
{"tparam": ...}; точки на окружности и эллипсе также принимают"direction": "short" | "cw" | "ccw"; - точку на траектории можно передать и как
[x, y]: AnimaGeo спроецирует координаты обратно в параметр траектории; - числа и углы: числа с плавающей точкой;
- логические значения:
true/falseв JSON,True/Falseв Python.
В сценах, построенных через DSL, созданные командами точки не являются независимыми по имени. Управляйте ими через переменные:
cx = scene.addVar("cx", 2.0)
cy = scene.addVar("cy", 4.0)
scene.putCode("C = Point(cx, cy)")
scene.play_keyframes({"version": 2, "keyframes": [
{"t": 0, "values": {"cx": 2.0, "cy": 4.0}},
{"t": 2, "values": {"cx": 4.0, "cy": 3.0}},
]})
Плавность¶
Поле "easing" ключевого кадра управляет интервалом, который ведёт к этому
кадру. Значение по умолчанию для всего таймлайна задаётся так:
Поддерживаемые имена:
linear, smooth, in, out, in_out, smootherstep,
ease_in_sine, ease_out_sine, ease_in_out_sine, ease_in_cubic,
ease_out_cubic, ease_in_out_cubic, rush_into, rush_from,
ease_out_back, ease_out_elastic, ease_out_bounce.
Веб-превью и Python-рендерер используют один и тот же список.
Треки стилей¶
В v2 каждый ключевой кадр может содержать styles. Стиль можно назначать
любому элементу, а не только независимому.
scene.play_keyframes({"version": 2, "keyframes": [
{"t": 0, "styles": {"c1": {"fill_opacity": 0.0, "stroke": "#2581b5"}}},
{"t": 2, "styles": {"c1": {"fill_opacity": 0.6, "stroke": "#d05456"}}},
{"t": 3, "styles": {"c1": {"stroke": None}}},
]})
JSON null или Python None возвращает ключ стиля к значению до начала
анимации. Цвета интерполируются перцептивно, если с обеих сторон заданы
hex-значения; остальные форматы цвета переключаются дискретно. Дискретные
ключи, например label_visible, label_anchor, point_shape, tick_count,
label_text и z_index, меняются в середине интервала.
Анимируемые ключи стиля:
- числа (интерполируются):
stroke_opacity,fill_opacity,stroke_width_px,stroke_dash_period_px,size_px,font_size_px,arc_size_px,arc_shift_px,right_angle_size_px,tick_length_px,tick_width_px,tick_shift_px,arrow_length_px,arrow_width_px,label_radial_offset_px - цвета (интерполируются):
stroke,fill,label_color label_offset_px:[x, y], интерполируется по компонентамstroke_dash_ratio: интерполируется между числами; переключается, если одна из сторонNone(сплошная линия)label_text: заменяется в середине интервала, не смешивается- переключаются в середине интервала:
point_shape,stroke_linecap,tick_count,tick_style,angle_range,right_angle_marker,label_anchor,label_visible,label_mode,z_index,z_index_fill
Любой другой ключ вызывает ошибку.
Подписи в ключевых кадрах¶
Снимки раскладки подписей работают, только если оба флага
overlay.label_placement.enabled и overlay.label_placement.keyframe_snapshots
равны true. Предварительный проход применяет стили каждого ключевого кадра до
измерения, поэтому анимированные размеры шрифта и дуг, текст и видимость влияют
на раскладку подписей.
Когда снимки включены, они определяют положение всех подписей: дорожка стиля
label_offset_px игнорируется и не конфликтует с интерполяцией снимков.
Подпись, которая появляется внутри интервала (скрыт её элемент или она сама в
начале интервала), сразу стоит на автоматически найденном месте. При
выключенном размещении подписи сохраняют импортированные или заданные вручную
смещения, снимки не строятся. apply_keyframes_at() ставит подписи по тем же
снимкам (считает только два ключевых кадра вокруг нужного момента).
Видимость и эффекты¶
visible — абсолютная карта видимости для каждого кадра. show и hide
принимаются как сокращённая запись v2 и сводятся к visible.
scene.play_keyframes({"version": 2, "keyframes": [
{"t": 0, "visible": {"seg": False}},
{"t": 1.5, "visible": {"seg": True},
"enter": {"seg": {"effect": "create", "duration": 0.8}}},
{"t": 3, "visible": {"seg": False}, "exit": {"seg": "fade"}},
]})
Эффекты появления: fade, none, create, grow, write. Эффекты
исчезновения: fade, none, uncreate, shrink. Они проигрываются внутри
интервала ключевого кадра с заданной длительностью; v2 не добавляет задержку
0,4 секунды из v1 для show/hide. grow и shrink масштабируют геометрию
элемента относительно её собственного центра; подпись остаётся на месте и
плавно гаснет, а не масштабируется.
Поэтапное построение¶
Для анимации в стиле «протокол построения»:
Сцена проходит по элементам в порядке зависимостей, выбирает подходящие по типу
эффекты появления и проигрывает сгенерированные кадры v2. Передайте
play=False, чтобы изучить или встроить полученный таймлайн, не проигрывая его
сразу.
Ключевые кадры камеры¶
"@camera" — зарезервированный псевдоэлемент v2 внутри values:
scene.play_keyframes({"version": 2, "keyframes": [
{"t": 0, "values": {"@camera": {"center": [0, 0], "width": 14}}},
{"t": 2, "values": {"@camera": {"center": [1, 1], "width": 6}}},
]})
Так анимируется рамка камеры Manim: геометрия и декоративные элементы с
пиксельными размерами масштабируются вместе. Это кинематографический pan/zoom,
а не сохраняющий пиксельные размеры ZoomIn из GeoGebra.
События акцентирования¶
Поле events ключевого кадра проигрывает однократные акценты с автоматическим
возвратом состояния внутри ведущего к кадру интервала:
scene.play_keyframes({"version": 2, "keyframes": [
{"t": 0},
{"t": 2, "events": [
{"effect": "indicate", "targets": ["B"], "at": 0.4, "duration": 0.6},
{"effect": "circumscribe", "targets": ["poly"], "at": 0.4, "duration": 0.6},
]},
]})
Эффекты: indicate, flash, circumscribe. targets — список имён
элементов. at и duration задаются в секундах от начала текущего интервала.
Статическое превью¶
apply_keyframes_at() переводит сцену в состояние для одного момента таймлайна
без воспроизведения анимации:
Вызов идемпотентен, а время за пределами таймлайна ограничивается его границами. Метод подходит для серверного создания миниатюр и превью в точке каретки интерфейса.