81 lines
1.9 KiB
JavaScript
81 lines
1.9 KiB
JavaScript
const Utils = require('./utils')
|
|
|
|
function getColorAttrib (color, attrib) {
|
|
const alpha = color.a / 255
|
|
const str = attrib + '="' + color.hex + '"'
|
|
|
|
return alpha < 1
|
|
? str + ' ' + attrib + '-opacity="' + alpha.toFixed(2).slice(1) + '"'
|
|
: str
|
|
}
|
|
|
|
function svgCmd (cmd, x, y) {
|
|
let str = cmd + x
|
|
if (typeof y !== 'undefined') str += ' ' + y
|
|
|
|
return str
|
|
}
|
|
|
|
function qrToPath (data, size, margin) {
|
|
let path = ''
|
|
let moveBy = 0
|
|
let newRow = false
|
|
let lineLength = 0
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
const col = Math.floor(i % size)
|
|
const row = Math.floor(i / size)
|
|
|
|
if (!col && !newRow) newRow = true
|
|
|
|
if (data[i]) {
|
|
lineLength++
|
|
|
|
if (!(i > 0 && col > 0 && data[i - 1])) {
|
|
path += newRow
|
|
? svgCmd('M', col + margin, 0.5 + row + margin)
|
|
: svgCmd('m', moveBy, 0)
|
|
|
|
moveBy = 0
|
|
newRow = false
|
|
}
|
|
|
|
if (!(col + 1 < size && data[i + 1])) {
|
|
path += svgCmd('h', lineLength)
|
|
lineLength = 0
|
|
}
|
|
} else {
|
|
moveBy++
|
|
}
|
|
}
|
|
|
|
return path
|
|
}
|
|
|
|
exports.render = function render (qrData, options, cb) {
|
|
const opts = Utils.getOptions(options)
|
|
const size = qrData.modules.size
|
|
const data = qrData.modules.data
|
|
const qrcodesize = size + opts.margin * 2
|
|
|
|
const bg = !opts.color.light.a
|
|
? ''
|
|
: '<path ' + getColorAttrib(opts.color.light, 'fill') +
|
|
' d="M0 0h' + qrcodesize + 'v' + qrcodesize + 'H0z"/>'
|
|
|
|
const path =
|
|
'<path ' + getColorAttrib(opts.color.dark, 'stroke') +
|
|
' d="' + qrToPath(data, size, opts.margin) + '"/>'
|
|
|
|
const viewBox = 'viewBox="' + '0 0 ' + qrcodesize + ' ' + qrcodesize + '"'
|
|
|
|
const width = !opts.width ? '' : 'width="' + opts.width + '" height="' + opts.width + '" '
|
|
|
|
const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path + '</svg>\n'
|
|
|
|
if (typeof cb === 'function') {
|
|
cb(null, svgTag)
|
|
}
|
|
|
|
return svgTag
|
|
}
|