Haskell Diagrams GIF Animation
I am about ready to release LiterateX,
and I have finally pushed the develop
branch to GitHub!
GIF Animation
In the README, I include an animation that explains the project name much more elegantly than prose can. It replaces the “X” with a selection of supported languages, showing that the “X” is a variable name. LiterateX allows you to write literate source code for many languages.
Since LiterateX is a Haskell project, it makes sense to implement the
animation in Haskell. I used the diagrams
framework, using the diagrams-cairo
backend to generate the GIF animation. The source code, available in the
project/animation
directory, is pretty concise.
animation :: [(Diagram B, Int)]
= (mkFrame "X", 300) : [(mkFrame lang, 50) | lang <- langs]
animation where
mkFrame :: String -> Diagram B
mkFrame lang= baselineText ("Literate" ++ lang)
# font "Noto Sans"
# fontSizeL 0.5
# fc black
# translateX (-3)
# translateY (-0.25)
<> rect 6.5 1 # lw none # fc white # bg white
The mkFrame
function creates a single frame in the
animation, given the String
to append to “Literate”. The
background rectangle, white to match GitHub, has a height of 1 unit and
a width of 6.5 units, which provides sufficient space for the text in
all of the frames. The text is rendered in black with a font size of 0.5
units, making it easy to align left and center vertically using
translation.
The animation
function returns a list of frame and
duration pairs. The animation displays “LiterateX” for 3 seconds
followed by the text for each selected language for 0.5 seconds
each.
Resolved Issues
Unfortunately, the diagrams-cairo
backend does not have many options for the generated files. The default
background is black, and I am unable to find a way to set a different
background color. The white rectangle background in the diagram of each
frame is aliased, resulting in gray lines at the top and bottom of the
rendered GIF animation.
Unable to fix the issue on the Haskell side, I resorted to using an external program (Gifsicle) to crop the rendered GIF image. Since I am using an external program anyway, I was also able to reduce the number of colors in the image as well, greatly reducing the size of the image. (There are no color options, and the default use of the RGB color space is inappropriate for most diagrams the software is used to create!)
Nix
Currently, diagrams only
works with old versions of GHC. I tried using it with Stack, but compilation failed
on my system (with a C header file parsing error). Thankfully, I was
able to avoid that problem by using Nix
instead. All of the program dependencies are met thanks to pinning an
appropriate nixpkgs
revision and using cabal2nix.
It works fine on my system, but my current Nix derivation is not
sufficient to make it work on other systems because it does not include
dependencies that are not required by the program itself. The program
makes use of the Noto
Sans font (noto-fonts
),
Gifsicle (gifsicle
)
is used processing the rendered GIF image, and GNU Make is (optionally)
used as well.
While I know how to specify such dependencies in other types of Nix derivations, I am not sure how it should be done in the style of Nix derivation that I am using. I do not have time to get sidetracked by this issue now… I will research it later, or perhaps a friend will point me in the right direction!