3 of 9 barcodes using HTML5 canvas

3 of 9 bar codes are the easiest bar codes to create. Here, I’ll show you how to create ad-hoc 3 of 9 bar codes using javascript and html5 canvas. You can have bar codes on your web page! Does anyone remember the CueCat ?

Text to encode:

3 of 9 bar codes consist of a set of 43 characters. This implementation doesn’t accommodate checksums and is Code 39 rather than “Full Code 39” and so doesn’t support lowercase letters.

Each character in a code 39 bar code is represented by 9 elements each of which can be a bar or space. The first and last characters of a bar code must be the asterisk character, and each character in a bar code (except the last) is followed by a terminating narrow space element.

This code creates a bar code of a specified character string as an HTML5 canvas element and inserts it into a specified DIV element.

The JS file used to render the bar code can be viewed here: http://www.jlion.com/scripts/barcode.js

Here’s how it works:

function AddBarCode(targetID, text) {
    var home = document.getElementById(targetID);;
    ClearParentDiv(home);

    var barcode = new Barcode();
    home.appendChild(barcode.Draw(text, 15, 30, 55));

    home.style.width = barcode.FinalWidth();
    home.style.height = barcode.FinalHeight();
}

The AddBarCode function adds a 3 of 9 bar code, representing the value of the “text” parameter to the HTML element with an ID equal to “targetID”.

ClearParentDiv removes all child elements from the HTML element (here, to prevent barcodes from stacking up if you click on the “display” button multiple times). The intial width and height of the HTML element are set to “auto”, so after creating the bar code, we set them to the actual size of the bar code, to help with page formatting (no giant DIVs!)

The Draw function is what actually creates the bar code:

    this.Draw = function (barText, xPos, yPos, barHeight) {
        _xPos = xPos;
        _xCurPos = xPos;
        _yPos = yPos;
        _barHeight = barHeight;

        var bufferCanvas = document.createElement('canvas');
        bufferCanvas.width = window.innerWidth;
        bufferCanvas.height = window.innerHeight;

        var bufferContext = bufferCanvas.getContext("2d");

        DrawSingleChar(bufferContext, '*', false); //start indicator
        for (singleLetterPos = 0; singleLetterPos < barText.length; singleLetterPos++) {
            var oneChar = barText.substr(singleLetterPos, 1);
            DrawSingleChar(bufferContext, oneChar, false);
        }
        DrawSingleChar(bufferContext, '*', true); //stop indicator

        DrawLabel(bufferContext, barText);

        _finalWidth = (_xCurPos - _xPos) + 30;
        _finalHeight = _barHeight + 70; //Add margin for text to be printed below bar code

        DrawBox(bufferContext);

        var finalCanvas = document.createElement('canvas');
        finalCanvas.width = _finalWidth;
        finalCanvas.height = _finalHeight;
        var finalContext = finalCanvas.getContext('2d');

        finalContext.drawImage(bufferCanvas, 0, 0);

        return finalCanvas;
    }

We create a buffer the size of the window. Later, when we know the final size of the bar code, we copy the image created in the buffer to a canvas of that exact size, for display.

The DrawSingleChar function encapsulates the translation of ASCII character to 3 of 9 character.

    function DrawSingleChar(
        canv,
        oneChar,
        isLastChar)
    {
        var encodedValue = Encode(oneChar);

        for (singleBarPos = 0; singleBarPos < encodedValue.length; singleBarPos++) {
            var oneBar = encodedValue.substr(singleBarPos, 1);
            var multiplier = GetMultiplier(oneBar);
            var barColor = '';

            if (oneBar === 'N' || oneBar === 'W')
                barColor = BARBLACK;
            else if (oneBar === 'n' || oneBar === 'w')
                barColor = BARWHITE;

            DrawSingleBar(
                canv,
                BARWIDTH * multiplier,
                barColor
            );
        }

        if (!isLastChar)
        {
            //characters are seperated by a single narrow space
            DrawSingleBar(
                canv,
                BARWIDTH * 1,   //narrow
                BARWHITE
            );
        }
    }

The Encode function gets the sequence of thick and thin bars that corresponds to a specific character as a sequence of these four characters:

  • N = narrow black bar
  • W = wide black bar
  • n = narrow white bar
  • w = wide white bar

For example, the sequence of white and black bars corresponding to the “*” character would be: NwNnWnWnN

The GetMultiplier function translates wide bars “W” and “w” into 2*the width of narrow bars.

The DrawSingleBar function uses the HTML5 fillRect function to actually draw the bar on canvas.