跳到正文

字符动画工作台

ASCII Animation Workbench

用视频、GIF、逐帧编辑、滚动文字或程序生成的效果做成字符网格动画,可导出文本帧、ANSI、asciicast v2、动图 GIF 和单文件 HTML 播放器。

这是一个工作台,不是转换器。文档是一串各带延时的字符网格,有四种填充方式——视频或 GIF、透着上一帧自己画、让横幅动起来、或者某种程序生成效果——和四种导出方式,包括真正的动态 GIF,以及一个完全不联网就能播放它的单个 HTML 文件。

🔒 完全在你的浏览器里运行asciiartanimationvideoterminal
帧从哪里来

Andy Sloane 的 donut.c(2006):一个带 z 缓冲的圆环面,按表面法线与固定光源的内积来着色。

同一个种子永远给出同样的帧,所以结果可以照原样重现、原样再导一次。

第1帧,共 1帧

1帧,0.1秒,内存约 7.5 kB

导出
























想要 MP4 或 WebM,先把 GIF 存下来,再交给GIF 转视频:那边已经用 WebCodecs 编码,把 H.264 封进 MP4、VP9 封进 WebM。在这里再写一个编码器,只会是那一个的劣化版。没有 APNG 导出:那要在 PNG 写入器之上再加 acTL、fcTL、fdAT 几个块,没做。
帧数上限 600,整个网格上限 240万格 —— 带上颜色差不多是同时占着 230 MB。按现在这个尺寸,是 600帧。再往上,手机上的标签页会被一声不吭地干掉,那比被拒绝还糟。
asciicast v2 是一行一条 JSON:先是一个头部对象,之后每帧一行 [时刻, "o", 数据] 数组。时刻是从头算起的绝对秒数,不是每帧间隔;每一帧都把光标送回顶端再清掉下面,这样短帧不会留下长帧的尾巴;行尾用 CRLF —— 终端原始输出里只写换行,就会出现那种经典的阶梯错位。这里是照着公开的规范实现的。
内存全花在帧数乘网格大小上,所以两样都设了上限,而且把上限写出来,不让人自己撞。转换在 worker 里跑,取消真能传到循环里,所以三百帧的活儿既不会卡住标签页,也不会在你叫停之后还接着跑。

怎么用

  1. 看帧预算,不看文件大小

    这里的一切开销都是帧数乘以网格格数,页面会印出在你选的宽度下能放多少帧。把输出从 80 字符加宽到 160,能容纳的帧数就减到四分之一。上限存在,是因为另一种结果是手机标签页被无声地杀掉。

  2. 导出前设好延时

    每一帧带自己的延时,每个导出器都读它,所以预览里看到的就是 GIF 和 asciicast 的表现。要恒定速率就设一帧然后按"应用到每一帧",想在某个姿势上停留就把那几帧单独设长。

  3. 按去向选导出

    asciicast v2 给 asciinema 和任何会在终端里播放它的人。GIF 给聊天窗口或 README。HTML 播放器用于嵌入——一个文件,帧在里面,不用 CDN。别的东西要读它就用纯文本帧。

常见问题

asciicast v2 是什么,为什么不直接用 GIF?

它是 asciinema 录制终端用的格式——JSON 行,一个头对象,然后每帧一个 [时间, "o", 数据] 数组——它始终是*文本*,所以 GIF 几兆字节时它只有几千字节,看的人还能选中并复制屏幕上的内容。这里按公开的规范实现。目的地播放不了终端录像时,GIF 是正确答案,大多数地方都是这样。

那些程序生成效果——是你们写的吗?

代码是;技法更早,页面上标了出处。旋转的圆环是 Andy Sloane 的 donut.c 方法——z 缓冲让近的面赢,表面法线与固定光源点积来索引梯度——火焰是 Fabien Sanglard 整理过的 demoscene 效果。等离子、雨和正弦滚动是没有单一作者的民间技法,页面这样标了。每个效果都是帧号和种子的纯函数,同一个种子永远给出同一段动画。

能停掉一个很长的转换吗?

能,而且真的会停。转换在一个每帧之间都检查的 worker 里运行,所以取消是结束工作,不是藏起结果——这在手机上很要紧,差别是风扇再转一分钟。

可以从这些接进来

接下来

这些工具吃得下当前工具的产出,结果可以直接送过去。