parent
ac0af48d8e
commit
86948f725f
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
env:
|
|
||||||
browser: true
|
|
||||||
|
|
||||||
rules:
|
|
||||||
func-names: 0
|
|
||||||
no-var: 0
|
|
||||||
prefer-arrow-callback: 0
|
|
||||||
strict: 0
|
|
@ -1,84 +1,86 @@
|
|||||||
(function () {
|
const WIN = window; // eslint-disable-line no-undef
|
||||||
'use strict';
|
const JQ = WIN.jQuery;
|
||||||
|
|
||||||
var jq = window.jQuery;
|
|
||||||
var guiValuePairs = [
|
|
||||||
['size', 'px'],
|
|
||||||
['minversion', ''],
|
|
||||||
['quiet', ' modules'],
|
|
||||||
['radius', '%'],
|
|
||||||
['msize', '%'],
|
|
||||||
['mposx', '%'],
|
|
||||||
['mposy', '%']
|
|
||||||
];
|
|
||||||
|
|
||||||
function updateGui() {
|
|
||||||
jq.each(guiValuePairs, function (idx, pair) {
|
|
||||||
var $label = jq('label[for="' + pair[0] + '"]');
|
|
||||||
$label.text($label.text().replace(/:.*/, ': ' + jq('#' + pair[0]).val() + pair[1]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateQrCode() {
|
const GUI_VALUE_PAIRS = [
|
||||||
var options = {
|
['size', 'px'],
|
||||||
render: jq('#render').val(),
|
['minversion', ''],
|
||||||
ecLevel: jq('#eclevel').val(),
|
['quiet', ' modules'],
|
||||||
minVersion: parseInt(jq('#minversion').val(), 10),
|
['radius', '%'],
|
||||||
|
['msize', '%'],
|
||||||
|
['mposx', '%'],
|
||||||
|
['mposy', '%']
|
||||||
|
];
|
||||||
|
|
||||||
fill: jq('#fill').val(),
|
const update_gui = () => {
|
||||||
background: jq('#background').val(),
|
JQ.each(GUI_VALUE_PAIRS, (idx, pair) => {
|
||||||
// fill: jq('#img-buffer')[0],
|
const $label = JQ('label[for="' + pair[0] + '"]');
|
||||||
|
$label.text($label.text().replace(/:.*/, ': ' + JQ('#' + pair[0]).val() + pair[1]));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
text: jq('#text').val(),
|
const update_qrcode = () => {
|
||||||
size: parseInt(jq('#size').val(), 10),
|
const options = {
|
||||||
radius: parseInt(jq('#radius').val(), 10) * 0.01,
|
render: JQ('#render').val(),
|
||||||
quiet: parseInt(jq('#quiet').val(), 10),
|
ecLevel: JQ('#eclevel').val(),
|
||||||
|
minVersion: parseInt(JQ('#minversion').val(), 10),
|
||||||
|
|
||||||
mode: parseInt(jq('#mode').val(), 10),
|
fill: JQ('#fill').val(),
|
||||||
|
background: JQ('#background').val(),
|
||||||
|
|
||||||
mSize: parseInt(jq('#msize').val(), 10) * 0.01,
|
text: JQ('#text').val(),
|
||||||
mPosX: parseInt(jq('#mposx').val(), 10) * 0.01,
|
size: parseInt(JQ('#size').val(), 10),
|
||||||
mPosY: parseInt(jq('#mposy').val(), 10) * 0.01,
|
radius: parseInt(JQ('#radius').val(), 10) * 0.01,
|
||||||
|
quiet: parseInt(JQ('#quiet').val(), 10),
|
||||||
|
|
||||||
label: jq('#label').val(),
|
mode: parseInt(JQ('#mode').val(), 10),
|
||||||
fontname: jq('#font').val(),
|
|
||||||
fontcolor: jq('#fontcolor').val(),
|
|
||||||
|
|
||||||
image: jq('#img-buffer')[0]
|
mSize: parseInt(JQ('#msize').val(), 10) * 0.01,
|
||||||
};
|
mPosX: parseInt(JQ('#mposx').val(), 10) * 0.01,
|
||||||
|
mPosY: parseInt(JQ('#mposy').val(), 10) * 0.01,
|
||||||
|
|
||||||
jq('#container').empty().qrcode(options);
|
label: JQ('#label').val(),
|
||||||
}
|
fontname: JQ('#font').val(),
|
||||||
|
fontcolor: JQ('#fontcolor').val(),
|
||||||
|
|
||||||
function update() {
|
image: JQ('#img-buffer')[0]
|
||||||
updateGui();
|
};
|
||||||
updateQrCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onImageInput() {
|
// options.fill = JQ('#img-buffer')[0];
|
||||||
var input = jq('#image')[0];
|
// options.fill = 'rgba(255,0,0,0.5)';
|
||||||
if (input.files && input.files[0]) {
|
// options.background = JQ('#img-buffer')[0];
|
||||||
var reader = new FileReader();
|
// options.background = 'rgba(255,0,0,0.5)';
|
||||||
reader.onload = function (event) {
|
|
||||||
jq('#img-buffer').attr('src', event.target.result);
|
|
||||||
jq('#mode').val('4');
|
|
||||||
setTimeout(update, 250);
|
|
||||||
};
|
|
||||||
reader.readAsDataURL(input.files[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function download() {
|
JQ('#container').empty().qrcode(options);
|
||||||
jq('#download').attr('href', jq('#container canvas')[0].toDataURL('image/png'));
|
};
|
||||||
}
|
|
||||||
|
const update = () => {
|
||||||
|
update_gui();
|
||||||
|
update_qrcode();
|
||||||
|
};
|
||||||
|
|
||||||
function init() {
|
const on_img_input = () => {
|
||||||
jq('#download').on('click', download);
|
const input = JQ('#image')[0];
|
||||||
jq('#image').on('change', onImageInput);
|
if (input.files && input.files[0]) {
|
||||||
jq('input, textarea, select').on('input change', update);
|
const reader = new WIN.FileReader();
|
||||||
jq(window).on('load', update);
|
reader.onload = event => {
|
||||||
update();
|
JQ('#img-buffer').attr('src', event.target.result);
|
||||||
|
JQ('#mode').val('4');
|
||||||
|
setTimeout(update, 250);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(input.files[0]);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const download = () => {
|
||||||
|
JQ('#download').attr('href', JQ('#container canvas')[0].toDataURL('image/png'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const init = () => {
|
||||||
|
JQ('#download').on('click', download);
|
||||||
|
JQ('#image').on('change', on_img_input);
|
||||||
|
JQ('input, textarea, select').on('input change', update);
|
||||||
|
JQ(WIN).on('load', update);
|
||||||
|
update();
|
||||||
|
};
|
||||||
|
|
||||||
jq(init);
|
JQ(init);
|
||||||
}());
|
|
||||||
|
@ -1,449 +1,433 @@
|
|||||||
(function (vendor_qrcode) {
|
const VQRCODE = require('./vqrcode');
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var jq = window.jQuery;
|
const WIN = window; // eslint-disable-line no-undef
|
||||||
|
const JQ = WIN.jQuery;
|
||||||
|
|
||||||
// Check if canvas is available in the browser (as Modernizr does)
|
// Check if canvas is available in the browser (as Modernizr does)
|
||||||
var hasCanvas = (function () {
|
const HAS_CANVAS = (() => {
|
||||||
var elem = document.createElement('canvas');
|
const el = WIN.document.createElement('canvas');
|
||||||
return !!(elem.getContext && elem.getContext('2d'));
|
return !!(el.getContext && el.getContext('2d'));
|
||||||
}());
|
})();
|
||||||
|
|
||||||
// Wrapper for the original QR code generator.
|
const is_img_el = x => x && typeof x.tagName === 'string' && x.tagName.toUpperCase() === 'IMG';
|
||||||
function createQRCode(text, level, version, quiet) {
|
|
||||||
var qr = {};
|
|
||||||
|
|
||||||
var vqr = vendor_qrcode(version, level);
|
// Wrapper for the original QR code generator.
|
||||||
vqr.addData(text);
|
const create_qrcode = (text, level, version, quiet) => {
|
||||||
vqr.make();
|
const qr = {};
|
||||||
|
|
||||||
quiet = quiet || 0;
|
const vqr = VQRCODE(version, level);
|
||||||
|
vqr.addData(text);
|
||||||
|
vqr.make();
|
||||||
|
|
||||||
var qrModuleCount = vqr.getModuleCount();
|
quiet = quiet || 0;
|
||||||
var quietModuleCount = vqr.getModuleCount() + 2 * quiet;
|
|
||||||
|
|
||||||
function isDark(row, col) {
|
const module_count = vqr.getModuleCount();
|
||||||
row -= quiet;
|
const quiet_module_count = module_count + 2 * quiet;
|
||||||
col -= quiet;
|
|
||||||
|
|
||||||
if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) {
|
const is_dark = (row, col) => {
|
||||||
return false;
|
row -= quiet;
|
||||||
}
|
col -= quiet;
|
||||||
return vqr.isDark(row, col);
|
return row >= 0 && row < module_count && col >= 0 && col < module_count && vqr.isDark(row, col);
|
||||||
}
|
};
|
||||||
|
|
||||||
function addBlank(l, t, r, b) {
|
|
||||||
var prevIsDark = qr.isDark;
|
|
||||||
var moduleSize = 1 / quietModuleCount;
|
|
||||||
|
|
||||||
qr.isDark = function (row, col) {
|
const add_blank = (l, t, r, b) => {
|
||||||
var ml = col * moduleSize;
|
const prev_is_dark = qr.is_dark;
|
||||||
var mt = row * moduleSize;
|
const module_size = 1 / quiet_module_count;
|
||||||
var mr = ml + moduleSize;
|
|
||||||
var mb = mt + moduleSize;
|
|
||||||
|
|
||||||
return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b);
|
qr.is_dark = (row, col) => {
|
||||||
};
|
const ml = col * module_size;
|
||||||
}
|
const mt = row * module_size;
|
||||||
|
const mr = ml + module_size;
|
||||||
qr.text = text;
|
const mb = mt + module_size;
|
||||||
qr.level = level;
|
return prev_is_dark(row, col) && (l > mr || ml > r || t > mb || mt > b);
|
||||||
qr.version = version;
|
};
|
||||||
qr.moduleCount = quietModuleCount;
|
};
|
||||||
qr.isDark = isDark;
|
|
||||||
qr.addBlank = addBlank;
|
|
||||||
|
|
||||||
return qr;
|
qr.text = text;
|
||||||
|
qr.level = level;
|
||||||
|
qr.version = version;
|
||||||
|
qr.module_count = quiet_module_count;
|
||||||
|
qr.is_dark = is_dark;
|
||||||
|
qr.add_blank = add_blank;
|
||||||
|
|
||||||
|
return qr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns a minimal QR code for the given text starting with version `min_ver`.
|
||||||
|
// Returns `undefined` if `text` is too long to be encoded in `max_ver`.
|
||||||
|
const create_min_qrcode = (text, level, min_ver, max_ver, quiet) => {
|
||||||
|
min_ver = Math.max(1, min_ver || 1);
|
||||||
|
max_ver = Math.min(40, max_ver || 40);
|
||||||
|
for (let ver = min_ver; ver <= max_ver; ver += 1) {
|
||||||
|
try {
|
||||||
|
return create_qrcode(text, level, ver, quiet);
|
||||||
|
} catch (err) {/* empty */}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const draw_background_label = (qr, context, settings) => {
|
||||||
|
const size = settings.size;
|
||||||
|
const font = 'bold ' + settings.mSize * size + 'px ' + settings.fontname;
|
||||||
|
const ctx = JQ('<canvas/>')[0].getContext('2d');
|
||||||
|
|
||||||
|
ctx.font = font;
|
||||||
|
|
||||||
|
const w = ctx.measureText(settings.label).width;
|
||||||
|
const sh = settings.mSize;
|
||||||
|
const sw = w / size;
|
||||||
|
const sl = (1 - sw) * settings.mPosX;
|
||||||
|
const st = (1 - sh) * settings.mPosY;
|
||||||
|
const sr = sl + sw;
|
||||||
|
const sb = st + sh;
|
||||||
|
const pad = 0.01;
|
||||||
|
|
||||||
|
if (settings.mode === 1) {
|
||||||
|
// Strip
|
||||||
|
qr.add_blank(0, st - pad, size, sb + pad);
|
||||||
|
} else {
|
||||||
|
// Box
|
||||||
|
qr.add_blank(sl - pad, st - pad, sr + pad, sb + pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a minimal QR code for the given text starting with version `minVersion`.
|
context.fillStyle = settings.fontcolor;
|
||||||
// Returns `undefined` if `text` is too long to be encoded in `maxVersion`.
|
context.font = font;
|
||||||
function createMinQRCode(text, level, minVersion, maxVersion, quiet) {
|
context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
|
||||||
minVersion = Math.max(1, minVersion || 1);
|
};
|
||||||
maxVersion = Math.min(40, maxVersion || 40);
|
|
||||||
for (var version = minVersion; version <= maxVersion; version += 1) {
|
const draw_background_img = (qr, context, settings) => {
|
||||||
try {
|
const size = settings.size;
|
||||||
return createQRCode(text, level, version, quiet);
|
const w = settings.image.naturalWidth || 1;
|
||||||
} catch (err) {/* empty */}
|
const h = settings.image.naturalHeight || 1;
|
||||||
}
|
const sh = settings.mSize;
|
||||||
return undefined;
|
const sw = sh * w / h;
|
||||||
|
const sl = (1 - sw) * settings.mPosX;
|
||||||
|
const st = (1 - sh) * settings.mPosY;
|
||||||
|
const sr = sl + sw;
|
||||||
|
const sb = st + sh;
|
||||||
|
const pad = 0.01;
|
||||||
|
|
||||||
|
if (settings.mode === 3) {
|
||||||
|
// Strip
|
||||||
|
qr.add_blank(0, st - pad, size, sb + pad);
|
||||||
|
} else {
|
||||||
|
// Box
|
||||||
|
qr.add_blank(sl - pad, st - pad, sr + pad, sb + pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawBackgroundLabel(qr, context, settings) {
|
context.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
|
||||||
var size = settings.size;
|
};
|
||||||
var font = 'bold ' + settings.mSize * size + 'px ' + settings.fontname;
|
|
||||||
var ctx = jq('<canvas/>')[0].getContext('2d');
|
|
||||||
|
|
||||||
ctx.font = font;
|
|
||||||
|
|
||||||
var w = ctx.measureText(settings.label).width;
|
|
||||||
var sh = settings.mSize;
|
|
||||||
var sw = w / size;
|
|
||||||
var sl = (1 - sw) * settings.mPosX;
|
|
||||||
var st = (1 - sh) * settings.mPosY;
|
|
||||||
var sr = sl + sw;
|
|
||||||
var sb = st + sh;
|
|
||||||
var pad = 0.01;
|
|
||||||
|
|
||||||
if (settings.mode === 1) {
|
|
||||||
// Strip
|
|
||||||
qr.addBlank(0, st - pad, size, sb + pad);
|
|
||||||
} else {
|
|
||||||
// Box
|
|
||||||
qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.fillStyle = settings.fontcolor;
|
const draw_background = (qr, context, settings) => {
|
||||||
context.font = font;
|
if (is_img_el(settings.background)) {
|
||||||
context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
|
context.drawImage(settings.background, 0, 0, settings.size, settings.size);
|
||||||
|
} else if (settings.background) {
|
||||||
|
context.fillStyle = settings.background;
|
||||||
|
context.fillRect(settings.left, settings.top, settings.size, settings.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawBackgroundImage(qr, context, settings) {
|
const mode = settings.mode;
|
||||||
var size = settings.size;
|
if (mode === 1 || mode === 2) {
|
||||||
var w = settings.image.naturalWidth || 1;
|
draw_background_label(qr, context, settings);
|
||||||
var h = settings.image.naturalHeight || 1;
|
} else if (is_img_el(settings.image) && (mode === 3 || mode === 4)) {
|
||||||
var sh = settings.mSize;
|
draw_background_img(qr, context, settings);
|
||||||
var sw = sh * w / h;
|
}
|
||||||
var sl = (1 - sw) * settings.mPosX;
|
};
|
||||||
var st = (1 - sh) * settings.mPosY;
|
|
||||||
var sr = sl + sw;
|
|
||||||
var sb = st + sh;
|
|
||||||
var pad = 0.01;
|
|
||||||
|
|
||||||
if (settings.mode === 3) {
|
|
||||||
// Strip
|
|
||||||
qr.addBlank(0, st - pad, size, sb + pad);
|
|
||||||
} else {
|
|
||||||
// Box
|
|
||||||
qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
|
const draw_modules_default = (qr, context, settings, left, top, width, row, col) => {
|
||||||
|
if (qr.is_dark(row, col)) {
|
||||||
|
context.rect(left, top, width, width);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function drawBackground(qr, context, settings) {
|
const draw_modules_rounded_dark = (ctx, l, t, r, b, rad, nw, ne, se, sw) => {
|
||||||
if (jq(settings.background).is('img')) {
|
if (nw) {
|
||||||
context.drawImage(settings.background, 0, 0, settings.size, settings.size);
|
ctx.moveTo(l + rad, t);
|
||||||
} else if (settings.background) {
|
} else {
|
||||||
context.fillStyle = settings.background;
|
ctx.moveTo(l, t);
|
||||||
context.fillRect(settings.left, settings.top, settings.size, settings.size);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var mode = settings.mode;
|
if (ne) {
|
||||||
if (mode === 1 || mode === 2) {
|
ctx.lineTo(r - rad, t);
|
||||||
drawBackgroundLabel(qr, context, settings);
|
ctx.arcTo(r, t, r, b, rad);
|
||||||
} else if (mode === 3 || mode === 4) {
|
} else {
|
||||||
drawBackgroundImage(qr, context, settings);
|
ctx.lineTo(r, t);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawModuleDefault(qr, context, settings, left, top, width, row, col) {
|
if (se) {
|
||||||
if (qr.isDark(row, col)) {
|
ctx.lineTo(r, b - rad);
|
||||||
context.rect(left, top, width, width);
|
ctx.arcTo(r, b, l, b, rad);
|
||||||
}
|
} else {
|
||||||
|
ctx.lineTo(r, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) {
|
if (sw) {
|
||||||
if (nw) {
|
ctx.lineTo(l + rad, b);
|
||||||
ctx.moveTo(l + rad, t);
|
ctx.arcTo(l, b, l, t, rad);
|
||||||
} else {
|
} else {
|
||||||
ctx.moveTo(l, t);
|
ctx.lineTo(l, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ne) {
|
if (nw) {
|
||||||
ctx.lineTo(r - rad, t);
|
ctx.lineTo(l, t + rad);
|
||||||
ctx.arcTo(r, t, r, b, rad);
|
ctx.arcTo(l, t, r, t, rad);
|
||||||
} else {
|
} else {
|
||||||
ctx.lineTo(r, t);
|
ctx.lineTo(l, t);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const draw_modules_rounded_light = (ctx, l, t, r, b, rad, nw, ne, se, sw) => {
|
||||||
|
if (nw) {
|
||||||
|
ctx.moveTo(l + rad, t);
|
||||||
|
ctx.lineTo(l, t);
|
||||||
|
ctx.lineTo(l, t + rad);
|
||||||
|
ctx.arcTo(l, t, l + rad, t, rad);
|
||||||
|
}
|
||||||
|
|
||||||
if (se) {
|
if (ne) {
|
||||||
ctx.lineTo(r, b - rad);
|
ctx.moveTo(r - rad, t);
|
||||||
ctx.arcTo(r, b, l, b, rad);
|
ctx.lineTo(r, t);
|
||||||
} else {
|
ctx.lineTo(r, t + rad);
|
||||||
ctx.lineTo(r, b);
|
ctx.arcTo(r, t, r - rad, t, rad);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sw) {
|
if (se) {
|
||||||
ctx.lineTo(l + rad, b);
|
ctx.moveTo(r - rad, b);
|
||||||
ctx.arcTo(l, b, l, t, rad);
|
ctx.lineTo(r, b);
|
||||||
} else {
|
ctx.lineTo(r, b - rad);
|
||||||
ctx.lineTo(l, b);
|
ctx.arcTo(r, b, r - rad, b, rad);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nw) {
|
if (sw) {
|
||||||
ctx.lineTo(l, t + rad);
|
ctx.moveTo(l + rad, b);
|
||||||
ctx.arcTo(l, t, r, t, rad);
|
ctx.lineTo(l, b);
|
||||||
} else {
|
ctx.lineTo(l, b - rad);
|
||||||
ctx.lineTo(l, t);
|
ctx.arcTo(l, b, l + rad, b, rad);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const draw_modules_rounded = (qr, context, settings, left, top, width, row, col) => {
|
||||||
|
const is_dark = qr.is_dark;
|
||||||
|
const right = left + width;
|
||||||
|
const bottom = top + width;
|
||||||
|
const radius = settings.radius * width;
|
||||||
|
const rowT = row - 1;
|
||||||
|
const rowB = row + 1;
|
||||||
|
const colL = col - 1;
|
||||||
|
const colR = col + 1;
|
||||||
|
const center = is_dark(row, col);
|
||||||
|
const northwest = is_dark(rowT, colL);
|
||||||
|
const north = is_dark(rowT, col);
|
||||||
|
const northeast = is_dark(rowT, colR);
|
||||||
|
const east = is_dark(row, colR);
|
||||||
|
const southeast = is_dark(rowB, colR);
|
||||||
|
const south = is_dark(rowB, col);
|
||||||
|
const southwest = is_dark(rowB, colL);
|
||||||
|
const west = is_dark(row, colL);
|
||||||
|
|
||||||
|
if (center) {
|
||||||
|
draw_modules_rounded_dark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west);
|
||||||
|
} else {
|
||||||
|
draw_modules_rounded_light(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) {
|
const draw_modules = (qr, context, settings) => {
|
||||||
if (nw) {
|
const module_count = qr.module_count;
|
||||||
ctx.moveTo(l + rad, t);
|
const module_size = settings.size / module_count;
|
||||||
ctx.lineTo(l, t);
|
let fn = draw_modules_default;
|
||||||
ctx.lineTo(l, t + rad);
|
let row;
|
||||||
ctx.arcTo(l, t, l + rad, t, rad);
|
let col;
|
||||||
}
|
|
||||||
|
|
||||||
if (ne) {
|
if (settings.radius > 0 && settings.radius <= 0.5) {
|
||||||
ctx.moveTo(r - rad, t);
|
fn = draw_modules_rounded;
|
||||||
ctx.lineTo(r, t);
|
}
|
||||||
ctx.lineTo(r, t + rad);
|
|
||||||
ctx.arcTo(r, t, r - rad, t, rad);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (se) {
|
context.beginPath();
|
||||||
ctx.moveTo(r - rad, b);
|
for (row = 0; row < module_count; row += 1) {
|
||||||
ctx.lineTo(r, b);
|
for (col = 0; col < module_count; col += 1) {
|
||||||
ctx.lineTo(r, b - rad);
|
const l = settings.left + col * module_size;
|
||||||
ctx.arcTo(r, b, r - rad, b, rad);
|
const t = settings.top + row * module_size;
|
||||||
}
|
const w = module_size;
|
||||||
|
|
||||||
if (sw) {
|
fn(qr, context, settings, l, t, w, row, col);
|
||||||
ctx.moveTo(l + rad, b);
|
|
||||||
ctx.lineTo(l, b);
|
|
||||||
ctx.lineTo(l, b - rad);
|
|
||||||
ctx.arcTo(l, b, l + rad, b, rad);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (is_img_el(settings.fill)) {
|
||||||
function drawModuleRounded(qr, context, settings, left, top, width, row, col) {
|
context.strokeStyle = 'rgba(0,0,0,0.5)';
|
||||||
var isDark = qr.isDark;
|
context.lineWidth = 2;
|
||||||
var right = left + width;
|
context.stroke();
|
||||||
var bottom = top + width;
|
const prev = context.globalCompositeOperation;
|
||||||
var radius = settings.radius * width;
|
context.globalCompositeOperation = 'destination-out';
|
||||||
var rowT = row - 1;
|
context.fill();
|
||||||
var rowB = row + 1;
|
context.globalCompositeOperation = prev;
|
||||||
var colL = col - 1;
|
|
||||||
var colR = col + 1;
|
context.clip();
|
||||||
var center = isDark(row, col);
|
context.drawImage(settings.fill, 0, 0, settings.size, settings.size);
|
||||||
var northwest = isDark(rowT, colL);
|
context.restore();
|
||||||
var north = isDark(rowT, col);
|
} else {
|
||||||
var northeast = isDark(rowT, colR);
|
context.fillStyle = settings.fill;
|
||||||
var east = isDark(row, colR);
|
context.fill();
|
||||||
var southeast = isDark(rowB, colR);
|
|
||||||
var south = isDark(rowB, col);
|
|
||||||
var southwest = isDark(rowB, colL);
|
|
||||||
var west = isDark(row, colL);
|
|
||||||
|
|
||||||
if (center) {
|
|
||||||
drawModuleRoundedDark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west);
|
|
||||||
} else {
|
|
||||||
drawModuleRoundendLight(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function drawModules(qr, context, settings) {
|
// Draws QR code to the given `canvas` and returns it.
|
||||||
var moduleCount = qr.moduleCount;
|
const draw_on_canvas = (canvas, settings) => {
|
||||||
var moduleSize = settings.size / moduleCount;
|
const qr = create_min_qrcode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
||||||
var fn = drawModuleDefault;
|
if (!qr) {
|
||||||
var row;
|
return null;
|
||||||
var col;
|
}
|
||||||
|
|
||||||
if (settings.radius > 0 && settings.radius <= 0.5) {
|
|
||||||
fn = drawModuleRounded;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.beginPath();
|
const $canvas = JQ(canvas).data('qrcode', qr);
|
||||||
for (row = 0; row < moduleCount; row += 1) {
|
const context = $canvas[0].getContext('2d');
|
||||||
for (col = 0; col < moduleCount; col += 1) {
|
|
||||||
var l = settings.left + col * moduleSize;
|
|
||||||
var t = settings.top + row * moduleSize;
|
|
||||||
var w = moduleSize;
|
|
||||||
|
|
||||||
fn(qr, context, settings, l, t, w, row, col);
|
draw_background(qr, context, settings);
|
||||||
}
|
draw_modules(qr, context, settings);
|
||||||
}
|
|
||||||
if (jq(settings.fill).is('img')) {
|
|
||||||
context.strokeStyle = 'rgba(0,0,0,0.5)';
|
|
||||||
context.lineWidth = 2;
|
|
||||||
context.stroke();
|
|
||||||
var prev = context.globalCompositeOperation;
|
|
||||||
context.globalCompositeOperation = 'destination-out';
|
|
||||||
context.fill();
|
|
||||||
context.globalCompositeOperation = prev;
|
|
||||||
|
|
||||||
context.clip();
|
|
||||||
context.drawImage(settings.fill, 0, 0, settings.size, settings.size);
|
|
||||||
context.restore();
|
|
||||||
} else {
|
|
||||||
context.fillStyle = settings.fill;
|
|
||||||
context.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draws QR code to the given `canvas` and returns it.
|
return $canvas;
|
||||||
function drawOnCanvas(canvas, settings) {
|
};
|
||||||
var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
|
||||||
if (!qr) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $canvas = jq(canvas).data('qrcode', qr);
|
// Returns a `canvas` element representing the QR code for the given settings.
|
||||||
var context = $canvas[0].getContext('2d');
|
const create_canvas = settings => {
|
||||||
|
const $canvas = JQ('<canvas/>').attr('width', settings.size).attr('height', settings.size);
|
||||||
|
return draw_on_canvas($canvas, settings);
|
||||||
|
};
|
||||||
|
|
||||||
drawBackground(qr, context, settings);
|
// Returns an `image` element representing the QR code for the given settings.
|
||||||
drawModules(qr, context, settings);
|
const create_img = settings => {
|
||||||
|
return JQ('<img/>').attr('src', create_canvas(settings)[0].toDataURL('image/png'));
|
||||||
|
};
|
||||||
|
|
||||||
return $canvas;
|
// Returns a `div` element representing the QR code for the given settings.
|
||||||
|
const create_div = settings => {
|
||||||
|
const qr = create_min_qrcode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
||||||
|
if (!qr) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a `canvas` element representing the QR code for the given settings.
|
// some shortcuts to improve compression
|
||||||
function createCanvas(settings) {
|
const settings_size = settings.size;
|
||||||
var $canvas = jq('<canvas/>').attr('width', settings.size).attr('height', settings.size);
|
const settings_bgColor = settings.background;
|
||||||
return drawOnCanvas($canvas, settings);
|
const math_floor = Math.floor;
|
||||||
}
|
|
||||||
|
|
||||||
// Returns an `image` element representing the QR code for the given settings.
|
const module_count = qr.module_count;
|
||||||
function createImage(settings) {
|
const module_size = math_floor(settings_size / module_count);
|
||||||
return jq('<img/>').attr('src', createCanvas(settings)[0].toDataURL('image/png'));
|
const offset = math_floor(0.5 * (settings_size - module_size * module_count));
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a `div` element representing the QR code for the given settings.
|
let row;
|
||||||
function createDiv(settings) {
|
let col;
|
||||||
var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
|
||||||
if (!qr) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// some shortcuts to improve compression
|
const container_css = {
|
||||||
var settings_size = settings.size;
|
position: 'relative',
|
||||||
var settings_bgColor = settings.background;
|
left: 0,
|
||||||
var math_floor = Math.floor;
|
top: 0,
|
||||||
|
padding: 0,
|
||||||
var moduleCount = qr.moduleCount;
|
margin: 0,
|
||||||
var moduleSize = math_floor(settings_size / moduleCount);
|
width: settings_size,
|
||||||
var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount));
|
height: settings_size
|
||||||
|
};
|
||||||
var row;
|
const dark_css = {
|
||||||
var col;
|
position: 'absolute',
|
||||||
|
padding: 0,
|
||||||
var containerCSS = {
|
margin: 0,
|
||||||
position: 'relative',
|
width: module_size,
|
||||||
left: 0,
|
height: module_size,
|
||||||
top: 0,
|
'background-color': settings.fill
|
||||||
padding: 0,
|
};
|
||||||
margin: 0,
|
|
||||||
width: settings_size,
|
|
||||||
height: settings_size
|
|
||||||
};
|
|
||||||
var darkCSS = {
|
|
||||||
position: 'absolute',
|
|
||||||
padding: 0,
|
|
||||||
margin: 0,
|
|
||||||
width: moduleSize,
|
|
||||||
height: moduleSize,
|
|
||||||
'background-color': settings.fill
|
|
||||||
};
|
|
||||||
|
|
||||||
var $div = jq('<div/>').data('qrcode', qr).css(containerCSS);
|
const $div = JQ('<div/>').data('qrcode', qr).css(container_css);
|
||||||
|
|
||||||
if (settings_bgColor) {
|
if (settings_bgColor) {
|
||||||
$div.css('background-color', settings_bgColor);
|
$div.css('background-color', settings_bgColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (row = 0; row < moduleCount; row += 1) {
|
for (row = 0; row < module_count; row += 1) {
|
||||||
for (col = 0; col < moduleCount; col += 1) {
|
for (col = 0; col < module_count; col += 1) {
|
||||||
if (qr.isDark(row, col)) {
|
if (qr.is_dark(row, col)) {
|
||||||
jq('<div/>')
|
JQ('<div/>')
|
||||||
.css(darkCSS)
|
.css(dark_css)
|
||||||
.css({
|
.css({
|
||||||
left: offset + col * moduleSize,
|
left: offset + col * module_size,
|
||||||
top: offset + row * moduleSize
|
top: offset + row * module_size
|
||||||
})
|
})
|
||||||
.appendTo($div);
|
.appendTo($div);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $div;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createHTML(settings) {
|
return $div;
|
||||||
if (hasCanvas && settings.render === 'canvas') {
|
};
|
||||||
return createCanvas(settings);
|
|
||||||
} else if (hasCanvas && settings.render === 'image') {
|
|
||||||
return createImage(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createDiv(settings);
|
const create_html = settings => {
|
||||||
|
if (HAS_CANVAS && settings.render === 'canvas') {
|
||||||
|
return create_canvas(settings);
|
||||||
|
} else if (HAS_CANVAS && settings.render === 'image') {
|
||||||
|
return create_img(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin
|
return create_div(settings);
|
||||||
// ======
|
};
|
||||||
|
|
||||||
// Default settings
|
const DEFAULTS = {
|
||||||
// ----------------
|
// render method: `'canvas'`, `'image'` or `'div'`
|
||||||
var defaults = {
|
render: 'canvas',
|
||||||
// render method: `'canvas'`, `'image'` or `'div'`
|
|
||||||
render: 'canvas',
|
|
||||||
|
|
||||||
// version range somewhere in 1 .. 40
|
// version range somewhere in 1 .. 40
|
||||||
minVersion: 1,
|
minVersion: 1,
|
||||||
maxVersion: 40,
|
maxVersion: 40,
|
||||||
|
|
||||||
// error correction level: `'L'`, `'M'`, `'Q'` or `'H'`
|
// error correction level: `'L'`, `'M'`, `'Q'` or `'H'`
|
||||||
ecLevel: 'L',
|
ecLevel: 'L',
|
||||||
|
|
||||||
// offset in pixel if drawn onto existing canvas
|
// offset in pixel if drawn onto existing canvas
|
||||||
left: 0,
|
left: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
|
|
||||||
// size in pixel
|
// size in pixel
|
||||||
size: 200,
|
size: 200,
|
||||||
|
|
||||||
// code color or image element
|
// code color or image element
|
||||||
fill: '#000',
|
fill: '#000',
|
||||||
|
|
||||||
// background color or image element, `null` for transparent background
|
// background color or image element, `null` for transparent background
|
||||||
background: null,
|
background: '#fff',
|
||||||
|
|
||||||
// content
|
// content
|
||||||
text: 'no text',
|
text: 'no text',
|
||||||
|
|
||||||
// corner radius relative to module width: 0.0 .. 0.5
|
// corner radius relative to module width: 0.0 .. 0.5
|
||||||
radius: 0,
|
radius: 0,
|
||||||
|
|
||||||
// quiet zone in modules
|
// quiet zone in modules
|
||||||
quiet: 0,
|
quiet: 0,
|
||||||
|
|
||||||
// modes
|
// modes
|
||||||
// 0: normal
|
// 0: normal
|
||||||
// 1: label strip
|
// 1: label strip
|
||||||
// 2: label box
|
// 2: label box
|
||||||
// 3: image strip
|
// 3: image strip
|
||||||
// 4: image box
|
// 4: image box
|
||||||
mode: 0,
|
mode: 0,
|
||||||
|
|
||||||
mSize: 0.1,
|
mSize: 0.1,
|
||||||
mPosX: 0.5,
|
mPosX: 0.5,
|
||||||
mPosY: 0.5,
|
mPosY: 0.5,
|
||||||
|
|
||||||
label: 'no label',
|
label: 'no label',
|
||||||
fontname: 'sans',
|
fontname: 'sans',
|
||||||
fontcolor: '#000',
|
fontcolor: '#000',
|
||||||
|
|
||||||
image: null
|
image: null
|
||||||
};
|
};
|
||||||
|
|
||||||
// Register the plugin
|
JQ.fn.qrcode = module.exports = function main(options) {
|
||||||
// -------------------
|
const settings = JQ.extend({}, DEFAULTS, options);
|
||||||
jq.fn.qrcode = function (options) {
|
|
||||||
var settings = jq.extend({}, defaults, options);
|
|
||||||
|
|
||||||
return this.each(function (idx, el) {
|
return this.each((idx, el) => {
|
||||||
if (el.nodeName.toLowerCase() === 'canvas') {
|
if (el.nodeName.toLowerCase() === 'canvas') {
|
||||||
drawOnCanvas(el, settings);
|
draw_on_canvas(el, settings);
|
||||||
} else {
|
} else {
|
||||||
jq(el).append(createHTML(settings));
|
JQ(el).append(create_html(settings));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}(function () {
|
|
||||||
// `qrcode` is the single public function defined by the `QR Code Generator`
|
|
||||||
// @include "../vendor/qrcode.js"
|
|
||||||
// @include "../vendor/qrcode_UTF8.js"
|
|
||||||
return qrcode; // eslint-disable-line no-undef
|
|
||||||
}()));
|
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
// @include "../vendor/qrcode.js"
|
||||||
|
// @include "../vendor/qrcode_UTF8.js"
|
Loading…
Reference in New Issue