HackerTextJS is a small library that renders widgets like the three examples below:

It can render multiple widgets, each with a different frame rate, size, text, renderer strategy and text filter. In an HTML document, you define an object called hacker_text_config in the head section. The hacker text config object has the property targets, an array of widget descriptor objects. Each widget descriptor specifies at a minimum the htmlId (the ID of the target element), text (the display text) and rows (the number of rows to render). Below is an example of what the configuration object might look like for rendering three elements.

  <script type="text/javascript">
var hacker_text_config =
{
targets: [
{
htmlId: "hackertext",
text: "A_SPECTRE_HAUNTS_EUROPE_",
renderer: {
strategy: "RandomizedFrameRenderStrategy"
},
framerate: 3,
rows: 15
},
{
htmlId: "hackertexttwo",
text: "A_SPECTRE_OF_COMMUNISM_",
framerate: 5,
rows: 15
},
{
htmlId: "hackertextthree",
text: "A_SPECTRE_HAUNTS_EUROPE_",
framerate: 5,
text_character_filters: ['LeetSourceFilter'],
rows: 18
}
]
};
</script>


After the hacker_text_config object has been defined, hackertext.js can be imported. It will only start initialisation if it can find this config descriptor.

For each widget, Hackertext.js calculates the maximum character length of each line for the current style sheet, so if this is 116, the specified rows field is 15 and the framerate is 10, it will fill the element with 1740 (116 times 15) characters 10 times per second. The renderer sets up a circular iterator over the specified text for each widget. Frames are built sequentially, one character at a time. For each character it can choose to either take the next character from the iterator or output a noise character. The probability is controlled by a dynamically determined noise ratio. When the RandomizedFrameRenderStrategy renderer strategy is used without any parameters, the noise ratio is fixed at 50%; when the SinePhaseFrameRenderStrategy, the noise ratio is controlled by a fixed frequency sine wave. There are other settings, but the documentation covers it adequately I think.

HTML elements aren't really designed to operate like this and I was fully aware of this at the time, but I wanted to know if you could reliably use JS to completely fill a div with text in such a way that it didn't overflow or underflow and to then make it animate. The first widget uses a sine wave renderer, the middle widget uses a completely randomised renderer and the third widget uses a cosine renderer.

At runtime it injects a hidden element (no margin or padding) with a test string. It uses the width of the hidden element to calculate the average width of a character, then it looks at the width of the target element for each widget, dividing it by the width of a character to work out the char count for each line.

It also watches for window resize events, so that it can dynamically adjust the number of characters the renderer spits out for each line.