使用 Remotion 制作一个 5 柱状图动画:从源码到 MP4 导出
2026/7/12 4:52:23 网站建设 项目流程

一、最终效果与技术特点

这个示例展示 North、South、East、West 和 Central 五个区域的数据,目标值分别为 72%、48%、86%、62% 和 94%。动画包含:

  • 五根柱子错峰出现;
  • 柱高和百分比数字同步变化;
  • 使用缓动曲线,让动画自然减速;
  • 渐变色、圆角和阴影效果;
  • 1280×720、30 FPS 的标准横屏视频;
  • 所有动画由帧驱动,导出结果稳定、可复现。

二、为什么选择 Remotion

Remotion 是一个通过 React 代码制作视频的框架。与传统视频编辑软件不同,它把视频画面视为 React 组件,并使用当前帧数控制元素状态。

这种方式尤其适合数据可视化、批量视频、排行榜、产品演示和自动化报告。只要替换数据,就能重复生成不同版本的视频。

三、准备开发环境

建议安装 Node.js 20 或 22 LTS,并确认版本:

node-vnpm-v

下载并解压项目后,进入目录:

cdanimated-bar-chart

使用 pnpm 安装依赖并启动:

pnpminstallpnpmdev

如果没有 pnpm,也可以使用 npm:

npminstallnpmrun dev

启动后,浏览器会打开 Remotion Studio。选择AnimatedBarChart即可预览和逐帧检查动画。

四、注册视频 Composition

src/Root.tsx定义视频的名称、时长、帧率和画布尺寸:

import "./index.css"; import {Composition} from "remotion"; import {AnimatedBarChart} from "./Composition"; export const RemotionRoot: React.FC = () => { return ( <Composition id="AnimatedBarChart" component={AnimatedBarChart} durationInFrames={120} fps={30} width={1280} height={720} /> ); };

其中,durationInFrames={120}fps={30}表示视频持续 4 秒:

120 帧 ÷ 30 帧/秒 = 4 秒

id既是 Studio 中显示的名称,也是命令行导出时使用的 Composition ID。

五、准备五组柱状图数据

src/Composition.tsx中,用数组统一保存标签、数值和颜色:

const bars = [ {label: "North", value: 72, color: "#7C5CFC"}, {label: "South", value: 48, color: "#20C7A6"}, {label: "East", value: 86, color: "#FFB84D"}, {label: "West", value: 62, color: "#FF6685"}, {label: "Central", value: 94, color: "#56A8FF"}, ] as const;

以后要修改图表,只需要替换这组数据,不必重新编写五份组件代码。

六、用帧驱动动画

Remotion 动画的核心是useCurrentFrame()interpolate()

const frame = useCurrentFrame(); const progress = interpolate(frame, [start, start + 42], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: Easing.bezier(0.16, 1, 0.3, 1), });

这里的逻辑是:

  1. frame表示当前正在渲染第几帧;
  2. 从第start帧到第start + 42帧,将进度从 0 映射到 1;
  3. clamp将范围外的结果固定在 0 或 1,避免柱子反向增长或超出目标;
  4. 贝塞尔缓动让柱子前期快速增长、后期平稳减速。

柱子的实时高度与数字可以由同一个progress推导:

const height = bar.value * 4.1 * progress; const displayedValue = Math.round(bar.value * progress);

这样柱高与百分比始终同步,不会出现数字已经结束但柱子仍在运动的问题。

七、实现五根柱子的错峰出现

如果五根柱子同时开始,画面会显得比较机械。可以根据数组下标增加延迟:

const start = 18 + index * 8;

第一根柱子从第 18 帧开始,后续柱子每隔 8 帧启动一次。在 30 FPS 下,8 帧约等于 0.27 秒。这种轻微的错峰能够引导观众从左到右阅读数据。

八、柱状图组件的关键结构

通过map()渲染五根柱子:

{bars.map((bar, index) => { const start = 18 + index * 8; const progress = interpolate(frame, [start, start + 42], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: Easing.bezier(0.16, 1, 0.3, 1), }); const height = bar.value * 4.1 * progress; const displayedValue = Math.round(bar.value * progress); return ( <div key={bar.label} style={{ flex: 1, height: "100%", display: "flex", flexDirection: "column", justifyContent: "flex-end", alignItems: "center", }} > <div style={{fontSize: 25, fontWeight: 800, marginBottom: 12, opacity: progress}}> {displayedValue}% </div> <div style={{ width: "100%", maxWidth: 150, height, background: `linear-gradient(180deg, ${bar.color}, ${bar.color}B8)`, borderRadius: "16px 16px 4px 4px", boxShadow: `0 16px 40px ${bar.color}28`, }} /> </div> ); })}

这里采用 Flex 布局,并使用justifyContent: "flex-end"将柱子固定在基线之上。改变高度时,柱子自然地从下向上生长。

九、让标题也具有入场动画

标题使用透明度和纵向位移实现淡入上浮:

const titleOpacity = interpolate(frame, [0, 16], [0, 1], { extrapolateRight: "clamp", }); <div style={{ opacity: titleOpacity, translate: `0 ${interpolate(frame, [0, 16], [18, 0], { extrapolateRight: "clamp", })}px`, }} > {/* 标题内容 */} </div>

Remotion 中不要依赖 CSStransition@keyframes。逐帧渲染时,直接根据frame计算样式,结果更加可靠。

十、导出 MP4 视频

在项目目录中执行:

npx remotion render AnimatedBarChart out/bar-chart.mp4

渲染完成后,文件位于:

out/bar-chart.mp4

也可以先渲染一张静态图检查排版:

npx remotion still AnimatedBarChart out/preview.png--frame=80

--frame=80表示截取第 80 帧,此时五根柱子基本已经完成入场。

十一、常见问题

1. 找不到pnpm命令

可以直接使用 npm,或者安装 pnpm:

npminstall-gpnpm

2. 导出时提示找不到 Composition

检查命令中的AnimatedBarChart是否与Root.tsx中的id完全一致,包括大小写。

3. 柱子超出画面

示例中的4.1是高度缩放系数:

const height = bar.value * 4.1 * progress;

如果数据范围更大,应当先归一化,或减小该系数。更通用的写法是根据最大值计算比例:

const maxValue = Math.max(...bars.map((item) => item.value)); const height = (bar.value / maxValue) * 385 * progress;

4. 修改数据后标签拥挤

减少标签长度、增大视频宽度,或者降低柱子之间的gap。如果柱子数量很多,更适合使用横向柱状图或分页展示。

十二、进一步扩展

基于这个项目,还可以继续加入:

  • 从 JSON、CSV 或接口动态读取数据;
  • 自动计算纵轴刻度和网格线;
  • 增加排序动画,让柱子交换位置;
  • 添加背景音乐、旁白和字幕;
  • 使用输入参数批量生成不同地区或不同月份的视频;
  • 增加片尾总结或品牌 Logo。

总结

Remotion 的关键思想是:把时间转换为帧,再把帧转换为组件样式。在这个五柱状图示例中,我们用useCurrentFrame()获取时间,用interpolate()计算动画进度,再由进度统一控制柱高、数字和透明度。

掌握这一模式后,折线图、排行榜、数据看板和年度总结视频都可以用相同思路实现。相比手工制作视频,代码化方案更容易复用,也更适合自动化和批量生产。


如果本文对你有帮助,欢迎点赞、收藏并在评论区交流。你还可以尝试把示例中的五组数据替换成自己的业务指标,生成第一段属于自己的数据可视化视频。

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

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

立即咨询