drawing_animation

一个用于在画布上逐步绘制 SVG 路径对象的 Flutter 库(绘制线条动画)。

该渲染库公开了一个名为 AnimatedDrawing 的核心小部件,该小部件允许以绘制的方式渲染 SVG 路径(通过 AnimatedDrawing.svg)或 Flutter Path 对象(通过 AnimatedDrawing.paths)。

入门 - AnimatedDrawing.svg

要开始使用 drawing_animation 包,您需要一个有效的 SVG 文件。
目前仅支持没有变换的简单路径元素(请参阅 支持的 SVG 规范

  1. 在您的 pubspec.yaml 中添加依赖项
dependencies:
  drawing_animation: ^0.1.1

  1. 添加 SVG 资源
assets:
  - assets/my_drawing.svg
  1. 使用小部件

    AnimatedDrawing 小部件可以通过两种方式启动

    1. 简化版 - 无动画控制器(请参阅 Example_01

      默认情况下,所有动画都会无限循环。要仅运行一次动画,您可以使用回调将 run 在第一个动画周期完成后设置为 false(请参阅字段 onFinish)。

      AnimatedDrawing.svg(
        "assets/my_drawing.svg",
        run: this.run,
        duration: new Duration(seconds: 3),
        onFinish: () => setState(() {
          this.run  = false;
        }),
      )
      
    2. 标准版 - 带动画控制器(请参阅 Example_02

      简化版将在大多数用例中足够。如果您希望进一步控制动画,或者希望将其与任何其他现有动画同步,您可以考虑使用自定义的 AnimationController

      AnimatedDrawing.svg(
        "assets/test.svg",
        controller: this.controller,
      )
      
  2. 请查看 examples 文件夹中的示例。似乎在使用调试模式时,Paint/Canvas 的抗锯齿已关闭。为获得漂亮的结果,请使用 flutter run --release

入门 - AnimatedDrawing.paths(仍处于实验阶段)

通过直接向小部件提供 Path 对象,可以动态更改元素,甚至可以在动画期间更改。内部数据结构会在每次状态更改时重建,因此如果 paths 中的元素数量非常多,动画性能可能会受到影响(请参阅限制)。稍后将提供更多示例(目前请参阅 Example_01Example_04)。

AnimatedDrawing.paths(
    [
    ///Path objects
    ],
    paints:[
    ///Paint objects (optional), specifies a [Paint] object for each [Path] element in `paths`.
    ],
    run: this.run,
    duration: new Duration(seconds: 3),
    onFinish: () => setState(() {
      this.run  = false;
    }),
  )

当前限制

如前所述,对于小部件的每次状态更改,都会重建路径对象的内部数据结构。当提供的路径对象数量很多并且定义了自定义 animationOrder(这会触发对数据结构进行排序操作)时,可能会导致延迟。当状态由另一个动画以 60fps 的速度重建时(例如,每帧旋转路径对象),这一点会特别明显。欢迎就如何优雅地解决此问题提出任何建议 :-)

支持的 SVG 规范

  • 目前仅支持路径元素(<path d="M3m1....">)。我目前正在考虑将 flutter_svg 添加为依赖项,以实现更完整的 SVG 解析。
  • 属性
    • 描边,目前仅支持不带 alpha 的十六进制颜色
    • 描边宽度
    • 样式,但仅支持上述两个字段
  • 目前不支持任何变换。

如何使用我自己的 SVG 文件?

许多工具可以将现有的 SVG 文件转换为 支持的格式
例如,使用 Inkscape

  1. 选择所有对象并取消分组,直到没有组为止(Ctrl+U)
  2. 将选定对象转换为路径:路径 >> 对象转路径,然后保存。
  3. 之后,使用 svgo 或 Web 版本 svgomg 删除变换。
  4. 现在它应该可以工作了,如果不行,请随时提交 issue!

待办事项

  • 更好的测试覆盖率
  • 改进 SVG 解析能力
    • 圆形、矩形等。
    • 更好的颜色解析,包括十六进制代码和 RGB(A) 的 alpha 值
    • 用成熟的解析库(如 flutter_svg)替换 SVG 解析逻辑
  • 提供一种覆盖 AnimatedDrawing.svg 的颜色/画笔等的方式 - 也许也可以通过 paints 对象?
  • 定义一个 [PathOrder],它维护每个 Path 并仅对它们进行相对排序
  • 改进 AnimatedDrawing.paths 的性能,每次重建都需要重新解析所有提供的路径。是否有办法像小部件的 Keys 一样检查 Path 对象是否相等?想法:实现一个 Path 的代理,当调用命令时创建一个唯一的哈希值
  • 展示:用不同的方式写“drawing_animation” + 3个圆圈 + 颜色以及一个 GIF,放在顶部
  • 展示:用 L-System 创建分形
  • AnimatedDrawing.paths
    • 提供某种固定的大小框,因为 Paths 和整体大小框可以动态更改(例如,旋转的圆脉冲大小)
    • 也提供自定义视口

GitHub

https://github.com/biocarl/drawing_animation