HyperFrames 时序移植指南:Remotion interpolate、spring 与 easing 到 GSAP 的完整映射 HyperFrames 时序移植指南Remotion interpolate、spring 与 easing 到 GSAP 的完整映射【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes导读本文是 remotion-to-hyperframes 技能中最高杠杆的一份参考——在把 RemotionReact合成移植为 HyperFramesHTML GSAP时缓动与时间轴是观众最先感知的差异时序翻错比其他任何翻译选择损失的 SSIM 都更多。本文以 timing.md 为主体骨架逐条讲解帧与秒的换算、interpolate线性/多段/自定义缓动、spring()弹簧、颜色与数字动画、stagger 错峰在 GSAP 时间线上的落地写法并给出 T1–T3 分层语料实测的 SSIM 数据与源码级佐证。读完你将能够把任意 Remotion 的帧驱动动画准确翻译成可渲染、可验证的 HyperFrames 时间线。为什么时序是移植中的最高优先级HyperFrames 的时间线以秒为单位而 Remotion 以帧为单位。两者之间的换算和缓动映射贯穿整个移植过程直接影响渲染结果的像素级一致性。在 SKILL.md 定义的评估流程里翻译结果会与 Remotion 基线渲染逐帧做 SSIM 对比时序错误造成的画面差异往往比其他任何翻译选择布局、字体、媒体都更显眼。因此本参考被标注为single highest-leverage reference并且已经过 T1–T3 分层语料的经验验证层级合成形态实测平均 SSIM阈值T1单元素淡入淡出0.9740.95T2多场景 spring 音频 图片0.9850.95T3数据驱动、自定义子组件、数字滚动0.9530.90完整验证基线见 SKILL.md 的 validated baseline 表SSIM 评估的完整流程见 eval.md。换算基础frames → secondsHF 的时间线单位是秒Remotion 基于帧。永远执行time_seconds frame / fps以 fps30 为例frame 15 → 0.5 sframe 30 → 1.0 sframe 90 → 3.0 s关键实践在翻译时一次性完成换算而不是在运行时换算。HyperFrames 的合成是seek 驱动的确定性模型动画应被烘焙成一条暂停的 GSAP 时间线帧计数在渲染时不应出现。这条规则在 tier-1-title-card 的 HF 产物中直接可见——翻译注释明确写着Frame ranges → time ranges: 0/300, 15/300.5, 75/302.5, 90/303.0所有时间偏移都在生成 HTML 时计算完毕。interpolate 线性插值 →ease: noneRemotion 最常见的单段线性插值const opacity interpolate(frame, [0, 30], [0, 1], { extrapolateRight: clamp });翻译为 GSAPgsap.to(target, { opacity: 1, duration: 1.0, ease: none }, 0); // 如果属性从 0 开始且 CSS 尚未设置初始值使用 fromTo gsap.fromTo(target, { opacity: 0 }, { opacity: 1, duration: 1.0, ease: none }, 0);要点ease: none与 Remotion 默认的线性插值完全一致如果初始状态已经写在 CSS 里用gsap.to即可否则必须用fromTo显式给出起始值。关于extrapolate的边界行为Remotion 中extrapolateLeft/extrapolateRight默认是extend继续外推但实际翻译中遇到最多的写法是clamp。GSAP 本身不会外推——tween 的起止值在动画前后保持恒定天然等价于clamp。因此源码用clamp→ GSAP 直接匹配无需额外处理源码用extend→ 需要在发射 HTML 前手动扩展输入范围把 tween 的起始/结束时间按外推斜率继续延伸到需要的帧GSAP 无法隐式表达。interpolate 多段插值 → 时间线分段 tweenRemotion 的多段插值如淡入→保持→淡出const opacity interpolate(frame, [0, 15, 75, 90], [0, 1, 1, 0]);在 GSAP 中翻译为三条时间线 tween偏移量依次为[0]/fps、[1]/fps、[2]/fpsfps30 时即 0 / 0.5 / 2.5 秒const tl gsap.timeline({ paused: true }); tl.to(target, { opacity: 1, duration: 0.5, ease: none }, 0); tl.to(target, { opacity: 1, duration: 2.0, ease: none }, 0.5); tl.to(target, { opacity: 0, duration: 0.5, ease: none }, 2.5);该模式在 T1 中已验证平均 SSIM 0.974。实际语料 TitleCard.tsx 的源码正是interpolate(frame, [0, 15, 75, 90], [0, 1, 1, 0], { extrapolateLeft: clamp, extrapolateRight: clamp })淡入 0–15 帧、保持 15–75 帧、淡出 75–90 帧其 HF 产物 index.html 中三条tl.to与上述代码逐条对应duration恰好是相邻关键帧的帧距除以 30。spring() 弹簧 → GSAP back.outspring()是损失最严重的翻译。Remotion 的弹簧基于物理模型damping/stiffness/mass而 GSAP 的back.out/elastic.out是参数化缓动两者并非精确等价。但经验证近似映射足以让真实合成保持 ≥ 0.92 SSIM。Remotionspring配置GSAP 等价写法验证情况{damping: 12, stiffness: 100, mass: 1}干脆利落back.out(1.4)时长约 0.7 sT2、T3TitleScene{damping: 14, stiffness: 90, mass: 1}更温和back.out(1.2)时长约 0.7 sT3StatCard{damping: 8, stiffness: 200}非常有弹性back.out(2.0)或elastic.out(1, 0.5)时长约 0.6 s未验证预算约 0.05 SSIM{overshootClamping: true}power3.out时长约 0.6 s无过冲未验证经验法则back.out(N)的过冲比例 ≈(stiffness / damping^2) * 1.4。例如damping:12, stiffness:100时1.4 * 100/144 ≈ 0.97接近已验证的 1.4——公式只是粗略估计最终以目视微调为准。典型配置的默认时长约 0.7 s。当 spring 的delay/from/to参数非默认值时按比例缩放时长把延迟与位移折算进 tween 的偏移与目标值。源码佐证T3 的 TitleScene.tsx 使用spring({ config: { damping: 12, stiffness: 100, mass: 1 } })驱动标题缩放其 HF 产物 index.html 中对应tl.to(title, { scale: 1, duration: 0.7, ease: back.out(1.4) }, 0)StatCard 的{damping: 14, stiffness: 90, mass: 1}则对应back.out(1.2)两处注释都标注了映射来源。interpolate 自定义缓动 → GSAP 缓动等价表Remotion 通过Easing传入自定义缓动import { Easing } from remotion; interpolate(frame, [0, 30], [0, 1], { easing: Easing.out(Easing.cubic) });完整映射表RemotionGSAPEasing.in(Easing.linear)ease: noneEasing.out(Easing.cubic)ease: power3.outEasing.inOut(Easing.cubic)ease: power3.inOutEasing.out(Easing.poly(N))ease: powerN.outN2 对应 quad3 对应 cubic4 对应 quart5 对应 quintEasing.bezier(a,b,c,d)CustomEase.create(c, M0,0 C${a},${b} ${c},${d} 1,1)需 CustomEase 插件Easing.elastic(bounciness)ease: elastic.out(${bounciness}, 0.3)Easing.bounceease: bounce.outEasing.back(overshoot)ease: back.out(${overshoot * 1.7})Remotion 的过冲比例刻度不同需放大 1.7 倍注意Easing.back的过冲刻度与 GSAP 不一致这正是上面spring → back.out经验法则里1.4 倍系数的另一种体现形式。interpolateColors 非数值属性 → GSAP 原生颜色动画Remotion 用interpolateColors做颜色插值const color interpolateColors(frame, [0, 30], [#ff0000, #0000ff]);GSAP 原生支持颜色 tweengsap.to(target, { color: #0000ff, duration: 1.0, ease: none }, 0);backgroundColor、borderColor同理。from值由 CSS 或内联样式读取无需在 JS 中重复声明。在 SKILL.md 的 lint 分级中interpolateColors属于 Info 级可直接翻译并附注不会阻断移植。自定义数字滚动 / count-up → 计数器对象 onUpdate当 Remotion 使用帧驱动的数字斜坡Math.round(value * eased)时典型源码const t interpolate(frame, [0, 45], [0, 1]); const eased 1 - (1 - t) ** 3; // cubic ease-out const value Math.round(target * eased); return div{value.toLocaleString()}/div;GSAP 等价写法——tween 一个计数器对象在onUpdate中写回textContentconst counter { v: 0 }; tl.to( counter, { v: target, duration: 1.5, ease: power3.out, onUpdate: () { el.textContent Math.round(counter.v).toLocaleString(); }, }, 0, );要点power3.out与1 - (1-t)^3精确相等无需近似在 T3 中验证平均 SSIM 0.953子帧时序偏移可能导致个别帧的数字显示略有出入但终值必然收敛对 SSIM 的影响低于噪声底可忽略。源码佐证T3 的 AnimatedNumber.tsx 正是45 帧内1 - (1-t)^3缓出 toLocaleString的实现HF 产物 index.html 中三张 StatCard 各自对应一个counter对象 tl.to(..., { duration: 1.5, ease: power3.out, onUpdate })起始偏移为场景起始时间加各自的 stagger。Stagger 错峰 → 按实例 prop 换算时间线偏移当自定义子组件接收delayInFramesprop 时StatCard delayInFrames{i * 12} value{...} /翻译为 GSAP 时间线偏移cards.forEach((card, i) { const start base i * (12 / fps); // i * 0.4s at fps30 tl.to(card, { ... }, start); });在 T3 中验证三张 StatCard 以 0.0 / 0.4 / 0.8 s 错峰入场12 帧 × i / 30fps。具体落地可对照 StatCard.tsx 的local frame - delayInFrames局部帧逻辑——HF 端将这一局部时间折叠进全局时间线的偏移计算i * 12帧直接换算为i * 0.4秒。组合实践从源码到 HF 时间线的完整链路综合以上映射一个典型的移植遵循 SKILL.md 的工作流Lint 源对 Remotion 源码跑 lint_source.py拦截useState/useEffect等阻塞项详见 escape-hatch.md识别interpolate/spring/Easing/interpolateColors等需要本参考的构造规划映射根据 api-map.md 确定需要加载的专题参考——出现useCurrentFrame、interpolate、spring、Easing、interpolateColors时加载本文对应的 timing.md生成 HF 合成输出index.html包含根#stage的data-composition-id/data-start/data-duration/data-fps等属性、扁平场景列表以及一条暂停的 GSAP 时间线所有useCurrentFrame()派生都变成时间线上正确偏移的 tween参数化的 props 处理见 parameters.md验证渲染两侧基线并做 SSIM 对比阈值约为该复杂度层级 p05 之下 0.02详见 eval.md。验证命令参考 SKILL.md 的快速路径# 渲染 Remotion 基线 cd remotion-src npx remotion render CompositionId out/baseline.mp4 # 渲染 HF 翻译 cd ../hf-src npx hyperframes render --skillremotion-to-hyperframes --output ../hf.mp4 # SSIM 对比 ../../scripts/render_diff.sh ./remotion-src/out/baseline.mp4 ./hf.mp4 ./diff关键前提两侧渲染必须使用匹配的像素格式在 Remotion 源码的remotion.config.ts中设置Config.setVideoImageFormat(png)与Config.setColorSpace(bt709)否则 SSIM 差异度量的是编码器差异约 0.05 SSIM 损失而非翻译保真度。若对比失败可用 frame_strip.sh 定位具体分歧帧再回到本文对应的映射表复查。小结一份可执行的时序翻译清单把 Remotion 的帧驱动动画翻译成 HyperFrames 时间线时遵循以下核对项即可覆盖绝大多数场景单位统一所有帧号除以fps换成秒且只在翻译时换算一次线性插值默认ease: none注意extrapolateRight: clamp与 GSAP 天然一致extend需手动外推输入范围多段插值拆成多条时间线 tween偏移取各关键帧对应秒数弹簧按 spring → back.out 映射表 选取back.out参数与时长未验证组合预留约 0.05 SSIM 的偏差预算最终目视微调自定义缓动对照 缓动等价表back过冲乘 1.7bezier需 CustomEase 插件颜色/数字颜色用 GSAP 原生 tween数字滚动用计数器对象 onUpdate写textContentpower3.out精确对应 cubic ease-outstaggerdelayInFrames除以fps变为时间线偏移叠加在场景基础时间之上。所有映射均已通过 T1–T3 测试语料 的 SSIM 阈值验证可直接作为移植 Remotion 合成到 HyperFrames 的实战参考。【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考