字节笔记本

2026年3月22日

HistoryOfEverything - Flutter 炫酷垂直时间线应用


slug: history-of-everything-flutter topic: flutter title: HistoryOfEverything - Flutter 打造的精美时间线应用

Flutter 的跨平台能力和丰富的动画系统使其成为构建精美 UI 应用的理想选择。HistoryOfEverything 是由 2Dimensions 团队打造的 Flutter Launch Timeline Demo,以垂直时间线的形式展示从宇宙大爆炸到互联网诞生的重大历史事件。该项目不仅展示了令人惊叹的视觉效果和流畅动画,还深入演示了 Flutter 自定义渲染、LeafRenderObjectWidget 等高级技术的实际应用,是 Flutter 动画和自定义绘制的标杆项目。

项目简介

HistoryOfEverything(万物历史)是一个垂直时间线应用,用户可以在其中浏览、探索和比较从大爆炸到互联网诞生之间的重大历史事件。每个事件都配有精美的插画和动画效果。该应用的灵感来源于 Kurzgesagt 频道的视频《Time: The History & Future of Everything》,由 2Dimensions 团队使用 Flutter 构建,支持 Android 和 iOS 双平台。

核心特性

  • 垂直时间线浏览: 通过垂直滚动的创新方式展示历史事件,支持缩放和自由导航
  • 精美动画插画: 每个历史事件都配有定制动画,基于 Flare/Nima 动画库实现
  • 三大时代分区: 将历史划分为宇宙、地球、人类三大时代,每个时代独立展示
  • 事件详情页: 点击事件可查看完整动画和详细描述
  • 收藏功能: 支持收藏感兴趣的历史事件
  • 搜索功能: 顶部搜索栏可快速定位特定事件
  • 自定义渲染引擎: 基于 LeafRenderObjectWidget 实现自定义渲染,充分展示 Flutter 底层能力

技术栈

  • Flutter: 跨平台 UI 框架,提供丰富的动画和渲染 API
  • Dart: 应用开发语言
  • Flare: 2Dimensions 自研的矢量动画运行时,与 Flutter 深度集成
  • Nima: 2Dimensions 的骨骼动画库
  • LeafRenderObjectWidget: Flutter 底层自定义渲染组件
  • RenderBox: Flutter 渲染树中的自定义绘制单元
  • SchedulerBinding: Flutter 帧调度系统,用于逐帧更新动画

技术亮点

该项目最突出的技术特点是大量使用了 Flutter 的底层渲染 API 来实现高度自定义的动画效果。具体体现在以下几个方面:

LeafRenderObjectWidget 与 RenderBox

项目中的 TimelineEntryWidget 继承自 LeafRenderObjectWidget,这是一个可以直接插入 Widget 树的基础组件。与之配合的 VignetteRenderObject 继承自 RenderBox,负责实际的绘制逻辑。这种设计绕过了 Flutter 的高层组件抽象,直接在 Canvas 上绘制,实现了极致的性能和视觉效果。

Flare 动画集成

Flare 库获取到 Flutter 暴露的 Canvas 后直接绘制动画。为了确保动画正确播放,每帧都需要调用 advance(elapsed) 推进 FlutterActor 的状态,并调用 apply(time)ActorAnimation 的插值应用到渲染对象上。这一切通过 Flutter 的 SchedulerBinding.scheduleFrameCallback() 实现,保证了动画的流畅性。

安装指南

前置条件

  • 已安装 Flutter SDK(安装指南请参考 Flutter 官方文档)
  • Android Studio 或 Xcode(用于编译和运行)

克隆与安装

bash
# 克隆项目
git clone https://github.com/2d-inc/HistoryOfEverything.git

# 进入应用目录
cd HistoryOfEverything/app

# 初始化子模块(包含动画资源等)
git submodule init
git submodule update

# 运行应用
flutter run

注意:该项目包含 Git 子模块,务必执行 git submodule initgit submodule update 命令来获取完整的动画资源文件,否则应用将无法正常显示动画。

快速开始

应用启动后,将看到主菜单界面,包含以下主要视图:

1. 主菜单 (Main Menu)

  • 位置: /app/lib/main_menu
  • 功能: 应用初始界面,顶部搜索栏,三大时代分区入口
  • 底部操作: 收藏、分享、关于页面入口

2. 时间线 (Timeline)

  • 位置: /app/lib/timeline
  • 功能: 核心浏览界面,垂直时间线展示
  • 交互: 上下滚动浏览、缩放、点击事件查看详情
  • 当事件进入视口时,会自动显示带有定制动画的气泡提示

3. 文章详情页 (Article Page)

  • 位置: /app/lib/article
  • 功能: 展示事件的完整动画和详细描述文字
  • 动画: 全屏动画播放配合文字说明

使用示例

自定义渲染组件示例

项目中 TimelineEntryWidget 的使用方式展示了如何将自定义渲染组件嵌入标准 Widget 树:

dart
Container(
  child: TimelineEntryWidget(
    isActive: true,
    timelineEntry: widget.article,
    interactOffset: _interactOffset
  )
)

这段代码来自 /app/lib/article/article_widget.dart,展示了自定义 LeafRenderObjectWidget 与标准 Container 的无缝组合。

LeafRenderObjectWidget 的两个关键方法

  • createRenderObject(): 在 Widget 树中实例化实际的 RenderObject
  • updateRenderObject(): 当 Widget 参数变化时更新渲染对象并触发重绘

RenderObject 的绘制逻辑

RenderBox 的核心是 paint() 方法的重写。通过 PaintingContext 获取 Canvas 引用,利用 Flutter 的完整绘图 API 进行自定义绘制。Flare 库正是通过这个 Canvas 实现了矢量动画的高效渲染。

项目架构

text
HistoryOfEverything/
├── app/
│   ├── lib/
│   │   ├── main_menu/          # 主菜单模块
│   │   ├── timeline/           # 时间线模块
│   │   └── article/            # 文章详情模块
│   │       ├── timeline_entry_widget.dart  # 自定义渲染组件
│   │       └── article_widget.dart          # 文章页面
│   └── assets/                 # 动画和文章资源
└── assets/
    └── articles/               # Wikipedia 文章(GNU FDL 许可)

学习价值

HistoryOfEverything 不仅仅是一个展示应用,更是学习 Flutter 高级技术的优秀教材:

  1. 自定义渲染: 深入理解 Flutter 渲染管线,掌握 LeafRenderObjectWidgetRenderBox 的使用
  2. 动画系统: 学习如何将第三方动画库(Flare/Nima)集成到 Flutter 应用中
  3. 帧调度: 了解 SchedulerBinding.scheduleFrameCallback() 的工作原理
  4. 性能优化: 通过直接操作 Canvas 避免高层 Widget 的性能开销
  5. 项目结构: 学习如何组织大型 Flutter 项目的代码结构

许可证

  • 代码: MIT License
  • 动画资源 (/assets 目录): CC-BY License
  • 文章内容 (assets/articles 目录): GNU Free Documentation License(内容来源于 Wikipedia)

适用场景

  • Flutter 开发者学习高级动画和自定义渲染技术
  • 跨平台应用开发中的 UI 设计参考
  • Flare/Nima 动画库的集成实践参考
  • 历史科普类应用的设计灵感来源

项目链接

分享: