353 lines
16 KiB
Markdown
353 lines
16 KiB
Markdown
# 视频合成结构(Composition)
|
||
|
||
<cite>
|
||
**本文引用的文件**
|
||
- [Composition.tsx](file://src/Composition.tsx)
|
||
- [Root.tsx](file://src/Root.tsx)
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx)
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx)
|
||
- [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx)
|
||
- [types.ts](file://src/types.ts)
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts)
|
||
- [mock-data.json](file://src/mock-data.json)
|
||
- [mock-cashflow.json](file://src/mock-cashflow.json)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构总览](#架构总览)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [依赖关系分析](#依赖关系分析)
|
||
7. [性能考量](#性能考量)
|
||
8. [故障排查指南](#故障排查指南)
|
||
9. [结论](#结论)
|
||
10. [附录](#附录)
|
||
|
||
## 简介
|
||
本文件围绕 Composition.tsx 在 Remotion 框架中的角色展开,重点说明其作为“可渲染的视频合成单元”的职责与设计意图。尽管当前文件仅导出一个空实现的 MyComposition 函数,但其命名与位置遵循 Remotion 的约定,为后续扩展预留了清晰的入口点。我们将在文档中系统阐述:
|
||
- 如何通过 Remotion 的 Composition 组件进行注册与参数配置(durationInFrames、fps 等)
|
||
- 如何将动态数据(来自 render_props.json 或本地 mock 数据)传递给子组件
|
||
- 如何构建多层画面布局(如画中画、分屏)
|
||
- 如何创建多个 Composition 变体以适配不同视频模板或客户场景
|
||
|
||
## 项目结构
|
||
Remotion 应用通过根组件集中注册多个 Composition,每个 Composition 对应一个独立的视频片段。Composition.tsx 当前处于待实现状态,未来将作为统一的入口或模板基座,承载 LifePlanChart、CashFlowChart、UnifiedHUD 等组件的组合与编排。
|
||
|
||
```mermaid
|
||
graph TB
|
||
Root["Root.tsx<br/>注册多个 Composition"] --> Comp1["Composition.tsx<br/>MyComposition待实现"]
|
||
Root --> LP["LifePlanChart.tsx"]
|
||
Root --> CF["CashFlowChart.tsx"]
|
||
Root --> DCV["DualChartView.tsx"]
|
||
DCV --> LP
|
||
DCV --> CF
|
||
DCV --> HUD["UnifiedHUD.tsx"]
|
||
LP --> Types["types.ts"]
|
||
CF --> Types
|
||
LP -. 使用 .-> Mock1["mock-data.json"]
|
||
CF -. 使用 .-> Mock2["mock-cashflow.json"]
|
||
```
|
||
|
||
图表来源
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
- [Composition.tsx](file://src/Composition.tsx#L1-L4)
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
- [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx#L1-L164)
|
||
- [types.ts](file://src/types.ts#L1-L30)
|
||
- [mock-data.json](file://src/mock-data.json#L1-L61)
|
||
- [mock-cashflow.json](file://src/mock-cashflow.json#L1-L200)
|
||
|
||
章节来源
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
- [Composition.tsx](file://src/Composition.tsx#L1-L4)
|
||
|
||
## 核心组件
|
||
- Composition.tsx:当前为空实现,命名为 MyComposition,符合 Remotion 入口约定,用于承载后续的视频合成逻辑与组件组合。
|
||
- Root.tsx:集中注册多个 Composition,包括 LifePlanChart、LifePlanBarChart、CashFlowChart、DualChartView 等,每个注册项包含时长、帧率、分辨率与默认数据。
|
||
- LifePlanChart.tsx:资产余额趋势图,支持动画推进与 HUD 展示。
|
||
- CashFlowChart.tsx:收支明细图,支持分段增长动画与 HUD 展示。
|
||
- DualChartView.tsx:双图视图,同步控制两个子图的动画进度,实现画中画/分屏效果。
|
||
- UnifiedHUD.tsx:统一 HUD,展示当前年份与关键财务指标。
|
||
- types.ts:定义 YearlySnapshot、LifePlanChartProps 等类型,确保组件间数据契约一致。
|
||
- render-props-types.ts:前端侧 render_props.json 类型定义,与后端生成的数据结构对齐。
|
||
- mock-data.json、mock-cashflow.json:演示数据,供本地开发与调试使用。
|
||
|
||
章节来源
|
||
- [Composition.tsx](file://src/Composition.tsx#L1-L4)
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
- [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx#L1-L164)
|
||
- [types.ts](file://src/types.ts#L1-L30)
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
- [mock-data.json](file://src/mock-data.json#L1-L61)
|
||
- [mock-cashflow.json](file://src/mock-cashflow.json#L1-L200)
|
||
|
||
## 架构总览
|
||
Remotion 的视频合成由“根注册 + 组合组件 + 子组件”三层构成:
|
||
- 根注册层:在 Root.tsx 中通过 Composition 组件注册多个视频片段,设置时长、帧率、分辨率与默认数据。
|
||
- 组合层:Composition.tsx 作为入口或模板基座,负责组织 LifePlanChart、CashFlowChart、UnifiedHUD 等组件;也可参考 DualChartView 的双图同步策略。
|
||
- 子组件层:各图表组件内部管理动画、数据切片与 HUD 渲染,保证视觉一致性与性能稳定。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Dev as "开发者"
|
||
participant Root as "Root.tsx"
|
||
participant Comp as "Composition.tsx"
|
||
participant LP as "LifePlanChart.tsx"
|
||
participant CF as "CashFlowChart.tsx"
|
||
participant DCV as "DualChartView.tsx"
|
||
participant HUD as "UnifiedHUD.tsx"
|
||
Dev->>Root : 编写/修改根注册
|
||
Root->>Comp : 注册 MyComposition待实现
|
||
Root->>LP : 注册 LifePlanChart
|
||
Root->>CF : 注册 CashFlowChart
|
||
Root->>DCV : 注册 DualChartView
|
||
Comp-->>Dev : 作为入口承载组件组合
|
||
LP-->>Dev : 动画推进与 HUD
|
||
CF-->>Dev : 分段增长动画与 HUD
|
||
DCV-->>Dev : 双图同步与布局
|
||
HUD-->>Dev : 统一指标展示
|
||
```
|
||
|
||
图表来源
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
- [Composition.tsx](file://src/Composition.tsx#L1-L4)
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
- [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx#L1-L164)
|
||
|
||
## 详细组件分析
|
||
|
||
### Composition.tsx(入口与模板)
|
||
- 角色定位:当前为空实现,命名为 MyComposition,遵循 Remotion 入口约定,未来将作为视频合成单元的承载者。
|
||
- 设计建议:
|
||
- 将 LifePlanChart、CashFlowChart、UnifiedHUD 等组件按需组合,形成单页视频。
|
||
- 通过外层容器实现画中画或分屏布局,复用 DualChartView 的同步策略。
|
||
- 从 defaultProps 或外部传入的数据源中提取 timeline、meta 等字段,传递给子组件。
|
||
- 参数配置:可在 Root.tsx 中参考现有注册方式,为 MyComposition 设置 durationInFrames、fps、width、height、defaultProps 等。
|
||
|
||
章节来源
|
||
- [Composition.tsx](file://src/Composition.tsx#L1-L4)
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
|
||
### LifePlanChart.tsx(资产余额趋势)
|
||
- 功能要点:
|
||
- 基于 Recharts 的面积图展示资产余额趋势,支持自定义 X 轴刻度与渐变填充。
|
||
- 使用 useCurrentFrame 与 useVideoConfig 获取帧索引与时长,通过 interpolate 实现平滑动画推进。
|
||
- 支持 HUD 展示当前年份、资产余额、收入与支出等关键指标。
|
||
- 性能优化:
|
||
- 使用 memo 包装组件,避免不必要的重渲染。
|
||
- 使用 useMemo 计算 Y 轴域与动画数据,减少每帧计算量。
|
||
- 复杂度分析:
|
||
- 动画推进与数据切片的时间复杂度近似 O(n),n 为 timeline 长度;Y 轴域计算为 O(n)。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["进入组件"]) --> GetFrame["获取当前帧与总时长"]
|
||
GetFrame --> Interp["插值计算精确索引"]
|
||
Interp --> Slice["根据索引切片可见数据"]
|
||
Slice --> InterpolatePoint{"是否需要插值点?"}
|
||
InterpolatePoint --> |是| AddPoint["插入插值点以平滑过渡"]
|
||
InterpolatePoint --> |否| SkipPoint["跳过"]
|
||
AddPoint --> CalcY["计算 Y 轴域基于全量数据"]
|
||
SkipPoint --> CalcY
|
||
CalcY --> Render["渲染图表与 HUD"]
|
||
Render --> End(["退出"])
|
||
```
|
||
|
||
图表来源
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
|
||
章节来源
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [types.ts](file://src/types.ts#L1-L30)
|
||
|
||
### CashFlowChart.tsx(收支明细)
|
||
- 功能要点:
|
||
- 使用组合图展示收入线与多类支出堆叠柱状图,支持分段增长动画。
|
||
- 自定义 X 轴刻度显示年份与年龄,提供 HUD 展示当前年份与收支平衡。
|
||
- 动画策略:
|
||
- 通过分段比例控制各类别柱状图的生长顺序,使动画更易理解。
|
||
- 在固定域模式下补齐缺失年份,避免坐标偏移。
|
||
- 复杂度分析:
|
||
- 数据扁平化与可见数据切片为 O(n);Y 轴域计算为 O(n)。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["进入组件"]) --> GetFrame["获取当前帧与总时长"]
|
||
GetFrame --> Interp["插值计算进度"]
|
||
Interp --> Segment["计算分段比例"]
|
||
Segment --> Flatten["扁平化数据并计算汇总"]
|
||
Flatten --> Slice["切片可见数据并应用分段动画"]
|
||
Slice --> Pad{"是否需要补齐年份?"}
|
||
Pad --> |是| Fill["填充空年份占位"]
|
||
Pad --> |否| SkipFill["跳过"]
|
||
Fill --> Domain["计算 Y 轴域"]
|
||
SkipFill --> Domain
|
||
Domain --> Render["渲染图表与 HUD"]
|
||
Render --> End(["退出"])
|
||
```
|
||
|
||
图表来源
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
|
||
章节来源
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
|
||
### DualChartView.tsx(双图同步)
|
||
- 功能要点:
|
||
- 同步控制 LifePlanChart 与 CashFlowChart 的动画进度,实现上/下分屏布局。
|
||
- 将 CashFlow 数据转换为 LifePlan 所需格式,确保两图共享同一动画时序。
|
||
- 通过 hideHeader 控制子图头部显示,减少重复信息。
|
||
- 关键流程:
|
||
- 统一插值计算动画进度,分别传递到两个子图。
|
||
- 使用 useMemo 预处理转换后的 timeline 与 meta,避免每帧重建数组。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant DCV as "DualChartView"
|
||
participant LP as "LifePlanChart"
|
||
participant CF as "CashFlowChart"
|
||
participant HUD as "UnifiedHUD"
|
||
DCV->>DCV : 插值计算动画进度
|
||
DCV->>LP : 传递外部索引与分数
|
||
DCV->>CF : 传递外部年进度
|
||
DCV->>HUD : 传递当前年份与指标
|
||
LP-->>DCV : 渲染资产余额趋势
|
||
CF-->>DCV : 渲染收支明细
|
||
HUD-->>DCV : 渲染统一 HUD
|
||
```
|
||
|
||
图表来源
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
- [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx#L1-L164)
|
||
|
||
章节来源
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
- [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx#L1-L164)
|
||
|
||
### UnifiedHUD.tsx(统一 HUD)
|
||
- 功能要点:
|
||
- 展示当前年份、年龄、收入、支出、净现金流与资产余额等关键指标。
|
||
- 使用统一配色与图标,突出正负差异。
|
||
- 设计建议:
|
||
- 可作为独立组件在 Composition 或 DualChartView 中复用,或由子图内部自行渲染。
|
||
|
||
章节来源
|
||
- [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx#L1-L164)
|
||
|
||
## 依赖关系分析
|
||
- 组件耦合:
|
||
- DualChartView 依赖 LifePlanChart、CashFlowChart 与 UnifiedHUD,形成组合关系。
|
||
- LifePlanChart 与 CashFlowChart 内部依赖 Recharts 与 Remotion 的时间控制 API。
|
||
- 数据契约:
|
||
- types.ts 定义 YearlySnapshot、LifePlanChartProps,确保组件间数据结构一致。
|
||
- render-props-types.ts 定义前端侧 render_props.json 结构,便于与后端数据对接。
|
||
- 外部数据:
|
||
- Root.tsx 通过 defaultProps 将 mock-data.json 与 mock-cashflow.json 注入对应 Composition。
|
||
|
||
```mermaid
|
||
graph LR
|
||
Root["Root.tsx"] --> Comp["Composition.tsx"]
|
||
Root --> LP["LifePlanChart.tsx"]
|
||
Root --> CF["CashFlowChart.tsx"]
|
||
Root --> DCV["DualChartView.tsx"]
|
||
DCV --> LP
|
||
DCV --> CF
|
||
DCV --> HUD["UnifiedHUD.tsx"]
|
||
LP --> Types["types.ts"]
|
||
CF --> Types
|
||
LP -. defaultProps .-> Mock1["mock-data.json"]
|
||
CF -. defaultProps .-> Mock2["mock-cashflow.json"]
|
||
```
|
||
|
||
图表来源
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
- [Composition.tsx](file://src/Composition.tsx#L1-L4)
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
- [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx#L1-L164)
|
||
- [types.ts](file://src/types.ts#L1-L30)
|
||
- [mock-data.json](file://src/mock-data.json#L1-L61)
|
||
- [mock-cashflow.json](file://src/mock-cashflow.json#L1-L200)
|
||
|
||
章节来源
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
- [types.ts](file://src/types.ts#L1-L30)
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
|
||
## 性能考量
|
||
- 动画推进:
|
||
- 使用 useCurrentFrame 与 interpolate 进行帧级插值,避免每帧重复计算动画进度。
|
||
- 数据切片与缓存:
|
||
- 通过 useMemo 缓存 Y 轴域、转换后的 timeline 与 meta,减少数组重建与昂贵计算。
|
||
- 图表渲染:
|
||
- Recharts 默认动画关闭,避免内部动画与外部插值冲突导致的闪烁。
|
||
- 布局与缩放:
|
||
- 使用 ResponsiveContainer 与固定宽高比,确保在不同分辨率下的稳定渲染。
|
||
|
||
章节来源
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
|
||
## 故障排查指南
|
||
- 数据不匹配:
|
||
- 若出现图表渲染异常,检查 YearlySnapshot 与 CashFlowData 字段是否与组件期望一致。
|
||
- 参考 render-props-types.ts 的类型定义,确保前后端数据结构一致。
|
||
- 动画卡顿或跳帧:
|
||
- 确认未在组件内执行昂贵的每帧计算,必要时使用 useMemo 缓存中间结果。
|
||
- 检查 interpolate 的区间与 extrapolate 配置,避免越界导致的异常值。
|
||
- 布局错位:
|
||
- 确保 DualChartView 中两个子图的边距与字体设置一致,避免视觉错位。
|
||
- 数据缺失:
|
||
- 在固定域模式下,CashFlowChart 会补齐空年份占位;若仍出现偏移,检查 timeline 的起止年份与 domain 计算逻辑。
|
||
|
||
章节来源
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441)
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
|
||
## 结论
|
||
Composition.tsx 当前作为 Remotion 的入口模板,虽未实现具体逻辑,但已具备清晰的扩展路径。结合 Root.tsx 的注册方式与各子组件的动画与布局策略,开发者可以快速构建多种视频模板(单图、双图、画中画等),并通过 defaultProps 或外部数据源(render_props.json)灵活适配不同客户场景。建议在实现 MyComposition 时,优先参考 DualChartView 的同步策略与布局模式,并充分利用 useMemo 与 Recharts 的性能特性,确保视频渲染的流畅与稳定。
|
||
|
||
## 附录
|
||
|
||
### 在 Root.tsx 中注册 Composition 的参考流程
|
||
- 为每个视频模板创建一个 Composition 注册项,设置 id、component、durationInFrames、fps、width、height、defaultProps 等。
|
||
- defaultProps 中注入数据源(如 mock-data.json 或 mock-cashflow.json),确保组件可直接消费。
|
||
- 参考现有注册项,为 MyComposition 预留参数与数据结构。
|
||
|
||
章节来源
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
|
||
### 将动态数据传递给子组件的实践
|
||
- render-props-types.ts 提供了前端侧 render_props.json 的类型定义,可用于校验与消费后端生成的数据。
|
||
- 在 Composition 中,将 render_props.json 的 charts、script、assets 等字段映射到子组件 props,实现数据驱动的视频内容生成。
|
||
|
||
章节来源
|
||
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
|
||
### 创建多个 Composition 变体的建议
|
||
- 单图模板:以 LifePlanChart 或 CashFlowChart 为核心,配合 HUD 展示关键指标。
|
||
- 双图模板:采用 DualChartView 的同步策略,实现资产余额与收支明细的联动展示。
|
||
- 画中画模板:在 Composition 中嵌套子组件,通过外层容器实现画中画布局,复用 HUD 与动画逻辑。
|
||
- 客户场景适配:通过不同的 defaultProps 与 meta 配置,快速切换货币单位、起始年份、时长等参数,满足不同客户的视频需求。
|
||
|
||
章节来源
|
||
- [Root.tsx](file://src/Root.tsx#L1-L68)
|
||
- [DualChartView.tsx](file://src/DualChartView.tsx#L1-L176)
|
||
- [LifePlanChart.tsx](file://src/LifePlanChart.tsx#L1-L349)
|
||
- [CashFlowChart.tsx](file://src/CashFlowChart.tsx#L1-L441) |