It’s easy to generate a QR code but here is simple way to add a bit of fun to its reveal animation.
Bitmap image
QR code or Quick Response code is a 2D barcode that contains information, most usely an URL.
We can easily get one with the Google API but it’s only a PNG bitmap image.
Just replace put whatever text you want to share at the end of this URL, after chl=
: https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=http://views.thenew.fr/posts/generate-and-animate-a-qr-code
and you will get your visual matrix code:
SVG
But many libraries exist to generate it ourself and therefore choose the output format.
SVG is better than a PNG: we can zoom on it as much as we want, it will stay sharp and it’s so much lighter, because it’s vector graphics.
For example, in JavaScript, with node-qrcode:
// JavaScript
const QRCode = require("qrcode")
QRCode.toString(
// the URL to encode
"http://views.thenew.fr/posts/generate-and-animate-a-qr-code",
{
// the format
type: "svg"
},
function (err, url) {
// insert the SVG into the HTML element <div id="qrcode"></div>
document.getElementById("qrcode").innerHTML = url;
}
)
SVG images are XML files, so we can change the color easily directly in the code or with CSS. But this SVG is containing only one <path>
so there is no room to play with it.
Detailed SVG
The PHP QR Code library is also generating a QR code but the SVG output is defining every squares, this time.
// PHP
include 'lib/full/qrlib.php';
echo QRcode::svg("http://views.thenew.fr/posts/generate-and-animate-a-qr-code");
The SVG doesn’t have one path
but as many rect
as it has squares. The code is very big compared to the previous SVG but it’s the price to pay to be able to animate it.
To avoid code repetition, it uses the SVG elements use
and defs
.
<!-- HTML -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 264 264" title="QR Code to view [URL] on mobile">
<defs>
<rect id="p" width="8" height="8" />
</defs>
<g fill="#000102">
<use x="0" y="0" href="#p" /><use x="8" y="0" href="#p" /><use x="16" y="0" href="#p" /><use x="24" y="0" href="#p" /><use x="32" y="0" href="#p" /><use x="40" y="0" href="#p" /><use x="48" y="0" href="#p" /><use x="80" y="0" href="#p" /><use x="96" y="0" href="#p" /><use x="104" y="0" href="#p" /><use x="120" y="0" href="#p" /><use x="136" y="0" href="#p" /><use x="144" y="0" href="#p" /><use x="152" y="0" href="#p" /><use x="160" y="0" href="#p" /><use x="168" y="0" href="#p" /><use x="176" y="0" href="#p" /><use x="184" y="0" href="#p" /><use x="208" y="0" href="#p" /><use x="216" y="0" href="#p" /><use x="224" y="0" href="#p" /><use x="232" y="0" href="#p" /><use x="240" y="0" href="#p" /><use x="248" y="0" href="#p" /><use x="256" y="0" href="#p" /><use x="0" y="8" href="#p" /><use x="48" y="8" href="#p" /><use x="64" y="8" href="#p" /><use x="80" y="8" href="#p" /><use x="104" y="8" href="#p" /><use x="112" y="8" href="#p" /><use x="120" y="8" href="#p" /><use x="128" y="8" href="#p" /><use x="136" y="8" href="#p" /><use x="160" y="8" href="#p" /><use x="192" y="8" href="#p" /><use x="208" y="8" href="#p" /><use x="256" y="8" href="#p" /><use x="0" y="16" href="#p" /><use x="16" y="16" href="#p" /><use x="24" y="16" href="#p" /><use x="32" y="16" href="#p" /><use x="48" y="16" href="#p" /><use x="96" y="16" href="#p" /><use x="104" y="16" href="#p" /><use x="120" y="16" href="#p" /><use x="128" y="16" href="#p" /><use x="144" y="16" href="#p" /><use x="168" y="16" href="#p" /><use x="176" y="16" href="#p" /><use x="208" y="16" href="#p" /><use x="224" y="16" href="#p" /><use x="232" y="16" href="#p" /><use x="240" y="16" href="#p" /><use x="256" y="16" href="#p" /><use x="0" y="24" href="#p" /><use x="16" y="24" href="#p" /><use x="24" y="24" href="#p" /><use x="32" y="24" href="#p" /><use x="48" y="24" href="#p" /><use x="64" y="24" href="#p" /><use x="72" y="24" href="#p" /><use x="80" y="24" href="#p" /><use x="96" y="24" href="#p" /><use x="112" y="24" href="#p" /><use x="120" y="24" href="#p" /><use x="136" y="24" href="#p" /><use x="208" y="24" href="#p" /><use x="224" y="24" href="#p" /><use x="232" y="24" href="#p" /><use x="240" y="24" href="#p" /><use x="256" y="24" href="#p" /><use x="0" y="32" href="#p" /><use x="16" y="32" href="#p" /><use x="24" y="32" href="#p" /><use x="32" y="32" href="#p" /><use x="48" y="32" href="#p" /><use x="72" y="32" href="#p" /><use x="128" y="32" href="#p" /><use x="136" y="32" href="#p" /><use x="144" y="32" href="#p" /><use x="152" y="32" href="#p" /><use x="160" y="32" href="#p" /><use x="184" y="32" href="#p" /><use x="208" y="32" href="#p" /><use x="224" y="32" href="#p" /><use x="232" y="32" href="#p" /><use x="240" y="32" href="#p" /><use x="256" y="32" href="#p" /><use x="0" y="40" href="#p" /><use x="48" y="40" href="#p" /><use x="64" y="40" href="#p" /><use x="72" y="40" href="#p" /><use x="88" y="40" href="#p" /><use x="96" y="40" href="#p" /><use x="120" y="40" href="#p" /><use x="144" y="40" href="#p" /><use x="160" y="40" href="#p" /><use x="176" y="40" href="#p" /><use x="208" y="40" href="#p" /><use x="256" y="40" href="#p" /><use x="0" y="48" href="#p" /><use x="8" y="48" href="#p" /><use x="16" y="48" href="#p" /><use x="24" y="48" href="#p" /><use x="32" y="48" href="#p" /><use x="40" y="48" href="#p" /><use x="48" y="48" href="#p" /><use x="64" y="48" href="#p" /><use x="80" y="48" href="#p" /><use x="96" y="48" href="#p" /><use x="112" y="48" href="#p" /><use x="128" y="48" href="#p" /><use x="144" y="48" href="#p" /><use x="160" y="48" href="#p" /><use x="176" y="48" href="#p" /><use x="192" y="48" href="#p" /><use x="208" y="48" href="#p" /><use x="216" y="48" href="#p" /><use x="224" y="48" href="#p" /><use x="232" y="48" href="#p" /><use x="240" y="48" href="#p" /><use x="248" y="48" href="#p" /><use x="256" y="48" href="#p" /><use x="72" y="56" href="#p" /><use x="80" y="56" href="#p" /><use x="88" y="56" href="#p" /><use x="112" y="56" href="#p" /><use x="120" y="56" href="#p" /><use x="128" y="56" href="#p" /><use x="160" y="56" href="#p" /><use x="168" y="56" href="#p" /><use x="176" y="56" href="#p" /><use x="184" y="56" href="#p" /><use x="192" y="56" href="#p" /><use x="0" y="64" href="#p" /><use x="8" y="64" href="#p" /><use x="16" y="64" href="#p" /><use x="24" y="64" href="#p" /><use x="32" y="64" href="#p" /><use x="48" y="64" href="#p" /><use x="56" y="64" href="#p" /><use x="64" y="64" href="#p" /><use x="72" y="64" href="#p" /><use x="88" y="64" href="#p" /><use x="120" y="64" href="#p" /><use x="136" y="64" href="#p" /><use x="152" y="64" href="#p" /><use x="176" y="64" href="#p" /><use x="200" y="64" href="#p" /><use x="216" y="64" href="#p" /><use x="232" y="64" href="#p" /><use x="248" y="64" href="#p" /><use x="24" y="72" href="#p" /><use x="56" y="72" href="#p" /><use x="80" y="72" href="#p" /><use x="96" y="72" href="#p" /><use x="104" y="72" href="#p" /><use x="112" y="72" href="#p" /><use x="128" y="72" href="#p" /><use x="136" y="72" href="#p" /><use x="144" y="72" href="#p" /><use x="152" y="72" href="#p" /><use x="168" y="72" href="#p" /><use x="184" y="72" href="#p" /><use x="208" y="72" href="#p" /><use x="248" y="72" href="#p" /><use x="256" y="72" href="#p" /><use x="0" y="80" href="#p" /><use x="32" y="80" href="#p" /><use x="48" y="80" href="#p" /><use x="56" y="80" href="#p" /><use x="80" y="80" href="#p" /><use x="104" y="80" href="#p" /><use x="112" y="80" href="#p" /><use x="120" y="80" href="#p" /><use x="128" y="80" href="#p" /><use x="176" y="80" href="#p" /><use x="200" y="80" href="#p" /><use x="216" y="80" href="#p" /><use x="0" y="88" href="#p" /><use x="16" y="88" href="#p" /><use x="24" y="88" href="#p" /><use x="64" y="88" href="#p" /><use x="96" y="88" href="#p" /><use x="104" y="88" href="#p" /><use x="128" y="88" href="#p" /><use x="160" y="88" href="#p" /><use x="168" y="88" href="#p" /><use x="176" y="88" href="#p" /><use x="184" y="88" href="#p" /><use x="200" y="88" href="#p" /><use x="216" y="88" href="#p" /><use x="224" y="88" href="#p" /><use x="240" y="88" href="#p" /><use x="0" y="96" href="#p" /><use x="8" y="96" href="#p" /><use x="32" y="96" href="#p" /><use x="40" y="96" href="#p" /><use x="48" y="96" href="#p" /><use x="64" y="96" href="#p" /><use x="72" y="96" href="#p" /><use x="80" y="96" href="#p" /><use x="96" y="96" href="#p" /><use x="112" y="96" href="#p" /><use x="136" y="96" href="#p" /><use x="176" y="96" href="#p" /><use x="184" y="96" href="#p" /><use x="192" y="96" href="#p" /><use x="200" y="96" href="#p" /><use x="216" y="96" href="#p" /><use x="224" y="96" href="#p" /><use x="0" y="104" href="#p" /><use x="8" y="104" href="#p" /><use x="24" y="104" href="#p" /><use x="64" y="104" href="#p" /><use x="72" y="104" href="#p" /><use x="128" y="104" href="#p" /><use x="144" y="104" href="#p" /><use x="152" y="104" href="#p" /><use x="160" y="104" href="#p" /><use x="168" y="104" href="#p" /><use x="184" y="104" href="#p" /><use x="208" y="104" href="#p" /><use x="232" y="104" href="#p" /><use x="248" y="104" href="#p" /><use x="256" y="104" href="#p" /><use x="8" y="112" href="#p" /><use x="32" y="112" href="#p" /><use x="48" y="112" href="#p" /><use x="64" y="112" href="#p" /><use x="80" y="112" href="#p" /><use x="88" y="112" href="#p" /><use x="96" y="112" href="#p" /><use x="120" y="112" href="#p" /><use x="128" y="112" href="#p" /><use x="144" y="112" href="#p" /><use x="168" y="112" href="#p" /><use x="176" y="112" href="#p" /><use x="192" y="112" href="#p" /><use x="200" y="112" href="#p" /><use x="208" y="112" href="#p" /><use x="216" y="112" href="#p" /><use x="232" y="112" href="#p" /><use x="248" y="112" href="#p" /><use x="0" y="120" href="#p" /><use x="8" y="120" href="#p" /><use x="16" y="120" href="#p" /><use x="24" y="120" href="#p" /><use x="32" y="120" href="#p" /><use x="40" y="120" href="#p" /><use x="72" y="120" href="#p" /><use x="88" y="120" href="#p" /><use x="112" y="120" href="#p" /><use x="152" y="120" href="#p" /><use x="160" y="120" href="#p" /><use x="168" y="120" href="#p" /><use x="176" y="120" href="#p" /><use x="192" y="120" href="#p" /><use x="208" y="120" href="#p" /><use x="240" y="120" href="#p" /><use x="16" y="128" href="#p" /><use x="24" y="128" href="#p" /><use x="40" y="128" href="#p" /><use x="48" y="128" href="#p" /><use x="56" y="128" href="#p" /><use x="72" y="128" href="#p" /><use x="80" y="128" href="#p" /><use x="88" y="128" href="#p" /><use x="120" y="128" href="#p" /><use x="136" y="128" href="#p" /><use x="152" y="128" href="#p" /><use x="176" y="128" href="#p" /><use x="200" y="128" href="#p" /><use x="224" y="128" href="#p" /><use x="248" y="128" href="#p" /><use x="16" y="136" href="#p" /><use x="32" y="136" href="#p" /><use x="56" y="136" href="#p" /><use x="72" y="136" href="#p" /><use x="96" y="136" href="#p" /><use x="104" y="136" href="#p" /><use x="112" y="136" href="#p" /><use x="128" y="136" href="#p" /><use x="152" y="136" href="#p" /><use x="160" y="136" href="#p" /><use x="184" y="136" href="#p" /><use x="208" y="136" href="#p" /><use x="232" y="136" href="#p" /><use x="248" y="136" href="#p" /><use x="256" y="136" href="#p" /><use x="16" y="144" href="#p" /><use x="40" y="144" href="#p" /><use x="48" y="144" href="#p" /><use x="56" y="144" href="#p" /><use x="72" y="144" href="#p" /><use x="104" y="144" href="#p" /><use x="112" y="144" href="#p" /><use x="120" y="144" href="#p" /><use x="128" y="144" href="#p" /><use x="160" y="144" href="#p" /><use x="176" y="144" href="#p" /><use x="200" y="144" href="#p" /><use x="216" y="144" href="#p" /><use x="224" y="144" href="#p" /><use x="232" y="144" href="#p" /><use x="248" y="144" href="#p" /><use x="0" y="152" href="#p" /><use x="16" y="152" href="#p" /><use x="24" y="152" href="#p" /><use x="64" y="152" href="#p" /><use x="72" y="152" href="#p" /><use x="96" y="152" href="#p" /><use x="104" y="152" href="#p" /><use x="120" y="152" href="#p" /><use x="128" y="152" href="#p" /><use x="144" y="152" href="#p" /><use x="168" y="152" href="#p" /><use x="184" y="152" href="#p" /><use x="200" y="152" href="#p" /><use x="224" y="152" href="#p" /><use x="232" y="152" href="#p" /><use x="240" y="152" href="#p" /><use x="8" y="160" href="#p" /><use x="16" y="160" href="#p" /><use x="24" y="160" href="#p" /><use x="32" y="160" href="#p" /><use x="48" y="160" href="#p" /><use x="56" y="160" href="#p" /><use x="72" y="160" href="#p" /><use x="80" y="160" href="#p" /><use x="96" y="160" href="#p" /><use x="112" y="160" href="#p" /><use x="136" y="160" href="#p" /><use x="176" y="160" href="#p" /><use x="184" y="160" href="#p" /><use x="192" y="160" href="#p" /><use x="200" y="160" href="#p" /><use x="216" y="160" href="#p" /><use x="224" y="160" href="#p" /><use x="232" y="160" href="#p" /><use x="248" y="160" href="#p" /><use x="0" y="168" href="#p" /><use x="16" y="168" href="#p" /><use x="64" y="168" href="#p" /><use x="80" y="168" href="#p" /><use x="144" y="168" href="#p" /><use x="152" y="168" href="#p" /><use x="160" y="168" href="#p" /><use x="168" y="168" href="#p" /><use x="184" y="168" href="#p" /><use x="192" y="168" href="#p" /><use x="200" y="168" href="#p" /><use x="208" y="168" href="#p" /><use x="216" y="168" href="#p" /><use x="232" y="168" href="#p" /><use x="240" y="168" href="#p" /><use x="248" y="168" href="#p" /><use x="256" y="168" href="#p" /><use x="0" y="176" href="#p" /><use x="16" y="176" href="#p" /><use x="40" y="176" href="#p" /><use x="48" y="176" href="#p" /><use x="56" y="176" href="#p" /><use x="64" y="176" href="#p" /><use x="88" y="176" href="#p" /><use x="96" y="176" href="#p" /><use x="120" y="176" href="#p" /><use x="160" y="176" href="#p" /><use x="168" y="176" href="#p" /><use x="176" y="176" href="#p" /><use x="192" y="176" href="#p" /><use x="200" y="176" href="#p" /><use x="224" y="176" href="#p" /><use x="248" y="176" href="#p" /><use x="0" y="184" href="#p" /><use x="24" y="184" href="#p" /><use x="64" y="184" href="#p" /><use x="72" y="184" href="#p" /><use x="88" y="184" href="#p" /><use x="112" y="184" href="#p" /><use x="160" y="184" href="#p" /><use x="168" y="184" href="#p" /><use x="176" y="184" href="#p" /><use x="184" y="184" href="#p" /><use x="192" y="184" href="#p" /><use x="200" y="184" href="#p" /><use x="208" y="184" href="#p" /><use x="216" y="184" href="#p" /><use x="232" y="184" href="#p" /><use x="240" y="184" href="#p" /><use x="0" y="192" href="#p" /><use x="16" y="192" href="#p" /><use x="32" y="192" href="#p" /><use x="48" y="192" href="#p" /><use x="56" y="192" href="#p" /><use x="64" y="192" href="#p" /><use x="72" y="192" href="#p" /><use x="80" y="192" href="#p" /><use x="88" y="192" href="#p" /><use x="120" y="192" href="#p" /><use x="128" y="192" href="#p" /><use x="136" y="192" href="#p" /><use x="144" y="192" href="#p" /><use x="152" y="192" href="#p" /><use x="176" y="192" href="#p" /><use x="192" y="192" href="#p" /><use x="200" y="192" href="#p" /><use x="208" y="192" href="#p" /><use x="216" y="192" href="#p" /><use x="224" y="192" href="#p" /><use x="256" y="192" href="#p" /><use x="64" y="200" href="#p" /><use x="72" y="200" href="#p" /><use x="80" y="200" href="#p" /><use x="96" y="200" href="#p" /><use x="104" y="200" href="#p" /><use x="112" y="200" href="#p" /><use x="128" y="200" href="#p" /><use x="136" y="200" href="#p" /><use x="144" y="200" href="#p" /><use x="152" y="200" href="#p" /><use x="168" y="200" href="#p" /><use x="176" y="200" href="#p" /><use x="184" y="200" href="#p" /><use x="192" y="200" href="#p" /><use x="224" y="200" href="#p" /><use x="256" y="200" href="#p" /><use x="0" y="208" href="#p" /><use x="8" y="208" href="#p" /><use x="16" y="208" href="#p" /><use x="24" y="208" href="#p" /><use x="32" y="208" href="#p" /><use x="40" y="208" href="#p" /><use x="48" y="208" href="#p" /><use x="64" y="208" href="#p" /><use x="72" y="208" href="#p" /><use x="104" y="208" href="#p" /><use x="112" y="208" href="#p" /><use x="120" y="208" href="#p" /><use x="128" y="208" href="#p" /><use x="160" y="208" href="#p" /><use x="184" y="208" href="#p" /><use x="192" y="208" href="#p" /><use x="208" y="208" href="#p" /><use x="224" y="208" href="#p" /><use x="232" y="208" href="#p" /><use x="240" y="208" href="#p" /><use x="248" y="208" href="#p" /><use x="0" y="216" href="#p" /><use x="48" y="216" href="#p" /><use x="80" y="216" href="#p" /><use x="96" y="216" href="#p" /><use x="104" y="216" href="#p" /><use x="120" y="216" href="#p" /><use x="160" y="216" href="#p" /><use x="168" y="216" href="#p" /><use x="184" y="216" href="#p" /><use x="192" y="216" href="#p" /><use x="224" y="216" href="#p" /><use x="232" y="216" href="#p" /><use x="240" y="216" href="#p" /><use x="248" y="216" href="#p" /><use x="256" y="216" href="#p" /><use x="0" y="224" href="#p" /><use x="16" y="224" href="#p" /><use x="24" y="224" href="#p" /><use x="32" y="224" href="#p" /><use x="48" y="224" href="#p" /><use x="64" y="224" href="#p" /><use x="72" y="224" href="#p" /><use x="96" y="224" href="#p" /><use x="112" y="224" href="#p" /><use x="120" y="224" href="#p" /><use x="128" y="224" href="#p" /><use x="136" y="224" href="#p" /><use x="176" y="224" href="#p" /><use x="192" y="224" href="#p" /><use x="200" y="224" href="#p" /><use x="208" y="224" href="#p" /><use x="216" y="224" href="#p" /><use x="224" y="224" href="#p" /><use x="256" y="224" href="#p" /><use x="0" y="232" href="#p" /><use x="16" y="232" href="#p" /><use x="24" y="232" href="#p" /><use x="32" y="232" href="#p" /><use x="48" y="232" href="#p" /><use x="64" y="232" href="#p" /><use x="72" y="232" href="#p" /><use x="128" y="232" href="#p" /><use x="144" y="232" href="#p" /><use x="152" y="232" href="#p" /><use x="160" y="232" href="#p" /><use x="168" y="232" href="#p" /><use x="224" y="232" href="#p" /><use x="232" y="232" href="#p" /><use x="240" y="232" href="#p" /><use x="248" y="232" href="#p" /><use x="256" y="232" href="#p" /><use x="0" y="240" href="#p" /><use x="16" y="240" href="#p" /><use x="24" y="240" href="#p" /><use x="32" y="240" href="#p" /><use x="48" y="240" href="#p" /><use x="64" y="240" href="#p" /><use x="80" y="240" href="#p" /><use x="88" y="240" href="#p" /><use x="96" y="240" href="#p" /><use x="120" y="240" href="#p" /><use x="128" y="240" href="#p" /><use x="144" y="240" href="#p" /><use x="168" y="240" href="#p" /><use x="184" y="240" href="#p" /><use x="192" y="240" href="#p" /><use x="208" y="240" href="#p" /><use x="232" y="240" href="#p" /><use x="240" y="240" href="#p" /><use x="0" y="248" href="#p" /><use x="48" y="248" href="#p" /><use x="64" y="248" href="#p" /><use x="88" y="248" href="#p" /><use x="112" y="248" href="#p" /><use x="120" y="248" href="#p" /><use x="128" y="248" href="#p" /><use x="160" y="248" href="#p" /><use x="168" y="248" href="#p" /><use x="176" y="248" href="#p" /><use x="200" y="248" href="#p" /><use x="208" y="248" href="#p" /><use x="224" y="248" href="#p" /><use x="232" y="248" href="#p" /><use x="240" y="248" href="#p" /><use x="0" y="256" href="#p" /><use x="8" y="256" href="#p" /><use x="16" y="256" href="#p" /><use x="24" y="256" href="#p" /><use x="32" y="256" href="#p" /><use x="40" y="256" href="#p" /><use x="48" y="256" href="#p" /><use x="64" y="256" href="#p" /><use x="88" y="256" href="#p" /><use x="136" y="256" href="#p" /><use x="144" y="256" href="#p" /><use x="160" y="256" href="#p" /><use x="176" y="256" href="#p" /><use x="184" y="256" href="#p" /><use x="192" y="256" href="#p" /><use x="208" y="256" href="#p" /><use x="232" y="256" href="#p" /><use x="248" y="256" href="#p" />
</g>
</svg>
By changing the styles of this use
elements in CSS, we can animate them randomly from one state to another.
/* CSS */
.qrcode use {
opacity: 0.01; /* hide */
transition: opacity 0.05s ease;
}
.qrcode.active use {
opacity: 1; /* show */
}
/* Add delay to random squares */
.qrcode.active use:nth-child(2n) {
transition-delay: 0.2s;
}
.qrcode.active use:nth-child(3n) {
transition-delay: 0.1s;
}
.qrcode.active use:nth-child(4n) {
transition-delay: 0.4s;
}
.qrcode.active use:nth-child(5n) {
transition-delay: 0.3s;
}
A bit of JavaScript is adding the .active
class and voila!
Misc
-
Google Chrome recently added an option to create a QR code for the current page in the right click menu but we can only download it as a poor quality, branded PNG.
-
Worth noting, the longer the text or URL we are encoding in the QR Code, more complex it will be. So we can have a smaller Flash code, with less rows and columns, by using a URL shortener, for example.
-
I think the average person is still ignoring QR code as the adoption is still really slow after years of uses in many communication support. I guess it’s just not appealing to scan a gibberish splatter of black and white dots.
I believe it should be replaced in medium term by a human and machine-readable URL as many modern smartphone can scan text now so the URL would be displayed with some specific graphics around to help the machine to scan. -
Don’t forget to add a
title
attribute to a SVG to make it accesible.
Fin