• Posted on: Aug 12, 2011
  • Tag:
  • Reactions: 9

> Text only dot matrix LCD animation


The other day I saw one of those dot matrix LCD animations you can easily spot on pinballs. Being an incurable nostalgic I wanted to replicate that retro effect using javascript, the first impulse was to go canvas but I soon after converted to a text-only version.

The first step is to find a nice, short, loopable animation. Deviantart is -as always- a great resource. I’ve found a very good one by khaosdog. I desaturated it, resized to 50×50 and exported all frames to PNG format.

The eight frames now need to be converted into a javascript readable format. PHP comes to rescue here. The following is the code I used.

$color = array();

for ($i=1; $i<9; $i++) {		// Get all 8 animation frames
	$img = imagecreatefrompng($i . ".png");		// Load png

	$width = imagesx($img);		// Get image width
	$height = imagesy($img);		// Get image height

	for ($y=0; $y<$height; $y++) {
		for($x=0; $x<$width; $x++) {
			$rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));		// Get pixel color at x,y
			$color[$i-1][] = round(10 / 255 * $rgb['red']);		// Convert RED to 0-10 value (compatible with CSS opacity)

file_put_contents('wolf-ani.js', 'var wolfAni=' . json_encode($color) . ';');		// Save JS object

What it does is to load the eight png files and convert them into a javascript object. The result is a 8 x 2500 matrix corresponding to the intensity of each pixel.

Next I need to create a text only pseudo LCD. It seemed logic to use the "•" character. Each dot will be 10 pixels wide so the full matrix width is 500 pixels (remember? the original animation is 50x50 pixels).

With a simple loop we create the matrix.

var display = document.getElementById('display');
function fillMatrix (val) {
	var out = '';
	for (i=0, l=wolfAni[0].length; i<l; i++) {
		out += '<em>' + val + '</em>';

	display.innerHTML = out;
	matrix = document.querySelectorAll('#display em');

val is defaulted to "•" but we can use any character.

The animation is simulated by changing the dots opacity. I get the pixel intensity from the javascript object I created with PHP and update the style.opacity of each element in the matrix.

function animate () {
	var opacity, i;
	for (i=0; i<2500; i++) {
		opacity = (1 + wolfAni[currentFrame][i]) / 10;
		if(opacity != matrix[i].style.opacity)
			matrix[i].style.opacity = opacity;
	if (currentFrame == wolfAni.length) currentFrame = 0;
	aniTimer = nextFrame(animate);

Repeat with requestAnimationFrame and you get a cool retro dot matrix animation using just text. It can (and should) be optimized, it's pretty CPU intensive as it is now, but still acceptable for a proof of concept. 30 minutes work, satisfaction for the rest of the day.

Enough blabbing, head to the demo page (should work on any decent browser). For the lazy ones, here's the end result video.

Update: it was inevitable! LCD matrix Nyan cat.

/Share the joy


  • Awesome! Completely random too, bored lately? :P

    Rinse and repeat for a longer animation?

    • a text ticker would be a nice experiment… but I’m not bored to that extent :)

  • Cool demo but I assume the low speed is because of the 2*2500 DOM interactions at every frame. It would be interesting to make a similar and probably speedier demo in canvas — sure, it would not be text, but the effect would be the same.

    • would be too easy with canvas :) anyway it can be further optimized to get better performance (eg: change color instead of opacity, remove text-shadow, remove the text character altogether and use just square elements with bg, …)

        • Author: Conexion
        • Posted on: 2011/11/21
        • At: 16:20

        Maybe rounded divs with a bit of padding?

    • Author: AP2
    • Posted on: 2011/08/14
    • At: 16:13

    The semicolon after the ‘if’ in animate() means the code is doing this:

    if(opacity != matrix[i].style.opacity)
    matrix[i].style.opacity = opacity;

  • Very nice. I love the fact that the code is so simple that even I can understand! Thanks.

    • Author: Roy Wood
    • Posted on: 2011/09/02
    • At: 23:39