HyperFrames motion-graphics 路线:用 HTML 制作 10 秒内的设计主导运动图形
【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes
导读:motion-graphics是 HyperFrames 路由体系中的一条专职工作流,面向"运动即信息"的短视频单元——动态字排(kinetic type)、数字滚动、图表冲击、Logo 片尾、标题动画、下三分之一字幕条、地图动效与真实素材融合镜头。本文将围绕这条路线的输入/输出契约与访谈规则展开,并结合skills/motion-graphics工作流的分类体系、七步执行管线与源码级约束,说明如何从一句触发语到一份可渲染的 MP4 或透明覆盖层。
路线契约:输入、输出与触发词
HyperFrames 的路由体系为每条工作流维护一个小型契约文件,供路由层在惰性安装工作流技能之前读取。motion-graphics路线的契约记录在 routes/motion-graphics.md,其定义如下:
- 输入(Input):一个短的设计主导单元,通常小于 10 秒,无旁白,运动本身就是信息。典型形态包括:kinetic type(动态字排)、统计数字滚动(stat/count-up)、图表冲击(chart hit)、Logo 片尾(logo sting)、动画标题、下三分之一字幕条(lower-third)、地图动效、推文/标题/网页高亮,以及素材融合镜头(asset-fusion)。
- 输出(Output):一个短 MP4,或带透明通道的 alpha WebM/MOV 覆盖层。
- 触发词(Triggers):"an 8s logo sting"(一个 8 秒 Logo 片尾)、"animate this stat"(让这个数字动起来)、"kinetic-type intro"(动态字排开场)、"animate this title"(让这个标题动起来)、"transparent lower-third overlay"(透明下三分之一覆盖层)。
工作流技能层面的完整描述与上述契约一致并做了扩充:motion-graphics/SKILL.md 将其归纳为"短、设计主导、无旁白、运动即信息(通常 <10s,最长约 30s)、无配音、无真人主体;输出 MP4 或透明覆盖层;更长/有旁白/多场景 →/general-video"。
为什么它是一条独立路由
在 HyperFrames 的创作路由表中,hyperframes/SKILL.md 的## 2. Route fresh creation表按优先级匹配交付物而非措辞,motion-graphics排在第六位:
| 优先级 | 请求特征 | 工作流 |
|---|---|---|
| 6 | 创建明确的短、无旁白、运动优先单元,通常 <10s | /motion-graphics |
同表还给出了消歧规则,直接划定了这条路线的边界:
- 当单元无旁白且运动即信息时,短动画标题、Logo 片尾、统计冲击、图表冲击、地图冲击或独立下三分之一 →
/motion-graphics;静态标题卡、有旁白序列、较长蒙太奇或自定义循环 →/general-video。 - 明确的短运动图形可以使用 URL、推文、文章或截图作为素材来源;而泛化的"把这个网站做成视频"请求 →
/product-launch-video。
在 capability-menu.md 的能力菜单中,"真实地图场景(Real map scenes)"一行将地图能力的主场明确挂靠在motion-graphics下:通过grounding/locate.mjs(地理编码)与categories/maps/(含bake-basemap.mjs)得到"确定性烘焙底图 + 定位标记"。
访谈规则:自主设计的边界
与动辄多轮提问的叙述型路线不同,motion-graphics的访谈条目 routes/motion-graphics.md 明确规定:
- 天然自主(Autonomous by design):整个流程中至多一个问题,且该问题由 director 步骤拥有。除确认输入外没有任何 must-have;确认后直接路由。
- Run-shape:两者皆非——成片只有几秒,storyboard(分镜板)与 companion 会话(共作模式)对此毫无增益。
- Front-door capability offer:跳过——director 的"一问题"上限具有权威性,前端能力推荐轮被整体略过。
这与 intent-interview.md 第 7 步"当所选路线文件要求跳过前端能力推荐时,跳过此步"的规则相互印证。工作流执行层面,motion-graphics/SKILL.md 亦声明:意图层直接路由至此,不做 run-shape 提问;渲染仍由用户把关——校验与证明快照通过后,必须询问"先预览还是直接渲染?"(问题原文规范见../hyperframes-core/references/brief-contract.md)。
分类体系:先决定"是否需要搜索"
motion-graphics工作流的第一步决策是这个镜头是否需要搜索,该分叉将全部类别一分为二(motion-graphics/SKILL.md)。
形式类别(Form categories)——无需搜索,内容由用户提供:
| 类别 | 意图 | 依赖 |
|---|---|---|
kinetic-type | 有力的台词/引言/标题,文字优先的运动 | caption-*系列 block + 动画规则 |
stat | 单一英雄数字 / 滚动计数 + 圆环 | apple-money-count/rules/{counting-dynamic-scale, stat-bars-and-fills} |
charts | 由数据驱动的柱/线/饼/竞赛/百分比 | data-chartblock |
logo-reveal | Logo 片尾 / 品牌锁版(用户提供 Logo) | logo-outro/rules/svg-path-draw |
lower-thirds | 姓名/标题条、标注、社交覆盖层 | caption-*+ registry 覆盖层 block |
maps | 地理动效——高亮区域、连接地点、缩放到位置(矢量车道或烘焙底图车道) | us-map/world-map家族 +bake-basemap.mjs |
搜索驱动类别(Search-driven categories)——先搜索,再按内容类型动画(RWA 路径):
| 返回内容 | 类别 | 动画方式 |
|---|---|---|
| 网页 / 链接 | webpage | 网页/UI 动画(滚动、揭示、光标、标注) |
| 新闻文章 | news | 标题揭示 + 来源卡片 + 关键事实标注 |
| 推文 | tweet | 动画推文卡片 |
| 图片 / 实体 | asset-fusion | 素材的几何形状变成图表(RWA 叙境融合) |
纯代码/文字类别(如kinetic-type、多数charts/stat)的asset_needs为空,直接从计划跳到设计;只有声明了素材的类别才走素材获取阶段。
七步执行管线
motion-graphics/SKILL.md 以阶段表定义了完整管线,所有产物写入videos/<project-name>/:
| 阶段 | 执行者 | 主产物 |
|---|---|---|
| init | Bash | hyperframes.json |
| plan | 子代理——先决定"是否搜索" + 分类 + 素材策略 | shot-plan.json(草稿) |
| source ◇ | Bash——media-use 解析(asset_needs为空则跳过) | assets/+assets/index.md |
| design | 子代理——围绕已解析素材设计镜头 | shot-plan.json(最终版) |
| build | 子代理——复用优先的合成 | compositions/index.html |
| verify | Bash——lint、check、证明快照;失败则修复 | snapshots/contact-sheet.jpg |
| approve | 询问预览还是渲染;等待回答 | 明确的渲染批准 |
| render | Bash——hyperframes render | renders/video.mp4或透明覆盖层 |
Step 0 — 初始化
项目目录使用用户给定的目录名,否则用意图生成短横线命名(<subject>-motion)。仅当$PROJECT_DIR/hyperframes.json不存在时:
PROJECT_DIR="${MOTION_GRAPHICS_DIR:-videos/<project-name>}" mkdir -p "$(dirname "$PROJECT_DIR")" npx hyperframes init "$PROJECT_DIR" --non-interactive --example=blank --skill=motion-graphics约束:绝不在工作区根目录执行hyperframes init;绝不在PROJECT_DIR内嵌套另一个hyperframes/;每条 Bash 命令都以(cd "$PROJECT_DIR" && ...)子 shell 形式执行。
Step 1 — 计划(Director 第一部分)
派发一个子代理(prompt 为完整agents/director.md+ 派发上下文),其任务:
- 决定是否需要搜索:不需要 → 选形式类别(内容用户提供,
asset_needs: []);需要 → 在asset_needs[]中输出搜索计划(news/web/tweet/image 双极查询),具体搜索驱动类别由 Step 2 返回的内容类型确认。 - 写出草稿
shot-plan.json(信封 + 已选形式类别或搜索意图 +asset_needs+ 一段镜头简介),schema 见 shot-plan-ir.md。
Step 2 — 素材获取 ◇(Bash,条件执行)
若asset_needs非空,通过 media-use 解析素材(搜索/生成/抓取 → 冻结的项目本地路径 + 台账)。若为空,直接跳到 Step 3。搜索/提供商不可用时优雅降级:类别回退为无素材模式并记入context.log。
Step 3 — 设计(Director 第二部分)
派发子代理,围绕可用素材设计镜头:挑选 catalog block +hyperframes-animation规则/蓝图、布局、运动、节拍;对asset-fusion还需产出element_positions与取色板。最终确定shot-plan.json(content.block+content.customize+ 各类别专属content)。Director 的设计启发式(agents/director.md)强调:运动即信息,钩子在约前 0.5 秒内落地;一个主导母题;超过约 2.5 秒需做模式打断(只改变一件事);关键元素保持可读 ≥ 约 0.3 秒;节拍可提前约 0.1 秒以获得感知同步。
Step 4 — 构建(Builder,复用优先)
派发子代理,复用优先:npx hyperframes add <block>后就地定制,仅手写 gap 与 asset-fusion 的 affordance 绑定。输出compositions/index.html,须遵守 HyperFrames 契约:暂停的 GSAP 时间线挂在window.__timelines、class="clip"+ 稳定 id、tl.seek(0)、确定性。
Step 5 — 校验
(cd "$PROJECT_DIR" && npx hyperframes lint .) (cd "$PROJECT_DIR" && npx hyperframes check .) (cd "$PROJECT_DIR" && npx hyperframes snapshot --at <proof-times>)证明时间点需覆盖开场状态、标志性动作与最终定格。检查生成的 contact/snapshot 图。任一关卡失败则派发修复子代理(agents/finalize.md)做一轮就地修复后重跑失败关卡;绝不通过修改固定时长来掩盖缺陷。
Step 6 — 批准与渲染
问一个问题:"先预览还是直接渲染?"选预览则打开 Studio:
(cd "$PROJECT_DIR" && npx hyperframes preview --background)获得明确渲染许可后才执行:
(cd "$PROJECT_DIR" && npx hyperframes render . --skill=motion-graphics -q high -o ./renders/video.mp4) # 透明覆盖层变体:--format webm (或 mov)续跑表
管线支持从任意中断点续跑(motion-graphics/SKILL.md## Resume table):无shot-plan.json→ Step 1;有asset_needs无assets/→ Step 2;shot-plan.json已定稿无compositions/index.html→ Step 3/4;index.html存在但无证明快照 → Step 5;校验通过但无已批准渲染 → Step 6;已批准渲染存在 → 校验输出后汇报。
类别模块的纵深实现
每个类别对应categories/<id>/module.md(规划 + 构建规则)。以下为仓库中已确认的类别实现要点。
kinetic-type:文字即主角
kinetic-type/module.md 规定样式优先:若项目有frame.md/design.md/DESIGN.md(优先级frame.md→design.md→DESIGN.md),必须读取并使用其精确调色板/字体/约束;无规格时选择命名样式或提问。文案按意义/气息切分为场景(英文约 3–7 词、中文约 4–12 字),标记Hook → Build → Punch → Resolve;每场景 1–2 个emphasis_words,配emotion+motion+beats。构建时优先选用 18 个caption-*block 之一(如caption-kinetic-slam、caption-editorial-emphasis),否则手写:一个全时长.clip、每场景一个 flex 居中的.group、场景入场用显式gsap.fromTo()。
stat:单一英雄数字
stat/module.md:内容为{ value, prefix ($), suffix (% / x / K-M-B), label, ring },约 4–6 秒。优先复用apple-money-count(金融风:$ 计数器 + 绿色闪光 + 金币爆发 + SFX),否则手写:计数滚动由时间线驱动——用onUpdate将代理对象{v:0}补间到目标并写出格式化数字(可 seek 安全,绝不使用 setInterval/墙钟);font-variant-numeric: tabular-nums;减速缓动,约 1.2–1.6 秒后定格终值;圆环经stroke-dashoffset与计数同步完成;标签在数字落地之后淡入(先值后义)。
charts:一个图表,一条信息
charts/module.md:内容为{ type: bar|line|pie|race|pct, data[], labels[], headline, axes },race类型要求累计/分阶段数据。复用data-chart(动画柱+线、交错揭示、数值标签),其数据烘焙在脚本内而非--variables标志,因此复用 =add+ 就地编辑。data-chart未覆盖的 gap(饼/环、bar-chart-race、环/百分比)手写:D3/visx 做数据→几何,GSAP 做运动。典型签名动画:柱交错生长、线stroke-dashoffset绘制、饼径向扫过、环填充、KPI 计数、竞赛重排。另有dashboard-skeleton 变体:顶栏放真实测试 Logo + 标题,网格排 3–4 张 KPI 卡(每张即一个stat计数)+ 一个data-chart面板,揭示顺序为头部 → 卡片交错 → 图表动画。
maps:矢量车道与烘焙底图车道
modules/maps/module.md 的第一决策是是否需要真实底图:
- 矢量车道(默认):风格化区域形状,无真实影像,HF 内原生运行且廉价,
asset_needs: []。复用us-map(+bubble/hex/flow)、world-map、spain-map;geo-highlight(国家着色 + 标签 + 边界脉冲)、geo-flow(世界弧线/枢纽网络)、flag-borders(旗帜剪裁进国界)、pin-rollout(城市顺序脉冲 + 计数器)需按签名手写(不在 catalog 中)。 - 底图车道:需要真实卫星/暗色瓦片、地球仪或缩放至真实地点时,
asset_needs: [{ type: "map-bake" }]。由于 HyperFrames 禁止渲染期网络并要求确定性,影像必须在 Source 阶段烘焙冻结。bake-basemap.mjs全环境参数驱动(NAME STYLE COUNTRIES CENTER ZSTART ZEND PITCH BEARING FPS DUR),以easeInOutCubic驱动相机 zoom→hold,每帧截图前await map.once('idle')(RemotiondelayRender技法,杜绝瓦片闪现),随后自编码为全 intra MP4(ffmpeg -framerate FPS -i f%04d.png -c:v libx264 -g 1 -pix_fmt yuv420p),并导出map.project()的coords.json(各国家 SVG 路径 + bbox + 近似标签锚点)。
构建时:底图<video>放 track 0,hold 期间在 SVG 覆盖层上动画国界stroke-dashoffset绘制 + 填色揭示 + 标签/图钉/卡片,全部经coords.json地理对齐;同一投影路径还可作 SVGclipPath,把旗帜(或任意纹理)剪进真实国界(已验证:暗色底图上法国三色旗)。
模块还以"每条硬规则都咬过我们"的立场列出工程约束:真实底图影像必须烘焙署名元素(Esri 卫星 → "Esri, Maxar, Earthstar Geographics";CARTO → "© CARTO, © OpenStreetMap");SVG 缩放动画 viewBox 而非手算 group 变换原点;居中元素只动画 opacity 或外包一层居中 div(GSAP 覆盖整个 transform 会杀死居中);用经度/纬度盒过滤国家几何(world-atlas 打包的海外领地会撑爆 bbox,如法国+圭亚那);Esri/CARTO 栅格需tileSize:256;跨 ±180° 的要素在投影前需按相机中心 ref 解卷经度;叠加层只能在静止相机上投影,动画仅在 hold 期间进行;hold 时才揭示的叠加层必须在构建期gsap.set到隐藏态(裸fromTo在补间开始前不应用 "from" 态)。
asset-fusion:素材几何变成图表
asset-fusion/module.md 是搜索驱动、全网新增能力("吸管变成量表、杯中的液体变成饼图"),约 5–8 秒。融合逻辑:先分类数据类型(时间/定量/比例/空间),再读取素材的几何 affordance(线性 → 时间线/量表;体积/纹理 → 饼;高度 → 柱;容器 → 爆炸视图),然后用定位协议接地element_positions,最后从素材取色(绝不用泛化的 #FFF/#000)。
定位协议在 grounding/PROTOCOL.md:作者模型在杂乱全图上回归像素坐标不可靠(弱视觉模型中心误差约 16–24%,圆环会落偏),但离散选格可靠(约 3–4%)。因此绝不目测坐标,而走网格循环:overlay打 9×9 编号网格选条带 →region裁剪放大再打 6×6 细网格再选 →final输出{box, center}→mark画框校验(红色框落在目标上才算完,失败仅一次廉价重试)。实现仅依赖 node + ffmpeg(HyperFrames 本就要求);实测端到端中心误差从目测的 6.5% 降到 2.3%。常见用例"在真实图中圈出/聚光物体 X"可直接套用samples/asset-fusion/_ref-circle-highlight.html模板:填CFG.box(来自定位协议)、CFG.label、CFG.asset、CFG.W/H、CFG.mode(full= 环+连接线+标签+角括号+扫描线,circle= 仅圆环),渲染即得。
模块还固化了渲染坑位:宽高必须为偶数(奇数会令 ffmpeg 编码失败/变形);data-width/data-height必须是舞台上的静态 HTML 属性(渲染器 StaticGuard 在 JS 运行前读取,setAttribute太晚,会回退到竖屏 1080×1920 并变形);stroke-dashoffset绘制必须用autoAlpha:0门控(getTotalLength()在布局前可能读 0 导致 t=0 出现实线);CSS 变量补间要作用在元素自身(元素内联--x会屏蔽:root补间);固定叠加层下不做相机推近(推近会让目标脱出圆环);无损交付用--format mov(ProRes),MP4 有损。
shot-plan IR:Director 与 Builder 之间的唯一契约
shot-plan-ir.md 定义PROJECT_DIR/shot-plan.json的完整 schema:
- 信封(每类别通用):
category、duration_s(3–30)、fps(30)、canvas(默认 1080×1920;按平台 16:9 / 1:1)、style、palette(hex 列表或"derive-from-asset")、font(HF embed 列表)、beats(可选强调帧/秒)、export(mp4或alpha-overlay透明 webm/mov)。 - 素材接缝(Director 第一部分):
asset_needs[],每项{ role, kind: image|icon|logo|svg|news|web|tweet, query|source, treatment: cutout|recolor|vectorize|none };空数组 = 跳过素材阶段。 - 构建指令(Director 第二部分,复用优先):
block(catalog block id,如data-chart、caption-kinetic-slam)+customize。 - 类别专属
content:kinetic-type→scenes[] { id, start, end, text, emphasis_words[], emotion, motion, beats[] };stat→{ value, prefix, suffix, label, ring };charts→{ type, data[], labels[], headline, axes };logo-reveal→{ logo, tagline, url };lower-thirds→{ name, role, position, brand_colors[] };webpage→{ url, capture, highlights[] };news→{ outlet, headline, body, keyword, layout: A|B, ... }(布局 A = 9:16 纯文字居中强调、不缩放,用标记带扫过关键词;布局 B = 16:9 全文 +logo+date+subject);tweet→{ author, handle, avatar, text, metrics };asset-fusion→{ data_type, asset, affordance, element_positions, derived_palette[], connectors[] }。
不变量:scenes划分[0, duration_s]且无缝隙重叠;空asset_needs必跳过素材阶段;命名的block意味着 Builder 复用定制而非手写。
运动词汇:从原语到 GSAP 配方
references/motion-vocabulary.md 提供 Director 在motion字符串中引用、Builder 实现的具名原语表(code_hint是框架中立物理,GSAP 配方是 HyperFrames 实现):
| 原语 | GSAP 配方 | 适用 |
|---|---|---|
slide_bottom/top/left/right | from({ y:±150 / x:±200, opacity:0, ease:"power4.out" }) | 沉稳、建构、专业 |
scale_grow | from({ scale:0, opacity:0, duration:.6, ease:"power2.out" }) | 沉稳、柔和 |
scale_punch | from({ scale:.6, opacity:0, ease:"back.out(2.2)" }) | 冲击、能量 |
fade_in | from({ opacity:0, duration:.4 }) | 细微 |
fade_blur | from({ opacity:0, filter:"blur(14px)" }) | 电影感、梦幻 |
typewriter | 经 clip/SplitText宽度步进揭示 | 技术、叙事 |
word_reveal | 逐词from({opacity:0,y:..}, stagger:.1) | 讲故事 |
wave | 逐字from({y:..}, stagger:{each:.04}) | 流动、音乐性 |
bounce_in | from({y:-120}, ease:"bounce.out") | 俏皮 |
slam | from({ y:-300, ease:"power4.out" })+ 落地抖动 | 冲击、沉重 |
强调原语(常在节拍上):scale_pulse(to({ scale:1.12, yoyo:true, repeat:1, ease:"sine.inOut" }))、shake(to({ keyframes:[{x:-9},{x:9},{x:0}] }))、glow(to({ textShadow:"0 0 46px <ink/accent>" }))、color_shift。退出原语:fade_out、slide_out、scale_out。非文字装饰:underline_sweep、bar_wipe、hold_breath。当 HF registry 组件适用时优先使用:caption-kinetic-slam、caption-editorial-emphasis、caption-neon-glow、caption-glitch-rgb、caption-particle-burst、caption-weight-shift、caption-matrix-decode、caption-pill-karaoke、shimmer-sweep——这些是生态内预构建、已渲染验证的组件。
源码级构建约束:确定性优先
references/builder-contract.md 固化了合成规则:
- 根必须有尺寸:
#stage(data-composition-id)需position: relative; width/height显式设定,否则 flex 子元素塌缩到约 0、内容堆叠到左上角。 - 先布局后动画:先识别 hero frame(多数元素可见的时刻),用静态 CSS 构建它,不写 GSAP;
.scene-content用 flex 居中 + 内边距(padding: 120px 160px; gap: 24px),绝不position:absolute; top:Npx定位内容容器,保持 ≥80px 安全边距。 - 时间线契约:
window.__timelines["<id>"]上一条gsap.timeline({paused:true}),tl.seek(0),永不tl.play();计时元素class="clip"+data-start/data-duration/data-track-index+ 稳定 id。 - 只确定性:无
Date.now()/Math.random()/网络;计数通过onUpdate补间代理对象(seek 安全),绝不使用墙钟计数器。评估发现的要点:延迟元素在 clip 内必须用注册时间线的显式fromTo()({ autoAlpha: 0 }→{ autoAlpha: 1 }),页面加载时gsap.set()或直接操作.clip可见性都会破坏框架生命周期;计数在宿主带事件推进时间线时才渲染(裸seek(t, true)会冻结在 0)。 - 调色板纪律:所有颜色收敛到一个
palette对象 / CSS 自定义属性,不在标记中散落内联 hex(asset-fusion则从素材取色)。 - 允许缓动:
power1–4、back、bounce、circ、elastic、expo、sine(.in/.out/.inOut);每场景一个母题;运行hyperframes check,刻意的溢出用data-layout-allow-overflow="true"标记。
渲染与透明覆盖层
产出阶段对应 hyperframes-cli/references/preview-render.md 的render命令。与 motion-graphics 输出契约直接相关的要点:
--format支持mp4, webm, mov, gif, png-sequence,默认mp4;WebM/MOV 携带透明通道,正是路线输出契约中的"透明 alpha 覆盖层"。GIF 为两遍调色板编码、fps 上限 30、仅 1 位透明。--quality draft用于快速迭代,--fps 60 --quality high用于最终交付(60fps 渲染时间翻倍)。- 默认
--output为renders/<project-name>_<YYYY-MM-DD>_<HH-MM-SS>.<ext>(每次渲染带时间戳互不覆盖),传--output获得稳定名称。 - 注意:
--resolution 4k不能与--format webm/mov组合——4k 超采样路径无 alpha 通道(cloud.md);4k 请渲染为 mp4,或在本机分辨率渲染 alpha。 preview支持--background持久会话与--port自定义端口,是渲染前的审批界面;play则提供轻量的<hyperframes-player>预览。
路线定位与进一步阅读
motion-graphics是 HyperFrames 路由体系中"短、无旁白、运动即信息"的唯一归属。路由决策的完整上下文见 hyperframes/SKILL.md(状态表、路由表与消歧规则)、intent-interview.md(意图层八步)与 capability-menu.md(能力菜单与借用规则——跨工作流借用能力前须npx hyperframes skills update <workflow-name>,并以绝对路径调用脚本、显式传入项目根)。
深入本路线的实现,可依次阅读:motion-graphics/SKILL.md(执行管线与续跑表)→ agents/director.md(分类与设计启发式)→ catalog-map.md(类别 → block 映射与复用机制)→ shot-plan-ir.md(IR schema)→ builder-contract.md(合成硬规则)→ motion-vocabulary.md(运动原语表)→ grounding/PROTOCOL.md(定位协议)。真实可安装的 registry 素材包括data-chart、logo-outro、apple-money-count及north-korea-locked-down标注套件(registry/blocks/目录),可在构建阶段通过npx hyperframes add <block>直接引用。
【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考