I wrote some JavaScript to create single-line 3D text using the three.js library to render 3D on a canvas using WebGL. Three.js can already render text with its TextGeometry class, but I wanted something simpler: single-line fonts.
Regular fonts characters are usually outline fonts. These font files describe the outline of characters, and the outline is filled with a color. The fill is the only actual visible part.
In a single-line font the line itself is the visible part of the font. It makes for much simpler font files. Compare it to writing with a pen: It’s much quicker and simpler to directly write characters as lines than to draw them as outlined shapes and fill in the shapes.
Single-line fonts are also knowns as engraving fonts, stroke fonts, technical lettering fonts, pen plotter fonts or stick fonts.
Setup
Clone the repository from GitHub at:
https://github.com/hisschemoller/single-line-3d-text.git
To install and start do the usual:
$ yarn install $ yarn start
…and the app will be available at localhost:3009
Or see it here live on GitHub Pages:
https://hisschemoller.github.io/single-line-3d-text/
Asteroids
Searching for information on single-line fonts I found an interesting summary of single-line fonts by Lindsay Robert Wilson, which mentions the font used in Atari’s 1979 Asteroids game.
Atari programmer Ed Logg designed the original Asteroids font. More recently Trammell Hudson made a slightly adjusted version of the font for his own projects, of which he put the source file on GitHub.
Three.js implementation
The font description by Trammell Hudson is a C language file, but it was easy to translate to a JSON file with SVG paths for the characters:
const asteroids_char_t asteroids_font[] = { ['0' - 0x20] = { P(0,0), P(8,0), P(8,12), P(0,12), P(0,0), P(8,12), FONT_LAST }, ['1' - 0x20] = { P(4,0), P(4,12), P(3,10), FONT_LAST }, ['2' - 0x20] = { P(0,12), P(8,12), P(8,7), P(0,5), P(0,0), P(8,0), FONT_LAST },
{ "chars": { "0": "M0 12 L8 12 L8 0 L0 0 L0 12 L8 0", "1": "M4 12 L4 0 L3 2", "2": "M0 0 L8 0 L8 5 L0 7 L0 12 L8 12",
From there I could take some functions from ThreeJS’s SVGLoader to parse the SVG strings into Path objects, en then create Line objects for each character and align them horizontally as a line of text in a Group.
Very cheap and simple text. The only thing I don’t like about the LineBasicMaterial text is that lines can only be 1 pixel wide. I would have liked to be able to adjust the line thickness. I will try and see if I can change that at some point, but for now this code does what I need.