Self–Drawing Barcode
Not all the barcodes end up being printed, some of them are simply displayed in browser. There are two main ways of getting them there:
- server–side rendering, where the barcode image is prepared on server and then sent to browser as an image;
- client–side rendering, where the barcode is rendered directly in browser.
There are many libraries and frameworks for both methods, but here we offer a framework–less implementation of client–side rendering by using a self–contained self–drawing SVG file.
Yes, by embedding Javascript code into SVG file we can make it draw itself.
This method is widely used for SVG animation, but not for barcodes. Let’s fix that! We’ll end up with a single self–drawing self–contained SVG file for QR codes, like the one below:
Here is the code used to display the image above:
<object data="qr.min.svg?data=hello, world" type="image/svg+xml" width="200" height="200">
</object>
The qr.min.svg file is just about 17Kb and contains everything you need to draw QR codes. Sounds interesting? Let’s do it step by step!
Simple SVG File
Here is a very simple SVG file we’ll be using as a template:
<?xml version="1.0" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
<g id="qrcode">
<line x1="0" y1="0" x2="200" y2="200" width="1" stroke="red"/>
<line x1="0" y1="200" x2="200" y2="0" width="1" stroke="red"/>
</g>
</svg>
And here’s what it looks like:
The image is made of two red lines defined by the <line> elements in the SVG file code. Now let’s change the SVG file to include some Javascript code to generate the line elements for us:
<?xml version="1.0" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
<g id="qrcode"/>
<script type="application/javascript">//<![CDATA[
function line(el, x1, y1, x2, y2, width, color) {
const nl = document.createElementNS("http://www.w3.org/2000/svg","line");
nl.setAttribute("x1", x1);
nl.setAttribute("y1", y1);
nl.setAttribute("x2", x2);
nl.setAttribute("y2", y2);
nl.setAttribute("width", width);
nl.setAttribute("stroke", color)
el.appendChild(nl);
}
const elem = document.getElementById("qrcode");
line(elem, 0, 0, 200, 200, 1, "red");
line(elem, 0, 200, 200, 0, 1, "red");
//]]>
</script>
</svg>
The code looks much longer now and although the resulting SVG looks the same:
we can now do much more with scripting. For instance if you change the last three lines to these:
const elem = document.getElementById("qrcode");
for (let i = -200; i < 200; i += 10) {
line(elem, 0, 0 + i, 200, 200 + i, 1, "red");
line(elem, 0, 200 + i, 200, 0 + i, 1, "red");
}
You’ll get a mesh of lines drawn by the SVG file itself:
Now let’s make it a little more interactive…
Parsing Input Parameters
The mesh image above is made like this in HTML:
<object data="qr-3.svg" type="image/svg+xml" width="200" height="200"></object>
Notice the data attribute points to the SVG file we’ve made. However, as with any other HTML resource we can pass some parameters after the file name:
<object data="qr-3.svg?color=green" type="image/svg+xml" width="200" height="200"></object>
Here we passed the color parameter with green as a value. Let’s now read it inside the SVG file. We’ll need this code:
const params = new URLSearchParams(window.location.search);
const color = params.get("color");
The first line reads all the parameters passed to the SVG file and the second line reads the color parameter out of them.
Now let’s change the last code snippet which draws a mesh to this:
const params = new URLSearchParams(window.location.search);
const color = params.get("color");
const elem = document.getElementById("qrcode");
for (let i = -200; i < 200; i += 10) {
line(elem, 0, 0 + i, 200, 200 + i, 1, color);
line(elem, 0, 200 + i, 200, 0 + i, 1, color);
}
and call it this way:
<object data="qr-4.svg?color=orange" type="image/svg+xml" width="200" height="200"></object>
the result is:
So we can read the input parameters and draw custom shapes with Javascript right inside the SVG file without any dependencies. Now we are ready to draw a QR code!
Drawing QR Code
We are not going to reinvent a wheel here and simply re–use the existing Javascript library for drawing QR codes by Kazuhiko Arase.
We’ll need a function for drawing filled rectangles:
function rect(el, x, y, width, height, color) {
const rc = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rc.setAttribute("x", x);
rc.setAttribute("y", y);
rc.setAttribute("width", width);
rc.setAttribute("height", height);
rc.setAttribute("fill", color)
el.appendChild(rc);
}
Now the main drawing code looks this way:
const elem = document.getElementById("qrcode");
const width = 200, height = 200;
const params = new URLSearchParams(window.location.search);
const data = params.get("data");
const cl = QRErrorCorrectLevel.H;
const qr = new QRCodeModel(_getTypeNumber(data, cl), cl);
qr.addData(data);
qr.make();
const count = qr.getModuleCount();
const cw = Math.floor(width / count);
const ch = Math.floor(height / count);
for (let row = 0; row < count; row++) {
for (let col = 0; col < count; col++) {
if (qr.isDark(row, col)) {
rect(elem, col * cw, row * ch, cw, ch, "black");
}
}
}
That’s a lot of code, but it actually is pretty simple: we read the barcode contents from a parameter, then create a QR code generator from the library we used and finally loop around all the cells of the barcode checking if they need to be filled up.
The real Javascript code contains some extra checks and errors processing. You can have a look at it here: qr.svg, or if you need the minified version: qr.min.svg.
Here are some examples of what you can do with this SVG file:
// Wi-Fi access point password
// WIFI:S:$SSID;P:$PASSWORD;;
<object data="qr.min.svg?data=WIFI:S:My Network;P:My Password;;" type="image/svg+xml" width="200" height="200"></object>
// Phone number
// tel:+NNNNNNNNNNNN
<object data="qr.min.svg?data=tel:+1234567890" type="image/svg+xml" width="200" height="200"></object>
// Map coordinates
// geo:+XXX,-YYY
<object data="qr.min.svg?data=geo:48.858222,2.2945" type="image/svg+xml" width="200" height="200"></object>
So basically anything you might want to present as a QR code can be done using this SVG file with a proper parameter. No libraries, no frameworks, no maintenance, just a single SVG file that draws itself. By the way, printing is also supported.
Limitations
The obvious limitation is that Javascript needs to be enabled in browser in order for this method to work. Here you decide for yourself if you need a backup barcode solution, but if browser doesn’t support scripting, you just get a blank space instead of the QR code with this file. No errors, no incorrect data. If the code is not the main thing on the page, it can be simply left as is.
The other limitation is that the SVG file needs a browser to work. If you open it with a viewer, load it to a vector editor or any other application — it will show nothing. Without the browser the script is not executed and the content is not drawn.
Finally, as you probably already noticed you need to use the <object> tag to display the SVG file instead of the <img> one. The problem is that browsers don’t run scripts inside SVG files loaded as images, so if you load the SVG file this way, you’ll get a blank space. That’s why the <object> tag is needed.
Can I Use That SVG?
Sure, you are very welcome to use the file as is or make the modifications you need. Please keep the original copyrights to respect the others’ work. Here are the links again: qr.svg, qr.min.svg.
You can see the same idea being used in our free QR online code generator.
More Barcode Tutorials
Installation
- Installation — how to install Barcode generator;
- License Activation — how to activate Barcode software with a license key.
Basics
- User Interface — Barcode user interface explained in details;
- Barcode Management — adding, renaming, cloning and deleting barcodes;
- Importing Barcodes — importing barcode images;
- Custom Texts — adding custom text elements to barcodes;
- Marks Panel — configuring border, margins and canvas of barcodes;
- Bar Width Reduction — adjusting barcodes to compensate for ink spread;
- Quiet Zone — making sure the barcodes can be scanned well.
EAN Barcodes
- Making EAN–13 Barcodes — standard point–of–sale barcodes;
- EAN–13 Calculator — how to compute EAN–13 check digits.
UPC Barcodes
- Making UPC–A Barcodes — learn to make UPC–A barcodes;
- Making UPC–E Barcodes — how to create UPC–E barcodes;
- UPC–A Calculator — compute check digits of UPC–A barcodes.
NDC Barcodes
- NDC Barcodes — learn about NDC barcodes and how to make them;
- NDC Barcode Check Digit Calculator — how to compute NDC check digits.
QR Code
- QR Code — how to make and configure the popular 2D barcodes;
- QR Code with Image — adding custom artwork to QR Code.
Other Barcodes
- ISBN Barcode Generator — how to make ISBN barcodes;
- BC412 Barcode — making barcodes for silicon wafers identification;
Export
- Transparent Barcodes — making barcodes with transparent background;
- PNG Barcodes — exporting barcodes to PNG format;
- Vector Barcodes — exporting barcodes to vector formats;
- Export.js — defining custom file names for exported barcodes.
Automation
- Batch Processing — how to batch–convert text data to barcodes;
- Command Line Processing — command line barcode generation.
Other
- Self–Drawing Barcode — drawing QR codes in browser with just an SVG file;
- Fake Barcodes — need a random barcode as a placeholder?