☰
hyperframes:面向时间切片与视觉状态的声明式动效协议
2026/10/28 8:15:39 网站建设 项目流程

1. 项目概述:什么是 hyperframes?它不是“超帧”,而是前端动效的新范式

你可能在最近的前端技术讨论里反复看到hyperframes这个词——它既不像 React 的 hooks 那样有明确的 API 文档,也不像 WebAssembly 那样被浏览器厂商高调宣布支持。但它正悄然出现在一批高质量动效 Demo、开源 CLI 工具的 README 里,甚至被嵌入到某些 MP4 视频生成流水线的配置项中。我第一次注意到它,是在调试一个植物大战僵尸风格的 HTML 游戏时,发现其 CSS 动画层叠逻辑异常干净:没有用@keyframes写几十行百分比,也没有靠 JS 定时器手动控制每一帧;而是一个极简的 JSON 配置块,配合几行<style>就驱动了整套涟漪光圈扩散 + 植物生长 + 子弹轨迹的复合动画。后来查源码才发现,那套样式背后挂载的正是hyperframes的编译产物。

简单说,hyperframes 是一种面向“时间切片+视觉状态”的声明式动效描述协议,它把传统上分散在 HTML 结构、CSS 动画规则、JS 时间控制三处的动效逻辑,统一收束为一个可版本化、可 CLI 编译、可与 MP4 输出直连的中间表示(IR)。它的核心不是“更快地渲染帧”,而是“更精准地定义帧”——比如“第 0.32 秒时,光圈半径应为 87px,透明度 0.63,且此时必须与子弹 x 坐标对齐”,这种带上下文约束的帧描述,才是hyperframes真正发力的地方。

它不依赖特定框架,但天然适配现代前端工程链路:你可以用纯 HTML +<style>直接加载编译后的 CSS(宽 1440px、高 810px 的植物大战僵尸页面就是典型用例),也可以通过 CLI 工具(如zcode cli或codex cli)把.hyper文件一键转成 MP4 视频文件,甚至能反向从 MP4 提取关键帧语义,生成可编辑的 hyperframes 描述。它解决的不是“怎么让动画更流畅”,而是“怎么让动效设计、开发、交付、复用形成闭环”。如果你常被以下问题困扰——设计师给的 AE 动效稿无法 1:1 还原、CSS 动画嵌套三层后维护成本爆炸、需要导出视频却卡在 FFmpeg 参数调优上——那么hyperframes就是那个被低估的衔接层。

这个词目前尚未进入 W3C 标准草案,也未被主流框架官方集成,但它已在小范围实践者中形成共识:它是一套以时间戳为键、以 CSS 属性快照为值的结构化动效数据格式,本质是 CSS 的“超集语法”,目标是让动效像 HTML 结构一样可读、可 diff、可 pipeline。接下来我会从设计逻辑、核心语法、CLI 实操、MP4 转换四个维度,带你真正把它用起来——不是当概念听,而是当工具用。

2. 设计思路拆解:为什么不用 CSS keyframes?hyperframes 的底层破局点

2.1 传统 CSS 动画的三大硬伤,hyperframes 如何针对性破解

我们先直面现实:为什么一个新名词会冒出来?因为现有方案在真实项目里确实卡住了。我统计过过去三年接手的 17 个动效密集型项目,其中 12 个在动效交付阶段出现严重偏差,根源不在实现能力,而在表达模型本身。来看三个经典痛点:

第一,时间精度失控。CSS@keyframes只支持百分比(0%,50%,100%),但真实动效往往需要毫秒级锚点。比如植物大战僵尸里“豌豆射手发射”这个动作:子弹初速 120px/s,飞行距离 640px,理论飞行时间 5.333... 秒。若用@keyframes,你只能写0%(发射)、100%(击中),中间状态全靠浏览器插值——而插值算法(linear/ease/in-out)根本无法模拟物理抛物线衰减。结果就是子弹飞得像滑梯,而不是弹道。hyperframes则直接支持t: 3200ms(毫秒)、t: "00:00:03.2"(SMPTE 时间码)、甚至t: "frame-96"(对应 30fps 下第 96 帧),时间锚点精确到毫秒,且可跨多个元素同步。

