【26】轻松制作简单 Shell 动画

本文基于 GNU General Public License v3.0 (GPL v3) 协议公开。

代码公开于 https://github.com/SteveHawk/Simple-Terminal-Animation

目标

这个项目的目的在于使用最基础的命令行工具,包括 cowsaylolcattoiletboxes,来制作一个简单的命令行动画,可以用于庆祝朋友的生日等用途。

这些工具的使用都非常简单,随便谷歌就可以找到非常多的使用教程,当然你也可以直接使用 man 来查看他们的文档。这么一来,我们就可以忽略太技术性的细节,更多的把时间花到剧情上。

不过话说回来,这种命令行动画的风格未必适合所有人,你得先确认下你的朋友喜欢这种风格。

成果

代码参见我的 Github repo:https://github.com/SteveHawk/Simple-Terminal-Animation

其实整个项目的核心只包含一个文件,即 A_MSTERY_STORY.sh。运行这个脚本,就会在控制台里输出一段基于对话的动画。故事是一只去寻找秘密宝藏的牛,最终找到了一块巨石,上面刻着生日快乐的话。至于这个故事的细节,可以直接阅读代码。由于用的都是非常简单易懂的指令,代码相对还是非常直观可读的。

怎么使用

怎么用这个动画给朋友一个惊喜?我有两个方案供参考。

一个方法是直接把 A_MYSTERY_STORY.sh 这个文件放到你朋友的电脑里,等着他/她发现。不过要这么做的话,你得确定你朋友的电脑能够正确运行这个脚本。(估计挺难的)

另一个方法是把动画录下来。我选择把动画录成一个 SVG 格式的动画。SVG 格式的优势就是可以非常非常容易的嵌入到网页中,大小小到可以忽略不计,不过会比较吃性能(CPU 和内存消耗都挺大)。当然你也可以选择录制成视频,并用别的方法发给你的朋友。

至于故事的内容,你当然可以选择直接用我现成写好的这个故事,你可以到代码的 351 行把名字改成你朋友的名字。如果你想对我的故事做一些改动甚至重写,也是完全可以的,代码是基于 GPL v3 协议开源的。

依赖

  • cowsay
  • lolcat
  • toilet
  • boxes
  • termtosvg (只有录制 SVG 才需要)

文件结构

代码总共有三个部分。

  1. 一些常用的函数。snc 用于暂停几秒并清空屏幕,bts 用于打印场景切换的动画,clear_stage 是在最开始清空屏幕并且隐藏光标,最后 clean_up 会清空屏幕,并且把光标恢复回来。
  2. 场景。我把三个场景以及对应的准备分开写到了六个函数里,这样能够更方便的调试。在场景里基本就是一堆的 cowsay。有时候我会用 toilet 打印一些标题和时间变换,最后会用 boxeslolcat 花里胡哨的打印出那个巨石的内容。
  3. 最后是主函数,用来调用所有的场景。

如何录制 SVG

在众多命令行录制工具里,我最终选择了 termtosvg。真的是个非常棒的工具。

安装完成以后,可以用这个指令录制:

1
termtosvg ./A_MYSTERY_STORY.svg -c './A_MYSTERY_STORY.sh' -D 5000 -g 85x35 -m 200 -t window_frame_js

不过在你录制的时候,可能需要修改下里面的参数。具体参数的含义可以直接参考他们 Github repo 里的文档。

需要额外指出的是,-m 这个参数非常重要。它代表最短帧的时长,默认为 1 毫秒。对于我们这里动画的需求,最短帧完全可以设置到比较大的 200 毫秒之类的数值,这样可以大大减小最终 SVG 文件的大小(我的例子是从 800+ KB 减到 300+ KB),可以提升最后渲染的性能。

把 SVG 内嵌在 Hugo 博客中

我博客框架用的是 Hugo,所以我只研究了怎么在 Hugo 中内嵌 SVG 动画。

参考文章:https://discourse.gohugo.io/t/embedding-inline-svg-in-content-markdown/7511/7

相关文档:https://gohugo.io/functions/readfile/https://gohugo.io/content-management/shortcodes/

我的方案对上面那个回答做了些修改。首先在你网站的根目录 $HUGO_SITE 下创建文件夹 $HUGO_SITE/layouts/shortcodes。在文件夹中新建一个文件 svg.html,然后在里面输入以下内容:

1
2
3
<figure align="center">
{{ readFile (index .Params 0) | safeHTML }}
</figure>

然后你就可以在你的 Markdown 文件中这样引用你的 SVG 文件了:

1
{{< svg "svg/A_MYSTERY_STORY.svg" >}}

双引号里面的是 SVG 文件相对网站根目录的路径。这里我把 SVG 文件放在了 $HUGO_SITE/svg/A_MYSTERY_STORY.svg,你当然可以选择别的地方。需要注意的是,SVG 文件本身不需要在网站编译的时候被拷到 $HUGO_SITE/public 目录下,因为 SVG 文件的内容是被直接内嵌到最终生成的 HTML 文件中的。

直接生成的 SVG 文件的大小是写死像素的,可以到 SVG 文件的第一行把 width="***" 中的数字替换成百分比。

最终成果可以参考这个页面:https://stevehawk.tk/demo/a-mystery-story


本文阅读量
本站访客量