Communitygithub.com

蒙太奇动效与标题设计

专注于蒙太奇项目中基于图形和文本的运动图形与标题制作,包含弹出、擦拭、颜色变化、动态文字及预告片特效等。适用于无需影像或角色,而是由形状、静态图像和文字构建的视频片段。

蒙太奇动效与标题设计 是什么?

该技能专为 Montagent 视频创作工具设计,提供一系列运动图形和标题的制作配方。它涵盖了从简单的弹出动画(带有微小过冲的进入动画)到复杂的擦拭揭示、颜色变化以及动态文本(如逐字母、逐词或逐行的运动)等多种效果。其核心方法论是首先规划“节拍表”(beat sheet),将所有动画事件(进入、颜色变化、剪切、退出)按节拍排列,然后基于该表生成项目脚本,以便通过单行编辑轻松调整节奏。技能还包含高级技巧,如使用`transition`实现元素间的推送、滑动或擦拭过渡,以及为预告片类型效果提供快速的 slammed、glitch 和 HUD 组件。每个配方都提供了具体的参数范围和检查步骤(look step),确保动画效果精确、流畅。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/MBehtemam/montagent-skills/tree/HEAD/skills/montagent-motion

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

运动图形与标题设计

针对由形状、静态图像和文本构建的片段提供的配方。它们嵌入到 montagent 的构建步骤循环中;如果尚未加载 montagent,请先加载。

在规划之前,请根据片段类型打开相应的参考文件:

片段类型打开文件
广告片头、产品/社交媒体广告、开场、片尾广告片头结构
Logo 揭示、Logo 短片、任何循环内容Logo 循环
预告片,或任何 slammed、glitch、闪烁、HUD 效果预告片特效

对于新片段或重新设计,请在选择布局前阅读创意方向。它涵盖了 Montagent 原生环境中的视觉概念、构图和编排。对于具体的剪辑任务,只阅读相关配方,并保留现有的方向。

在节拍表上规划

在编写任何元素之前,先编写节拍表:将所有进入、颜色变化、剪切和退出事件整合到一个表格中,每个事件占据 montagent-craft 提供的一个节拍(包括其节奏、重拍、帧对齐,以及哪些事件应落在节拍上)。

使用一个生成器脚本从节拍表构建项目,这样重新调整时间只需编辑一行代码。

配方

每个配方提供的是起始范围,而非最终答案。每个配方都以一个检查步骤结束:加载 montagent-craft,然后在该步骤指示的位置进行检查,然后再继续。

弹出动画

一种带有小幅度过冲并最终稳定的进入动画。过冲体现在曲线上:使用一对关键帧,其贝塞尔曲线的 y 值超过 1,而不是使用三个关键帧。

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 2000, "output": "out/pop.mp4",
  "tracks": [
    {"name": "badge", "layer": 10, "elements": [
      {"id": "badge", "type": "ellipse", "start": 500, "end": 2000, "x": 960, "y": [{"t": 500, "v": 580}, {"t": 900, "v": 540, "ease": [0.34, 1.56, 0.64, 1]}], "origin": "center", "width": 240, "height": 240, "fill": "#FF5A36", "scale": [{"t": 500, "v": [0.5, 0.5]}, {"t": 900, "v": [1.0, 1.0], "ease": [0.34, 1.56, 0.64, 1]}]}
    ]}
  ]
}
  • 时长: 300–450 毫秒。较短的时长感觉更干脆,较长的则更漂浮。
  • 起始缩放: 文本和卡片为 0.5–0.7;小形状和徽章为 0。
  • 过冲: [0.34, 1.56, 0.64, 1] 峰值大约超过目标值的 10%。将第二个数字提高到 1.8 可获得更活泼的效果,或降低到 1.3 以获得更稳重的效果。在一个片段中,所有弹出动画保持使用同一个曲线。
  • 上升: y 轴上 20–60 像素的移动,配合相同的曲线,可以增加重量感。对于排列在一行的弹出动画,可以跳过此步。
  • 交错: 当每个项目落在自己的节拍上时,间隔一个节拍;如果项目在同一节拍内,则间隔 60–120 毫秒。
  • 检查: 在开始时间加上动画时长 40% 的位置查看 frame,此时过冲达到峰值,并检查是否有任何元素超出帧边缘或与相邻元素重叠。然后 preview 一个从第一次弹出前到最后一次弹出后的时间范围。