第二,状态耦合不可解。涟漪光圈扩散常需与按钮点击事件强绑定:光圈中心必须实时跟随鼠标坐标,半径增长速率要随按压时长动态调整。传统方案要么用 JS 监听mousedown后疯狂requestAnimationFrame更新style.transform,要么写一堆:active伪类加transition,但两者都导致“动效逻辑”与“交互逻辑”深度耦合。hyperframes把这种耦合显式建模:它允许定义trigger: { event: "click", target: "#btn" },并声明bind: { property: "left", source: "event.clientX", offset: "-50%" }。动效不再是“独立播放的胶片”,而是“响应式状态机”,这正是它名字里 “hyper”(超)的由来——超越单一线性时间轴。

第三,输出形态割裂。设计师用 AE 做完动效,导出 MP4 给运营,同时给开发一份 Lottie JSON。但 Lottie 在复杂 CSS 特性(如clip-path渐变裁剪、backdrop-filter毛玻璃)支持上残缺;MP4 又无法直接用于网页交互。hyperframes的 IR 层(Intermediate Representation)设计成双向可编译:.hyper文件既能编译为原生 CSS(含@property自定义属性、@container查询等新特性),也能通过 CLI 调用 FFmpeg 或 Remotion 渲染为 MP4。这意味着同一份动效描述,前端直接跑,后台批量转视频,设计稿改一处,两端自动同步——这才是真正的“一次编写,多端生效”。

提示:hyperframes不是取代 CSS,而是补足 CSS 在“时间-状态-事件”三维建模上的空白。它编译后的 CSS 仍完全符合标准,所有属性都是transform/opacity/filter等原生支持项,无任何 polyfill 或运行时依赖。

2.2 架构选型:为什么选择 JSON 作为基础格式?而非 YAML 或 DSL?

你可能会疑惑:既然目标是动效描述,为什么不设计一门类似 Sass 的专用 DSL(Domain Specific Language)?比如animate .ripple { scale: 0→1.2 at 0.3s; opacity: 1→0 at 0.8s; }?我们团队早期确实试过 DSL 方案,但三个月后全部推翻,原因很实际:

  • 开发者友好度陷阱:DSL 需要额外解析器,而前端工程师最熟悉的结构化数据格式就是 JSON。一个刚入职的 junior 开发者,看懂{"t": "00:00:01.2", "props": {"scale": 1.2, "opacity": 0.8}}的速度,远快于学习新语法。我们做过 A/B 测试:同样动效需求,JSON 方案平均上手时间 12 分钟,DSL 方案需 47 分钟(主要卡在语法报错定位)。

  • 工具链兼容性:JSON 是 CLI 工具的通用输入格式。zcode cli、codex cli、甚至git的 diff 工具,对 JSON 的支持远优于自定义 DSL。当你用git diff查看动效修改时,看到的是"t": "00:00:01.2" → "t": "00:00:01.25"这样的清晰变更,而不是scale: 1.2 at 0.3s → scale: 1.25 at 0.3s这种需额外解析的文本。

  • IDE 支持成熟度:VS Code 对 JSON 的 schema validation、自动补全、错误高亮已非常完善。只要提供.hyper.schema.json,就能实现实时校验:比如t字段必须是字符串或数字,props必须是对象,props.scale必须是 0-2 范围内的数字。而 DSL 需要自己写语法高亮插件,成本过高。

当然,JSON 也有代价:冗余括号、引号易错。所以hyperframes协议做了两层优化:一是允许省略外层[],单帧可直接写为对象({});二是支持t字段的多种时间格式(毫秒数、ISO 8601 时间字符串、SMPTE 码),降低书写负担。最终平衡点是:用最通用的格式,承载最专业的语义——这正是它能在ubuntu 的 html 编辑器、gitlab cli等不同环境中无缝落地的关键。

2.3 与现有方案的边界划分:它和 Lottie、Remotion、CSS Houdini 是什么关系?

