/*! qrcanvas v3.1.2 | ISC License */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _objectWithoutPropertiesLoose = require('@babel/runtime/helpers/objectWithoutPropertiesLoose'); var _extends = require('@babel/runtime/helpers/extends'); var qrcode = require('qrcode-generator'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e['default'] : e; } var _objectWithoutPropertiesLoose__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutPropertiesLoose); var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends); var qrcode__default = /*#__PURE__*/_interopDefaultLegacy(qrcode); var COLOR_BLACK = '#000'; var COLOR_WHITE = '#fff'; var helpers = { createCanvas: createCanvas, isCanvas: isCanvas, isDrawable: isDrawable, getCanvas: getCanvas, updateCanvas: updateCanvas, drawCanvas: drawCanvas, drawText: drawText }; function createCanvas(width, height) { var canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; return canvas; } function isCanvas(el) { return el instanceof HTMLCanvasElement; } function isDrawable(el) { return isCanvas(el) || el instanceof HTMLImageElement; } /** * @desc Create a new canvas. * @param {Int} width Width of the canvas. * @param {Int} height Height of the canvas. * @return {Canvas} */ function getCanvas(width, height) { return helpers.createCanvas(width, height == null ? width : height); } function updateCanvas(canvas, width, height) { if (canvas) { canvas.width = width; canvas.height = height == null ? width : height; return canvas; } return getCanvas(width, height); } /** * @desc Draw to the canvas with given image or colors. * @param {Canvas} canvas The canvas to initialize. * @param {Image | String | Array} data * @param {Object} options * cellSize: {Int} * clear: {Boolean} */ function drawCanvas(canvas, data, options) { if (options === void 0) { options = {}; } var _options = options, cellSize = _options.cellSize, context = _options.context, _options$clear = _options.clear, clear = _options$clear === void 0 ? true : _options$clear; var width = canvas.width, height = canvas.height; var queue = [data]; var ctx = context || canvas.getContext('2d'); if (clear) ctx.clearRect(0, 0, width, height); ctx.globalCompositeOperation = 'source-over'; while (queue.length) { var item = queue.shift(); if (Array.isArray(item)) { queue = item.concat(queue); } else if (item) { var obj = void 0; if (helpers.isDrawable(item)) { obj = { image: item }; } else if (typeof item === 'string') { obj = { style: item }; } else { obj = item; } var x = (obj.col == null ? obj.x : obj.col * cellSize) || 0; var y = (obj.row == null ? obj.y : obj.row * cellSize) || 0; if (x < 0) x += width; if (y < 0) y += width; var w = ('cols' in obj ? obj.cols * cellSize : obj.w) || width; var h = ('rows' in obj ? obj.rows * cellSize : obj.h) || width; if (obj.image) { ctx.drawImage(obj.image, x, y, w, h); } else { ctx.fillStyle = obj.style || 'black'; ctx.fillRect(x, y, w, h); } } } return canvas; } function drawText(text, options) { var _ref = options || {}, _ref$fontSize = _ref.fontSize, fontSize = _ref$fontSize === void 0 ? 64 : _ref$fontSize, _ref$fontStyle = _ref.fontStyle, fontStyle = _ref$fontStyle === void 0 ? '' : _ref$fontStyle, _ref$fontFamily = _ref.fontFamily, fontFamily = _ref$fontFamily === void 0 ? 'Cursive' : _ref$fontFamily, _ref$color = _ref.color, color = _ref$color === void 0 ? null : _ref$color, _ref$pad = _ref.pad, pad = _ref$pad === void 0 ? 8 : _ref$pad, _ref$padColor = _ref.padColor, padColor = _ref$padColor === void 0 ? COLOR_WHITE : _ref$padColor, _ref$mode = _ref.mode, mode = _ref$mode === void 0 ? 1 : _ref$mode; var canvas = getCanvas(1); var ctx = canvas.getContext('2d'); var padColorArr; if (padColor) { ctx.fillStyle = padColor; ctx.fillRect(0, 0, 1, 1); var _ctx$getImageData = ctx.getImageData(0, 0, 1, 1); padColorArr = _ctx$getImageData.data; if (!padColorArr[3]) padColorArr = null; } var height = fontSize + 2 * pad; var font = [fontStyle, fontSize + "px", fontFamily].filter(Boolean).join(' '); var resetContext = function resetContext() { ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.font = font; }; resetContext(); var width = Math.ceil(ctx.measureText(text).width) + 2 * pad; canvas.width = width; canvas.height = height; resetContext(); var fillText = function fillText() { ctx.fillStyle = color || COLOR_BLACK; ctx.fillText(text, width / 2, height / 2); }; if (mode === 1) { ctx.fillStyle = padColor; ctx.fillRect(0, 0, width, height); fillText(); } else { fillText(); if (padColorArr) { (function () { var imageData = ctx.getImageData(0, 0, width, height); var data = imageData.data; var total = width * height; var padded = []; var offset = 0; var _loop = function _loop(loop) { var current = []; var unique = {}; padded[offset] = current; offset = 1 - offset; var last = padded[offset]; if (!last) { last = []; for (var i = 0; i < total; i += 1) { last.push(i); } } last.forEach(function (i) { if (data[4 * i + 3]) { [i % width ? i - 1 : -1, (i + 1) % width ? i + 1 : -1, i - width, i + width].forEach(function (j) { var k = 4 * j; if (k >= 0 && k <= data.length && !unique[j]) { unique[j] = 1; current.push(j); } }); } }); current.forEach(function (i) { var j = 4 * i; if (!data[j + 3]) { for (var k = 0; k < 4; k += 1) { data[j + k] = padColorArr[k]; } } }); }; for (var loop = 0; loop < pad; loop += 1) { _loop(); } ctx.putImageData(imageData, 0, 0); })(); } } return canvas; } var effects = { "default": renderDefault, round: renderRound, fusion: renderFusion, spot: renderSpot }; function renderDefault(_ref) { var foreground = _ref.foreground, cellSize = _ref.cellSize, isDark = _ref.isDark, count = _ref.count; var getCanvas = helpers.getCanvas, drawCanvas = helpers.drawCanvas; var width = cellSize * count; var canvasMask = getCanvas(width); var context = canvasMask.getContext('2d'); context.fillStyle = COLOR_BLACK; drawCells({ cellSize: cellSize, count: count }, function (_ref2) { var i = _ref2.i, j = _ref2.j, x = _ref2.x, y = _ref2.y; if (isDark(i, j)) { context.fillRect(x, y, cellSize, cellSize); } }); var canvasFg = getCanvas(width); drawCanvas(canvasFg, foreground, { cellSize: cellSize }); var ctx = canvasFg.getContext('2d'); ctx.globalCompositeOperation = 'destination-in'; ctx.drawImage(canvasMask, 0, 0); return canvasFg; } function renderRound(_ref3, maskOptions) { var foreground = _ref3.foreground, cellSize = _ref3.cellSize, isDark = _ref3.isDark, count = _ref3.count; var getCanvas = helpers.getCanvas, drawCanvas = helpers.drawCanvas; var width = cellSize * count; var canvasMask = getCanvas(width); var _maskOptions$value = maskOptions.value, value = _maskOptions$value === void 0 ? 1 : _maskOptions$value; var radius = value * cellSize / 2; var context = canvasMask.getContext('2d'); context.fillStyle = COLOR_BLACK; drawCells({ cellSize: cellSize, count: count }, function (_ref4) { var i = _ref4.i, j = _ref4.j, x = _ref4.x, y = _ref4.y; if (isDark(i, j)) { context.beginPath(); context.moveTo(x + 0.5 * cellSize, y); drawCorner(context, x + cellSize, y, x + cellSize, y + 0.5 * cellSize, radius); drawCorner(context, x + cellSize, y + cellSize, x + 0.5 * cellSize, y + cellSize, radius); drawCorner(context, x, y + cellSize, x, y + 0.5 * cellSize, radius); drawCorner(context, x, y, x + 0.5 * cellSize, y, radius); // context.closePath(); context.fill(); } }); var canvasFg = getCanvas(width); drawCanvas(canvasFg, foreground, { cellSize: cellSize }); var ctx = canvasFg.getContext('2d'); ctx.globalCompositeOperation = 'destination-in'; ctx.drawImage(canvasMask, 0, 0); return canvasFg; } function renderFusion(_ref5, maskOptions) { var foreground = _ref5.foreground, cellSize = _ref5.cellSize, isDark = _ref5.isDark, count = _ref5.count; var getCanvas = helpers.getCanvas, drawCanvas = helpers.drawCanvas; var width = cellSize * count; var canvasMask = getCanvas(width); var context = canvasMask.getContext('2d'); context.fillStyle = COLOR_BLACK; var _maskOptions$value2 = maskOptions.value, value = _maskOptions$value2 === void 0 ? 1 : _maskOptions$value2; var radius = value * cellSize / 2; drawCells({ cellSize: cellSize, count: count }, function (_ref6) { var i = _ref6.i, j = _ref6.j, x = _ref6.x, y = _ref6.y; var corners = [0, 0, 0, 0]; // NW, NE, SE, SW if (isDark(i - 1, j)) { corners[0] += 1; corners[1] += 1; } if (isDark(i + 1, j)) { corners[2] += 1; corners[3] += 1; } if (isDark(i, j - 1)) { corners[0] += 1; corners[3] += 1; } if (isDark(i, j + 1)) { corners[1] += 1; corners[2] += 1; } if (isDark(i, j)) { if (isDark(i - 1, j - 1)) corners[0] += 1; if (isDark(i - 1, j + 1)) corners[1] += 1; if (isDark(i + 1, j + 1)) corners[2] += 1; if (isDark(i + 1, j - 1)) corners[3] += 1; context.beginPath(); context.moveTo(x + 0.5 * cellSize, y); drawCorner(context, x + cellSize, y, x + cellSize, y + 0.5 * cellSize, corners[1] ? 0 : radius); drawCorner(context, x + cellSize, y + cellSize, x + 0.5 * cellSize, y + cellSize, corners[2] ? 0 : radius); drawCorner(context, x, y + cellSize, x, y + 0.5 * cellSize, corners[3] ? 0 : radius); drawCorner(context, x, y, x + 0.5 * cellSize, y, corners[0] ? 0 : radius); // context.closePath(); context.fill(); } else { if (corners[0] === 2) { fillCorner(context, x, y + 0.5 * cellSize, x, y, x + 0.5 * cellSize, y, radius); } if (corners[1] === 2) { fillCorner(context, x + 0.5 * cellSize, y, x + cellSize, y, x + cellSize, y + 0.5 * cellSize, radius); } if (corners[2] === 2) { fillCorner(context, x + cellSize, y + 0.5 * cellSize, x + cellSize, y + cellSize, x + 0.5 * cellSize, y + cellSize, radius); } if (corners[3] === 2) { fillCorner(context, x + 0.5 * cellSize, y + cellSize, x, y + cellSize, x, y + 0.5 * cellSize, radius); } } }); var canvasFg = getCanvas(width); drawCanvas(canvasFg, foreground, { cellSize: cellSize }); var ctx = canvasFg.getContext('2d'); ctx.globalCompositeOperation = 'destination-in'; ctx.drawImage(canvasMask, 0, 0); return canvasFg; } function renderSpot(_ref7, maskOptions) { var foreground = _ref7.foreground, cellSize = _ref7.cellSize, isDark = _ref7.isDark, count = _ref7.count; var getCanvas = helpers.getCanvas, drawCanvas = helpers.drawCanvas; var width = cellSize * count; var canvasMask = getCanvas(width); var value = maskOptions.value, _maskOptions$foregrou = maskOptions.foregroundLight, foregroundLight = _maskOptions$foregrou === void 0 ? COLOR_WHITE : _maskOptions$foregrou; var context = canvasMask.getContext('2d'); var canvasLayer = getCanvas(width); var canvasFg = getCanvas(width); var ctxLayer = canvasLayer.getContext('2d'); [{ dark: true, foreground: foreground }, { dark: false, foreground: foregroundLight }].forEach(function (item) { context.fillStyle = COLOR_BLACK; context.clearRect(0, 0, width, width); drawCells({ cellSize: cellSize, count: count }, function (_ref8) { var i = _ref8.i, j = _ref8.j, x = _ref8.x, y = _ref8.y; if (isDark(i, j) ^ +!item.dark) { var fillSize; if (i <= 7 && j <= 7 || i <= 7 && count - j - 1 <= 7 || count - i - 1 <= 7 && j <= 7 || i + 5 <= count && i + 9 >= count && j + 5 <= count && j + 9 >= count || i === 7 || j === 7) { fillSize = 1 - 0.1 * value; } else { fillSize = 0.25; } var offset = (1 - fillSize) / 2; context.fillRect(x + offset * cellSize, y + offset * cellSize, fillSize * cellSize, fillSize * cellSize); } }); drawCanvas(canvasLayer, item.foreground, { cellSize: cellSize, context: ctxLayer }); ctxLayer.globalCompositeOperation = 'destination-in'; ctxLayer.drawImage(canvasMask, 0, 0); drawCanvas(canvasFg, canvasLayer, { cellSize: cellSize, clear: false }); }); return canvasFg; } function drawCells(_ref9, drawEach) { var cellSize = _ref9.cellSize, count = _ref9.count; for (var i = 0; i < count; i += 1) { for (var j = 0; j < count; j += 1) { var x = j * cellSize; var y = i * cellSize; drawEach({ i: i, j: j, x: x, y: y }); } } } function drawCorner(ctx, cornerX, cornerY, x, y, r) { if (r) { ctx.arcTo(cornerX, cornerY, x, y, r); } else { ctx.lineTo(cornerX, cornerY); ctx.lineTo(x, y); } } function fillCorner(context, startX, startY, cornerX, cornerY, destX, destY, radius) { context.beginPath(); context.moveTo(startX, startY); drawCorner(context, cornerX, cornerY, destX, destY, radius); context.lineTo(cornerX, cornerY); context.lineTo(startX, startY); // context.closePath(); context.fill(); } // Enable UTF_8 support qrcode__default.stringToBytes = qrcode__default.stringToBytesFuncs['UTF-8']; var DEFAULTS = { background: 'white', foreground: 'black', typeNumber: 0, correctLevel: 'L', data: '', padding: 0, resize: true }; var QRCanvasRenderer = /*#__PURE__*/function () { function QRCanvasRenderer(options) { var _this = this; this.options = _extends__default({}, DEFAULTS); this.cache = {}; this.isDark = function (i, j) { var _this$cache = _this.cache, qr = _this$cache.qr, count = _this$cache.count; if (i < 0 || i >= count || j < 0 || j >= count) return false; return qr.isDark(i, j); }; this.setOptions(options); } var _proto = QRCanvasRenderer.prototype; _proto.render = function render(canvas, config) { if (config === void 0) { config = {}; } var _this$options = this.options, background = _this$options.background, foreground = _this$options.foreground, padding = _this$options.padding, effect = _this$options.effect, logo = _this$options.logo, resize = _this$options.resize; var onRender = effects[effect.type] || effects["default"]; var count = this.cache.count; var drawCanvas = helpers.drawCanvas; var _config = config, size = _config.size; var canvasOut; var canvasBg; var canvasFg; // Prepare output canvas, resize it if cellSize or size is provided. { var _config2 = config, cellSize = _config2.cellSize; if (!canvas && !cellSize && !size) cellSize = 6; if (cellSize) size = count * cellSize + padding + padding; if (size) { canvasOut = resize || !canvas ? helpers.updateCanvas(canvas, size) : canvas; } else { size = canvas.width; canvasOut = canvas; } } var contentSize = size - padding - padding; // Create foreground and background layers on canvas { var _cellSize = Math.ceil(contentSize / count); var sketchSize = _cellSize * count; canvasBg = helpers.getCanvas(_cellSize * count); drawCanvas(canvasBg, background, { cellSize: _cellSize }); canvasFg = onRender(_extends__default({ foreground: foreground, cellSize: _cellSize, isDark: this.isDark }, this.cache), this.options.effect); // draw logo if (logo) { var logoLayer = _extends__default({}, logo); if (!logo.w && !logo.h && !logo.cols && !logo.rows) { var _ref = logo.image, width = _ref.width, height = _ref.height; var imageRatio = width / height; var posRatio = Math.min((count - 18) / count, 0.38); var h = Math.min(height, sketchSize * posRatio, sketchSize * posRatio / imageRatio); var w = h * imageRatio; var x = (sketchSize - w) / 2; var y = (sketchSize - h) / 2; logoLayer.w = w; logoLayer.h = h; logoLayer.x = x; logoLayer.y = y; } drawCanvas(canvasFg, logoLayer, { clear: false }); } } // Combine the layers drawCanvas(canvasOut, [{ image: canvasBg }, { image: canvasFg, x: padding, y: padding, w: contentSize, h: contentSize }]); return canvasOut; }; _proto.setOptions = function setOptions(options) { this.options = _extends__default({}, this.options, options); this.normalizeEffect(); this.normalizeLogo(); var _this$options2 = this.options, typeNumber = _this$options2.typeNumber, data = _this$options2.data, logo = _this$options2.logo; // L / M / Q / H var correctLevel = this.options.correctLevel; if (logo && ['Q', 'H'].indexOf(correctLevel) < 0) correctLevel = 'H'; var qr = qrcode__default(typeNumber, correctLevel); qr.addData(data || ''); qr.make(); var count = qr.getModuleCount(); this.cache = { qr: qr, count: count }; }; _proto.normalizeEffect = function normalizeEffect() { var effect = this.options.effect; if (typeof effect === 'string') { effect = { type: effect }; } this.options.effect = effect || {}; }; _proto.normalizeLogo = function normalizeLogo() { var isDrawable = helpers.isDrawable, drawText = helpers.drawText; var logo = this.options.logo; if (logo) { if (isDrawable(logo)) { logo = { image: logo }; } else if (!isDrawable(logo.image)) { if (typeof logo === 'string') { logo = { text: logo }; } if (typeof logo.text === 'string') { logo = { image: drawText(logo.text, logo.options) }; } else { logo = null; } } } this.options.logo = logo; }; return QRCanvasRenderer; }(); function qrcanvas(options) { var canvas = options.canvas, size = options.size, cellSize = options.cellSize, rest = _objectWithoutPropertiesLoose__default(options, ["canvas", "size", "cellSize"]); var renderer = new QRCanvasRenderer(rest); return renderer.render(canvas, { size: size, cellSize: cellSize }); } function setCanvasModule(canvasModule) { var Canvas = canvasModule.Canvas, Image = canvasModule.Image, createCanvas = canvasModule.createCanvas; var isCanvas = function isCanvas(el) { return el instanceof Canvas; }; var isDrawable = function isDrawable(el) { return isCanvas(el) || el instanceof Image; }; helpers.createCanvas = createCanvas; helpers.isCanvas = isCanvas; helpers.isDrawable = isDrawable; } exports.effects = effects; exports.helpers = helpers; exports.qrcanvas = qrcanvas; exports.setCanvasModule = setCanvasModule;