保持,然后清除

进入动画的最后一个关键帧已经保持状态,因此保持本身不消耗额外性能。退出动画从保持值的时刻开始,用一个关键帧记录该值。validate 会将该关键帧报告为 R-EASE-INERT,说明文档会解释为何这是预期的。

  • 退出时长: 200–350 毫秒,使用 ease-in。退出速度比进入快。
  • 退出运动: 一个淡出加上 20–40 像素的位移,或缩放到 0.9。若要硬切,使用单个 step 关键帧跳转到新值(请参考入门项目中的标题)。
  • 保持时长: 由 montagent-craft 提供的阅读时间。
  • 分组退出: 整个组一起退出,或按照阅读顺序交错 30–60 毫秒。
  • 检查: 在退出前的最后一帧查看 frame,确认整个组完全进入且处于静止状态。

单词上的颜色变化

使用该词所在行的一个 highlight 在节拍上改变其颜色。这会保持一个元素:无需创建第二个副本进行交叉淡入淡出,且元素自身的颜色仍然是整行的颜色。

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 3000, "output": "out/accent.mp4",
  "fonts": {"title": [{"file": "fonts/Inter-Bold.ttf"}]},
  "fontVendor": {"fonts/Inter-Bold.ttf": {"licence": "OFL-1.1", "source": "https://github.com/rsms/inter", "sha256": "288316099b1e0a47a4716d159098005eef7c0066921f34e3200393dbdb01947f"}},
  "tracks": [
    {"name": "line", "layer": 20, "elements": [
      {"id": "line", "type": "text", "start": 0, "end": 3000, "x": 960, "y": 540, "origin": "center", "width": 1600, "height": 140, "font": "title", "size": 110, "color": "#F5F0E6", "align": "center", "runs": [{"text": "Video your agent can "}, {"text": "read.", "highlight": {"start": 2000, "end": 3000, "color": "#FF5A36"}}], "caption": false}
    ]}
  ]
}
  • 时机: 变化发生在节拍上,绝不能发生在单词进入的时刻。在单词变化之前,至少留出半个节拍的时间让眼睛先阅读该词。
  • 强调: 当单词是一个独立的元素时,在同一节拍上应用一个缩放凸起(从 1.0 到 1.06–1.1,再在 200–300 毫秒内恢复),以使变化更加突出。
  • 检查: 在变化前和变化后各查看一帧 frame,确认只有目标单词发生了改变。

动态文本与键入效果

