papnkukn/qrcode-svg

The output svg code can be more concise

kkocdko opened this issue · 2 comments

Before:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="250" height="250">
    <rect x="0" y="0" width="10" height="10" style="fill:#000000;shape-rendering:crispEdges;"/>
    <rect x="10" y="0" width="10" height="10" style="fill:#ffffff;shape-rendering:crispEdges;"/>
    <rect x="20" y="0" width="10" height="10" style="fill:#000000;shape-rendering:crispEdges;"/>
    ...

After

<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges" viewBox="0 0 250 250">
    <defs><path id="c" d="M0 0h10v10H0z"/></defs>
    <use x="0" y="0" href="#c"/>
    <use x="20" y="0" href="#c"/>
    ...

My method:

/**
 * Output to svg
 * @param  {number}   moduleLength   Every modules' length of side
 * @return {string}   Svg content string
 */
this.toSvg = function(moduleLength) {
    var moduleArr = this.qrcode.modules;
    var length = moduleArr.length;
    var svgContent = '';
    var viewBoxLengthStr = length * moduleLength;
    svgContent += `<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges" viewBox="0 0 ${viewBoxLengthStr} ${viewBoxLengthStr}"><defs><path id="c" d="M0 0h${moduleLength}v${moduleLength}H0z"/></defs>`;
    for (var y in moduleArr) {
        for (var x in moduleArr) {
            var module = moduleArr[x][y];
            if (module == true) {
                var coordinateX = x * moduleLength;
                var coordinateY = y * moduleLength;
                svgContent += `<use href="#c" x="${coordinateX}" y="${coordinateY}"/>`;
            }
        }
    }
    svgContent += '</svg>';
    return svgContent;
};

That could not work correctly if you have more than one svg on the same page: the second image is taking path from the first one. The path ID should be unique

@kkocdko thanks for contributing the pattern. For sure this technique will reduce the file size. However the issue is with some editors and converters not supporting or not properly rendering the SVG image when using defs and use elements.

Added in version 1.1.0