
HyperFrames 停止运动节奏原语解析用步进时间律实现确定性逐帧定格动画【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes导读本文深入解析 HyperFrames 仓库中stop-motion-cadence这一视频运动原语motion primitive它以先量化、再求值的步进时间律stepped-time law为唯一驱动让四个纸剪 token 形状按节拍依次抛出落地、压扁回弹并叠加 2 帧沸腾抖动与星光点缀还原传统定格动画stop-motion的手工逐帧质感。读完本文你将掌握该原语的全部四个变量、标准挂载方式以及它是如何从源码层面满足 HyperFrames 的确定性渲染契约的——这套单一驱动 全量派生的模式可直接复用到你自己的逐帧动画组件中。该组件是 Wave M10 实验的一个演示原语参考了 MotionMarkus 定格动画分镜表仓库中以 README、组件 HTML、注册元数据 和 演示页 四个文件完整呈现。核心思想先量化再求值The Law整个组件只有一个时间驱动每一帧先把时间轴时间量化成离散步进时间ts再用ts去驱动所有运动ts floor(t * fps) / fps在 stop-motion-cadence.html 的applyTime()中这一法则被逐字实现var step Math.floor(timeSeconds * fps 1e-6); var ts step / fps; var boilIdx Math.floor(step / 2);step是整数帧索引ts是量化后的步进时间末尾的1e-6微小偏移用于吸收 GSAP seek 往返的浮点误差保证正向、反向或乱序 seek 落在步进边界时量化结果一致沸腾种子boilIdx同样由步进索引派生即floor(step / 2)的两帧窗口。因为每一次落地命中hit都被定义为整数步索引landStep round(t_land * fps)压扁是step - landStep的逐帧包络沸腾种子哈希自floor(step / 2)星光仅在0 step - landStep life时可见——所有状态都派生自同一个量化驱动因此任意顺序的 seek前进、后退、打乱都会落在完全相同的帧上。这正是 docs/concepts/determinism.mdx 所要求的渲染契约同样的输入永远产出同样的像素。四个变量节奏、沸腾、主色与出场组件通过data-composition-variables声明了四个枚举变量见 registry-item.json 与 HTML 头部声明idtypedefault说明fpsenum10步进节奏可选8、10、12帧每秒boilenumon2 帧边缘抖动种子哈希自floor(step / 2)off时完全静止accentenumgreen主形状颜色green 使用--brandblue 使用--accentviolet 使用--accent-2其余形状按明度阶梯区分而非换色相exitenumnone出场方式none保持到硬切fade仅透明度淡出up向上移出在源码中变量通过window.__hyperframes.getVariables()读取并做防御性归一化见 stop-motion-cadence.htmlfps只在严格等于8或12时生效否则回落10boil只要不等于off就开启exit仅接受fade或up。主色通过 CSS 变量注入root.style.setProperty(--smc-c1, accentColors[accent]); root.style.setProperty(--smc-c2, color-mix(in srgb, var(--fg, #f8fafc) 72%, transparent)); root.style.setProperty(--smc-c3, color-mix(in srgb, var(--fg, #f8fafc) 45%, transparent));这样组件能无缝继承宿主项目已有的设计 token--brand、--accent、--accent-2符合 docs/concepts/variables.mdx 中变量改变内容、不改变视口与帧率的边界约定——注意fps虽是变量但它只作用于组件内部的量化网格并不改变项目渲染帧率。挂载方式弹性盒子 字面量时间轴键组件以 template 包裹、#root填满宿主裁剪框的方式挂载不声明data-width/data-height弹性根内部使用container-type: size与cqmin容器查询单位自适应任意盒尺寸。标准挂载片段来自 READMEdiv classclip >var throws [ { t0: 0.15, t1: 1.0, from: { x: -0.12 * W, yB: 0.28 * H }, to: 0.3 * W, arc: 0.3 * H, rot0: -170, rot1: 8, squash: 0.3, life: 2 }, { t0: 0.6, t1: 1.5, from: { x: 1.12 * W, yB: 0.2 * H }, to: 0.56 * W, arc: 0.34 * H, rot0: 150, rot1: -6, squash: 0.34, life: 3 }, { t0: 1.25, t1: 2.0, from: { x: 0.78 * W, yB: -0.12 * H }, to: 0.72 * W, arc: 0.06 * H, rot0: -120, rot1: 5, squash: 0.26, life: 2 }, { t0: 1.8, t1: 2.55, from: { x: -0.08 * W, yB: 0.1 * H }, to: 0.43 * W, arc: 0.4 * H, rot0: 200, rot1: -12, squash: 0.22, life: 3 }, ];每次抛出的t1 * fps经四舍五入得到整数landStep压扁包络按落地后的步数查表见 stop-motion-cadence.htmlvar SQUASH_ENV [1, 0.55, -0.3, 0.1, 0]; // 命中、深压、回弹拉伸、稳定、归零 function squashAt(stepsSince, amount) { if (stepsSince 0) return 0; if (stepsSince SQUASH_ENV.length) return 0; return SQUASH_ENV[stepsSince] * amount; }压扁效果依赖两个实现细节transform-origin: 50% 100%形状以底部触地点为原点缩放落地时向地面压缩scaleX增大、scaleY缩小产生压进地面的物理感接触阴影每个形状配一个椭圆阴影元素随形状接近地面而变大变暗落地后跟随压扁同步缩放强化撞击感。沸腾抖动与星光纯函数化的手工质感**2 帧沸腾boil**是定格动画的标志性质感——同一张纸片在两帧间轻微颤抖。组件用确定性哈希代替随机数见 stop-motion-cadence.htmlfunction rnd(n) { var x Math.sin(n * 127.1 311.7) * 43758.5453; return x - Math.floor(x); }每次更新时以boilIdx * k i * m为种子的 sin-fold 哈希产出 x/y 偏移与旋转抖动种子是纯时间的函数且在一个 2 帧窗口内恒定因此同一帧无论被求值多少次都得到同一份抖动。boil: off时抖动归零组件在 HOLD 阶段完全静止。星光点缀精确存活 2 或 3 步由life决定并按帧交替大/小缩放与 0°/45° 旋转模拟手绘闪烁var d step - th.landStep; if (d 0 d th.life) { gsap.set(sp, { x: xC side * (sw * 0.62) - 0.0275 * M, y: groundY - sh * 0.9, scale: d % 2 0 ? 1 : 0.62, rotation: d % 2 0 ? 0 : 45, opacity: 1, }); }时间包络固定 IN/OUT 弹性 HOLD组件的时间包络在源码注释与实现中均有明确说明见 stop-motion-cadence.html 与 L265-L273IN_BASE 3.0s四个形状全部落地并恢复HOLD max(0, D - IN - OUT)弹性保持段——沸腾仍持续呼吸boil: off则死静OUT_BASE 0.45s仅当exit ! none时存在若挂载时长短于 3 秒编排抛出时间会被压缩在一起但 fps 网格本身永不缩放——量化作用于绝对时间节奏是绝对的。这个固定 IN/OUT 弹性 HOLD、永不动 timeScale的包络策略配合一个覆盖[0, D]的惰性锚点 tweentl.to({ p: 0 }, { p: 1, duration: duration, ease: none }, 0)保证每次事件化 seek 都会触发onUpdate回调去调用applyTime(tl.time())同时 HOLD 不会被提前截断。确定性保证无随机、无时钟、无增量状态从源码可以确认该组件的三条确定性铁律无Math.random唯一随机源是 sin-fold 整数哈希rnd(n)无墙钟一切运动由tl.time()派生时间轴为paused: true只 seek 不播放符合 docs/concepts/determinism.mdx 中渲染永不播放视频的原则无增量状态舞台尺寸仅在挂载时测量一次stage.clientWidth/clientHeight每次更新的写入只有transform与opacity通过gsap.set全部由当前时间重新计算。因此任意顺序的帧求值都得到逐位一致的像素这也使得该原语可以直接进入自动化流水线与 CI 测试而无需担心输出漂移。注册元数据与使用场景registry-item.json 将组件标记为hyperframes:component、family: demonstrate、profile: stepped-time标签包括motion-primitive、time-law、stop-motion、stepped、boil、deterministic、experiment并声明了一个同步点syncPoints: [{ id: first-hit, phase: in, offset: 1.0 }]——即第一次落地命中位于入场后 1.0s可供宿主在剪辑时对齐音乐重拍或字幕卡点。典型用法作为剪辑库中的演示性素材jobs 为demonstrate比如音乐卡点视频的章节开篇、定格动画风格的转场点缀或作为学习确定性逐帧动画的参考实现。使用时只需按上文 Mount 片段挂载并通过data-variable-values覆盖fps、boil、accent、exit即可得到 8/10/12 fps 三种节奏、有无沸腾、三种主色与三种出场方式的组合变体——同一份 HTML 源、同一时间轴键每次挂载获得不同的最终画面这正是 HyperFrames 组合与变量体系docs/concepts/compositions.mdx所倡导的一份源码、多处复用。【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考