当每个字母、单词或行共享一个运动曲线并以规则步长(every 毫秒)出现时,保持单个 text 元素,并使用 units 进行交错(by:letter、word 或 line;order:forward、reverse、center_out 或 edges_in)。以下示例中,一个标题从中心向外模糊显现:

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 2000, "output": "out/evaporate.mp4",
  "fonts": {"title": [{"file": "fonts/Inter-Bold.ttf"}]},
  "fontVendor": {"fonts/Inter-Bold.ttf": {"licence": "OFL-1.1", "source": "https://github.com/rsms/inter", "sha256": "288316099b1e0a47a4716d159098005eef7c0066921f34e3200393dbdb01947f"}},
  "tracks": [
    {"name": "title", "layer": 20, "elements": [
      {"id": "evaporate", "type": "text", "start": 0, "end": 2000, "x": 960, "y": 540, "origin": "center", "width": 1400, "height": 160, "font": "title", "size": 108, "color": "#F5F0E6", "align": "center", "runs": [{"text": "SHARP FOCUS"}], "units": {"by": "letter", "order": "center_out", "every": 45, "y": [{"t": 0, "v": 20}, {"t": 360, "v": 0, "ease": "ease-out"}], "opacity": [{"t": 0, "v": 0}, {"t": 360, "v": 1, "ease": "ease-out"}], "blur": [{"t": 0, "v": 24}, {"t": 360, "v": 0, "ease": "ease-out"}]}, "caption": false}
    ]}
  ]
}
  • 蒸发/光学聚焦(blur): 在 units 中设置 blur 从 16–32 像素降至 0,时长 300–450 毫秒(ease-out),并与 opacity(0 -> 1)和一个小幅度 y 提升(16–28 像素 -> 0)或 scale([1.08, 1.08] -> [1.0, 1.0])组合。一旦 blur 达到 0 且 opacity 达到 1,渲染器将采用快速路径,没有额外的图层开销。
  • 对称顺序(center_out、edges_in): center_out 从中间单元(偶数时从中间两个单元)开始,逐步向两端扩展;edges_in 从首尾单元同时开始,向中间汇聚。
  • 行波(A -> 峰值 -> A): 无需像 After Effects 的范围选择器(triangle、round 或 smooth),直接在 units 中编写一个三个关键帧的返回曲线——例如 "y": [{"t": 0, "v": 0}, {"t": 180, "v": -28, "ease": "ease-out"}, {"t": 360, "v": 0, "ease": "ease-in-out"}](或 scale/blur 脉冲)——让 every 使峰值在整个行中波动。若要将某个单词或字母独立出来并设置自定义时间,可将其拆分为自己独立的 run 并附带 unit。
  • 保持字形为 text(切勿将字形转换为 path): path 元素只有一个轮廓(points,没有 holes),因此将多轮廓字形(如 O、A、B、8、i、?、%)转换为 path 会填充内部区域或丢失孤立部分(ADR-0224)。将文本保持为 text,并通过 stroke、units、path 和 effects 进行样式化或动画处理。
  • 不规则节拍时间或打字光标(scripts/type_on.py): 当单词落在不规则的节拍时间戳上,或字母需要带有步进光标时,运行 python3 scripts/type_on.py <project> <spec>(使用 --help 查看 spec)。它会使用 measure 测量行,并为每个单元发射一个 text 元素("by": "word" 配合 "enter": "pop" 和 times/highlights,或 "by": "letter" 在 60–150 毫秒内配合闪烁的 cursor),并将每个标记为 caption: false。
  • 跟踪标题: 不要将标题拆分成字母。编写一个 text 元素,并使用 letter_spacing,单位为千分之一 em(每个字母后的像素距离为 size × letter_spacing / 1000;负值收紧)。通过关键帧使标题逐渐散开:"letter_spacing": [{"t": 0, "v": 0}, {"t": 800, "v": 120, "ease": [0.65, 0, 0.35, 1]}]。任何非零值都会关闭可选的连字功能,像阿拉伯语这样的连字脚本不会产生间距。
  • 垂直列和侧边文字: Montagent 没有 writing_mode 属性(ADR-0224)。对于垂直堆叠的列(CJK 竖排文字或垂直字幕),使用 \n 连接字素("text": "東\n京\n都")放在一个狭窄的 text 框内,设置 "align": "center" 和 "line_height": 1.0 或 1.1;将 2–3 个水平数字或拉丁首字母保持在一行("text": "第\n25\n回",纵中横排),并使用 "by": "line" 进行交错,使水平数字作为一个整体移动。对于侧边的拉丁文字,设置一个水平 text 元素,并使用 "rotation": -90(从下往上读)或 "rotation": 90(从上往下读)旋转它。
  • 检查: preview 行出现的时间范围。然后在静止时 frame 检查,确保间距读起来像一行,单词或字母边界处没有过宽的间隙。

擦拭揭示