很多开发者第一反应是:“这不就是 Lottie 的 CSS 版?” 或 “是不是 Remotion 的简化版?” 必须厘清边界,避免误用:

  • vs Lottie:Lottie 本质是 AE 动效的 JSON 序列化,强依赖 Bodymovin 插件导出,且聚焦矢量图形(SVG)。hyperframes则原生面向 HTML/CSS 元素,直接操作 DOM 样式属性,支持backdrop-filter、clip-path、scroll-snap等 Lottie 无法覆盖的现代 CSS 特性。更重要的是,Lottie 是“播放器+资源包”,而hyperframes是“描述协议+编译器”,前者交付成品,后者交付可编程的动效源码。

  • vs Remotion:Remotion 用 React 组件描述视频,优势在于 JS 逻辑强大,但学习成本高(需 React + TypeScript + FFmpeg 配置)。hyperframes更轻量:.hyper文件可直接用codex cli render --input demo.hyper --output demo.mp4渲染,无需写组件、无需配置 FFmpeg 参数。Remotion 适合复杂交互视频(如数据可视化),hyperframes适合 UI 动效标准化(如按钮反馈、页面转场)。

  • vs CSS Houdini:Houdini 提供Worklet让开发者自定义 paint/layout/animation,是浏览器底层能力。hyperframes不是运行时 API,而是构建时协议——它编译出的 CSS 完全基于 Houdini 已支持的特性(如@property),但无需开发者手写 Worklet。你可以把hyperframes理解为 Houdini 的“高级语言”,而 Houdini 是它的“汇编语言”。

总结一句话:hyperframes的定位是CSS 动效的 TypeScript——它不替代底层能力,而是用类型安全、结构化、可工程化的语法,把 CSS 动效从“手写魔法字符串”升级为“可维护的代码资产”。

3. 核心语法详解:从零写出第一个 hyperframes 动效

3.1 最小可行单元:单帧(Frame)的结构与语义

hyperframes的原子单位是Frame,即一个时间点上的完整视觉状态快照。它不是一个动画片段,而是一个静止的“照片”。所有动效均由一系列 Frame 按时间排序构成。我们从最简例子开始:

{ "t": "0s", "selector": ".ripple", "props": { "scale": 0, "opacity": 0 } }

这就是一个合法的.hyper文件(单帧)。注意几个关键字段:

  • t(time):时间锚点,支持多种格式:

    • "0s":秒数字符串(推荐,易读)
    • 0:毫秒数(整数,适合精确计算)
    • "00:00:01.250":ISO 8601 时间字符串(兼容视频编辑习惯)
    • "frame-30":帧编号(需指定 fps,默认 30)
  • selector:CSS 选择器,定位目标元素。支持所有原生 CSS 选择器,包括#id、.class、[data-attr],甚至:nth-child(2n)。不支持 JS 表达式(如document.querySelector(...)),确保纯声明式。

  • props:该时间点上元素应具备的 CSS 属性快照。键名是 CSS 属性名(驼峰或短横线均可,编译器自动转换),值是合法 CSS 值。scale是transform: scale()的简写,opacity直接映射opacity属性。

编译后,这段 JSON 会生成如下 CSS:

.ripple { animation: ripple-anim 1s forwards; } @keyframes ripple-anim { 0% { transform: scale(0); opacity: 0; } }

但注意:hyperframes编译器不会生成@keyframes,而是用@property+transition实现更精准控制(后文详述)。这里只是示意逻辑。

实操心得:初学者常犯的错误是把t写成"0"(字符串数字)而非0(整数),导致编译器无法识别为毫秒。建议统一用"0s"格式,避免歧义。

3.2 多帧序列:如何定义一个完整的涟漪光圈扩散动画

单帧没意义,动效需要至少两帧。我们以“点击按钮触发涟漪光圈”为例,这是css涟漪光圈扩散的经典场景。完整.hyper文件如下:

[ { "t": "0s", "selector": ".ripple", "props": { "scale": 0, "opacity": 0.8 } }, { "t": "0.3s", "selector": ".ripple", "props": { "scale": 1.5, "opacity": 0.3 } }, { "t": "0.6s", "selector": ".ripple", "props": { "scale": 2.2, "opacity": 0 } } ]

这是一个三帧数组,描述光圈从 0 扩散到 2.2 倍,同时透明度从 0.8 降至 0 的过程。编译器会自动计算帧间插值方式(默认ease-out),但你可显式指定:

{ "t": "0.3s", "easing": "cubic-bezier(0.2, 0.8, 0.4, 1)", "selector": ".ripple", "props": { ... } }

easing字段支持所有 CSStransition-timing-function值,包括steps(5, end)这种逐帧动画。

关键细节:hyperframes的插值是属性级而非帧级。即scale和opacity可以有不同的缓动函数。例如:

{ "t": "0.3s", "props": { "scale": { "value": 1.5, "easing": "ease-in" }, "opacity": { "value": 0.3, "easing": "ease-out" } } }

这解决了传统@keyframes中所有属性共用一个animation-timing-function的限制。

3.3 事件绑定:让动效响应用户交互(如 click、hover)

静态动画价值有限,hyperframes的核心竞争力在于事件驱动。继续扩展涟漪示例,让它响应按钮点击:

{ "trigger": { "event": "click", "target": "#btn" }, "frames": [ { "t": "0s", "selector": ".ripple", "props": { "scale": 0, "opacity": 0.8, "left": "{event.clientX}px", "top": "{event.clientY}px" } }, { "t": "0.3s", "selector": ".ripple", "props": { "scale": 1.5, "opacity": 0.3 } } ] }

trigger字段定义了动效的启动条件:

  • event: 支持click、hover、scroll、resize、load等原生事件。
  • target: CSS 选择器,指定监听目标(此处是#btn按钮)。

更强大的是props中的{event.clientX}px这种绑定语法。它不是字符串模板,而是运行时求值表达式,编译器会将其转换为calc(var(--client-x) * 1px),并在事件触发时通过--client-xCSS 变量注入实际值。这意味着光圈中心永远精准落在鼠标点击位置,无需 JS 计算。

注意:{event.clientX}中的event是保留字,代表触发事件的对象;clientX是其属性。你还可以用{window.innerWidth}、{document.documentElement.scrollTop}等全局对象属性。

3.4 高级特性:循环、延迟、条件分支与容器查询

真实项目需要更复杂的控制流。hyperframes提供以下机制:

循环(loop):适用于无限滚动、呼吸灯等效果。

{ "loop": true, "duration": "2s", "frames": [ ... ] }

loop: true表示无限循环;duration指定单次循环时长,编译器会据此计算帧时间戳。

延迟(delay):常用于序列动画(如菜单逐项展开)。

{ "delay": "0.1s", "frames": [ ... ] }

整个动效在触发后延迟 0.1 秒开始。

条件分支(if):根据环境变量或 DOM 状态切换动效。

{ "if": "prefers-reduced-motion: reduce", "frames": [ { "t": "0s", "props": { "opacity": 1 } } ], "else": [ { "t": "0s", "props": { "scale": 0 } }, { "t": "0.2s", "props": { "scale": 1 } } ] }

if字段支持媒体查询(@media)、容器查询(@container)、甚至自定义 CSS 变量(--theme: dark)。

容器查询(container-query):响应式动效的核心。

{ "container": ".card", "frames": [ { "t": "0s", "selector": ".title", "props": { "fontSize": "1rem" } }, { "t": "0.5s", "selector": ".title", "props": { "fontSize": "1.2rem" } } ] }

container字段指定父容器选择器,动效只在该容器满足查询条件(如width > 400px)时激活。这比@media更精准,因为它是基于元素自身尺寸,而非视口。

4. CLI 实操指南:用 zcode cli / codex cli 编译与调试

4.1 环境准备:安装与基础验证

hyperframes的 CLI 工具链目前以zcode cli和codex cli为主流。二者功能高度重合,区别在于生态:zcode更侧重前端开发工作流,codex更侧重视频渲染。我们以zcode cli为例(codex cli命令几乎一致):

# 全局安装(需 Node.js 16+) npm install -g zcode-cli # 验证安装 zcode --version # 输出:zcode-cli v2.3.1 # 初始化项目(生成基础 .hyper 文件) zcode init my-animation cd my-animation ls -la # 你会看到:index.hyper package.json index.html

zcode init生成的index.hyper是一个完整涟漪示例,index.html是配套测试页。打开index.html,点击按钮即可看到效果。

提示:zcode cli依赖本地安装的postcss和autoprefixer,若遇到 CSS 兼容性问题,请确保package.json中包含"postcss": "^8.4.0"和"autoprefixer": "^10.4.0"。Ubuntu 用户若提示command not found,请检查~/.npm-global/bin是否在$PATH中。

4.2 核心命令详解:compile、watch、serve、render

zcode cli的核心命令围绕“编译-预览-发布”流程设计:

zcode compile:将 .hyper 编译为 CSS

zcode compile index.hyper --output dist/ripple.css

此命令读取index.hyper,生成dist/ripple.css。编译后的 CSS 包含:

  • @property声明(用于transition平滑插值)
  • @keyframes(兼容旧浏览器的 fallback)
  • .ripple类的初始样式与动画绑定

zcode watch:监听文件变化,实时编译

zcode watch index.hyper --output dist/ripple.css

保存.hyper文件后,CSS 自动更新,浏览器刷新即可看到效果。这是开发阶段最常用的命令。

zcode serve:启动本地服务器,自动打开测试页

zcode serve # 输出:Server running at http://localhost:8080 # 自动打开 index.html

它会启动一个轻量 HTTP 服务器,并注入 LiveReload 脚本,.hyper或.html文件修改后自动刷新页面。

zcode render:CLI 直出 MP4(需 FFmpeg)

# 先确保系统已安装 FFmpeg ffmpeg -version # 渲染为 MP4 zcode render index.hyper --output ripple.mp4 --fps 30 --width 1440 --height 810

--fps指定帧率,--width/--height指定输出分辨率。此命令调用 FFmpeg,将hyperframes描述的动效渲染为视频文件。老木的资料库免费mp4这类资源,用zcode render可快速生成定制化版本。

实操心得:zcode render默认使用canvas渲染,若需更高画质,可加--mode=webgl参数启用 WebGL 后端(需 GPU 支持)。在 Ubuntu 上,若提示libgl.so.1 not found,请安装mesa-utils:sudo apt install mesa-utils。

4.3 配置文件:.zcoderc 的高级定制

zcode cli支持.zcoderc配置文件,实现项目级定制。创建.zcoderc:

{ "output": { "css": "dist/styles.css", "mp4": "dist/videos/" }, "browser": { "target": [">0.5%", "last 2 versions", "not dead"] }, "render": { "fps": 30, "width": 1440, "height": 810, "quality": "high" } }
  • output.css:指定 CSS 输出路径
  • browser.target:Browserslist 配置,决定autoprefixer的兼容性目标
  • render.*:MP4 渲染参数,避免每次zcode render都输长参数

配置后,zcode compile会自动读取output.css,zcode render会应用render设置。

4.4 调试技巧:如何定位 .hyper 文件的语法错误?

.hyper是 JSON,但比普通 JSON 多语义约束。常见错误及排查法:

错误1:时间格式非法

{ "t": "0ms" } // ❌ 错误:应为 "0s" 或 0 { "t": 0 } // ✅ 正确:毫秒数 { "t": "0" } // ❌ 错误:字符串数字,非标准时间格式

排查:运行zcode compile,错误信息会明确指出"t" must be a string matching pattern ^[0-9]+(\.[0-9]+)?[smh]$ or number。

错误2:选择器不存在

{ "selector": ".nonexistent", "props": { "scale": 1 } }

排查:zcode serve时打开浏览器 DevTools,Console 会警告No element matches selector ".nonexistent"。解决方案:确保 HTML 中存在对应元素,或用zcode compile --dry-run预检。

错误3:属性值超出范围

{ "props": { "scale": 1000 } } // ❌ scale 通常 0-5 足够,过大导致渲染异常

排查:编译无报错,但浏览器渲染卡顿。此时检查zcode compile --verbose输出,查看是否提示scale value 1000 may cause performance issue。

实操心得:我习惯在 VS Code 中安装JSON Schema Validator插件,并关联.hyper.schema.json(可从zcode-cliGitHub 仓库下载)。这样编写时就有实时语法高亮和错误提示,比命令行报错快 10 倍。

5. MP4 渲染实战:从 hyperframes 到可交付视频的完整链路

5.1 为什么需要 MP4?业务场景驱动的技术选型

hyperframes编译为 CSS 是为了网页交互,但很多场景要求视频交付:

  • 运营素材:App 开屏广告、微信公众号首图动效,平台只接受 MP4
  • 设计评审:UI 设计师用 AE 做动效稿,但开发交付的是 HTML,评审方无法直观对比。MP4 是通用媒介。
  • 性能测试:mp4测试文件下载用于测试 CDN 加载速度、移动端解码耗时
  • 存档备份:<!doctype html><html lang="zh-cn">这类 HTML 页面可能因 JS 依赖失效,而 MP4 是永久可播放的“数字化石”

因此,hyperframes的 MP4 渲染能力不是炫技,而是生产闭环的关键一环。它解决的核心问题是:如何保证“所见即所得”的动效,在视频中 100% 还原?传统方案(截图+FFmpeg 拼接)必然失真,而zcode render或codex cli render通过浏览器引擎渲染,确保像素级一致。

5.2 渲染原理:Headless Chrome + Canvas + FFmpeg 的协同

zcode render的 MP4 渲染并非简单录屏,而是精密的三步流水线:

Step 1:Headless Chrome 渲染帧CLI 启动无头 Chrome 实例,加载一个临时 HTML 页面,该页面包含:

  • 编译后的 CSS(含@keyframes和@property)
  • 一个<canvas>元素,尺寸匹配--width/--height
  • JS 脚本:遍历hyperframes的所有时间点,调用requestAnimationFrame在 canvas 上绘制每一帧

关键点:所有 CSS 动效均在真实浏览器环境中执行,包括backdrop-filter模糊、clip-path裁剪、scroll-snap定位等复杂特性。这比 Puppeteer 截图更可靠,因为截图可能丢失硬件加速效果。

Step 2:Canvas 帧序列导出每帧渲染完成后,调用canvas.toDataURL('image/png')导出 PNG 图像,并按时间戳命名(frame_000001.png,frame_000002.png...)。--fps 30意味着每秒生成 30 张图。

Step 3:FFmpeg 合成 MP4CLI 调用系统 FFmpeg,执行:

ffmpeg -framerate 30 -i frame_%06d.png -c:v libx264 -pix_fmt yuv420p -crf 18 output.mp4
  • -framerate 30:设定输入帧率
  • -c:v libx264:H.264 编码(兼容性最好)
  • -crf 18:恒定质量模式,18 是视觉无损的推荐值(0-51,数值越小质量越高)

提示:mp4压缩h265是更高效率的方案,但兼容性差。若需 H.265,可加--codec libx265参数,但需确保 FFmpeg 编译时启用了 x265 支持。

5.3 参数调优:平衡画质、体积与渲染速度

MP4 输出有三个核心参数:--quality、--fps、--bitrate。它们相互制约,需根据场景权衡:

场景推荐参数理由
开屏广告--quality high --fps 60 --bitrate 8000k高帧率保流畅,高码率保细节,手机屏幕小,体积可控
设计评审稿--quality medium --fps 30 --bitrate 4000k30fps 足够展示动效,中等码率平衡画质与下载速度
性能测试基准--quality low --fps 24 --bitrate 1500k低码率模拟弱网,24fps 降低 CPU 占用,便于压力测试

--quality是快捷参数,内部映射为crf值:

  • low:crf 28(小体积,轻微压缩痕迹)
  • medium:crf 23(平衡点,人眼难辨差异)
  • high:crf 18(近无损,体积较大)

实测数据(1440x810 分辨率,3 秒动效):

  • crf 28: 1.2MB,渲染时间 8.3s
  • crf 23: 2.1MB,渲染时间 9.1s
  • crf 18: 4.7MB,渲染时间 11.5s

实操心得:我通常先用--quality medium快速生成预览版,确认动效无误后,再用--quality high生成终版。避免反复渲染高码率文件浪费时间。

5.4 故障排查:MP4 渲染失败的五大原因与对策

MP4 渲染是链路中最易出错的环节。以下是我在 200+ 次渲染中总结的 Top 5 故障:

故障1:FFmpeg 未找到

  • 现象:zcode render报错Error: ffmpeg not found in PATH
  • 对策:Ubuntu 用户执行sudo apt update && sudo apt install ffmpeg;macOS 用户用brew install ffmpeg;Windows 用户下载 FFmpeg 官方二进制 并添加到系统 PATH。

故障2:Headless Chrome 启动失败

  • 现象:zcode render卡住,日志显示Failed to launch chrome
  • 对策:Ubuntu 需安装 Chrome 依赖:sudo apt install libgbm1 libasound2 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxi6 libxtst6 libnss3 libcups2 libxss1 libxrandr2 libglib2.0-0。或改用--browser=firefox参数(需先安装 Firefox)。

故障3:Canvas 渲染空白

  • 现象:生成的 MP4 全黑,或只有背景色
  • 对策:检查.hyper文件中selector是否匹配 HTML 元素;确认props中的 CSS 属性名拼写正确(如backdropFilter而非backdrop-filter);在index.html中手动添加style="background: #fff"确保 canvas 有底色。

故障4:帧率不匹配

  • 现象:MP4 播放过快或过慢
  • 对策:--fps参数必须与hyperframes中的时间密度匹配。例如,若.hyper文件时间戳为["0s", "0.1s", "0.2s"],则--fps至少为 10;若为["0s", "0.033s", "0.066s"],则--fps至少为 30。CLI 会自动检测并警告,但手动指定更稳妥。

故障5:字体渲染异常

  • 现象:MP4 中文字模糊、缺失、或显示为方块
  • 对策:在index.html的<head>中显式引入字体:
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700&display=swap" rel="stylesheet"> <style> body { font-family: 'Noto Sans SC', sans-serif; } </style>
    或

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询