擦拭动画通过滑动一个边缘来揭示下方的物体。在被揭示物体的上方放置一个遮挡物:一个填充了与背景完全相同颜色的矩形。然后以远离边缘的方向缩小遮挡物,使其近边缘扫过物体。一条沿着该边缘移动的强调条能使擦拭动作看起来更刻意。

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 2000, "output": "out/wipe.mp4",
  "tracks": [
    {"name": "mark", "layer": 10, "elements": [
      {"id": "mark", "type": "image", "start": 0, "end": 2000, "source": "media/still.png", "x": 960, "y": 540, "origin": "center", "width": 360, "height": 360, "fit": "contain"}
    ]},
    {"name": "occluder", "layer": 11, "elements": [
      {"id": "occluder", "type": "rect", "start": 0, "end": 1000, "x": 1160, "y": 540, "origin": "center-right", "width": 400, "height": 400, "fill": "#101418", "scale": [{"t": 400, "v": [1.0, 1.0]}, {"t": 900, "v": [0.0, 1.0], "ease": [0.65, 0, 0.35, 1]}]}
    ]},
    {"name": "edge", "layer": 12, "elements": [
      {"id": "edge", "type": "rect", "start": 400, "end": 1000, "x": [{"t": 400, "v": 760}, {"t": 900, "v": 1160, "ease": [0.65, 0, 0.35, 1]}], "y": 540, "origin": "center", "width": 16, "height": 420, "fill": "#FF5A36", "opacity": [{"t": 900, "v": 1.0}, {"t": 1000, "v": 0.0, "ease": "ease-in"}]}
    ]}
  ]
}
  • 时长: 400–600 毫秒,[0.65, 0, 0.35, 1]:一个起始和结束都柔和的扫动。
  • 遮挡物: 在物体的每一侧都大出 20–40 像素,并使用与其背后的地面相同的填充。起始关键帧放置在擦拭开始的位置,以便物体在此之前保持被覆盖状态。
  • 边缘条: 8–24 像素宽,比遮挡物高 5–10%,沿相同的曲线和时间移动。它在扫动完成后 100–200 毫秒内消失。
  • 方向: 沿阅读方向擦拭;要擦除,则从近边缘反向扩大遮挡物。
  • 复杂背景: 遮挡物仅在纯色背景上有效。在照片、渐变或视频内容上,应为元素自身的 mask 设置关键帧:{"name": "mask", "shape": "rect", "x": 0, "y": 0, "width": [{"t": 400, "v": 0}, {"t": 900, "v": 400, "ease": [0.65, 0, 0.35, 1]}], "height": 400} 可以从左边缘揭示一个 400×400 的元素,无需遮挡物。矩形蒙版是元素本地的,相对于元素的左上角;宽度为零的蒙版会隐藏元素,因此揭示开始时是覆盖的。添加 feather 以获得柔边。
  • 检查: 在扫动进行到一半时 frame 检查,确保边缘条恰好覆盖遮挡物的边缘;然后在扫动结束后立即 frame 检查,确认遮挡物已完全消失。

通过推、滑或擦拭进行转场

为了从一个卡片、静态图像或场景平滑移动到下一个,使用 transition 类型的 push、slide 或 wipe。对两个元素分别设置 x 关键帧会导致在连接处产生偏移;过渡效果确保两半像素级对齐,validate 会检查这一点。

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 3000, "output": "out/handover.mp4",
  "tracks": [
    {"name": "first", "layer": 10, "elements": [
      {"id": "card-1", "type": "rect", "start": 0, "end": 1700, "x": 0, "y": 0, "origin": "top-left", "width": 1920, "height": 1080, "fill": "#FF5A36"}
    ]},
    {"name": "second", "layer": 11, "elements": [
      {"id": "card-2", "type": "rect", "start": 1200, "end": 3000, "x": 0, "y": 0, "origin": "top-left", "width": 1920, "height": 1080, "fill": "#2E86FF"}
    ]},
    {"name": "handover", "layer": 12, "elements": [
      {"id": "handover", "type": "transition", "start": 1200, "end": 1700, "kind": "push", "from": "card-1", "to": "card-2", "direction": "left", "ease": [0.65, 0, 0.35, 1]}
    ]}
  ]
}
  • 类型: 当两个元素属于一个序列(页面、步骤、轮播)时使用 push;当新元素落在静止的旧元素之上时使用 slide;当旧元素应保持在原位并被划掉时使用 wipe。
  • 方向: 运动传播的方向。left 使新元素从右侧进入,符合阅读方向。
  • 时长: 400–600 毫秒,[0.65, 0, 0.35, 1]。过渡的 start 和 end 正好是两个元素共存的时段。
  • 滑动层级: 在 slide 中,进入的元素必须位于更高的 layer 上。
  • 检查: 在过渡的中段 frame 检查,确保连接处没有间隙或重叠。然后 preview 整个过渡范围,确认运动流畅。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

相关技能