Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
631df8abac | 5 years ago |
![]() |
bf58382a98 | 6 years ago |
![]() |
86948f725f | 6 years ago |
@ -1,5 +1,4 @@
|
|||||||
/build/
|
/build/
|
||||||
/coverage/
|
/coverage/
|
||||||
/dist/
|
/dist/
|
||||||
/vendor/
|
|
||||||
/node_modules/
|
/node_modules/
|
||||||
|
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
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.8 KiB |
@ -1,84 +1,81 @@
|
|||||||
(function () {
|
const WIN = global.window;
|
||||||
'use strict';
|
const JQ = WIN.jQuery;
|
||||||
|
|
||||||
var jq = window.jQuery;
|
const GUI_VALUE_PAIRS = [
|
||||||
var guiValuePairs = [
|
['size', 'px'],
|
||||||
['size', 'px'],
|
['minversion', ''],
|
||||||
['minversion', ''],
|
['quiet', ' modules'],
|
||||||
['quiet', ' modules'],
|
['radius', '%'],
|
||||||
['radius', '%'],
|
['msize', '%'],
|
||||||
['msize', '%'],
|
['mposx', '%'],
|
||||||
['mposx', '%'],
|
['mposy', '%']
|
||||||
['mposy', '%']
|
];
|
||||||
];
|
|
||||||
|
|
||||||
function updateGui() {
|
const update_gui = () => {
|
||||||
jq.each(guiValuePairs, function (idx, pair) {
|
JQ.each(GUI_VALUE_PAIRS, (idx, pair) => {
|
||||||
var $label = jq('label[for="' + pair[0] + '"]');
|
const $label = JQ('label[for="' + pair[0] + '"]');
|
||||||
$label.text($label.text().replace(/:.*/, ': ' + jq('#' + pair[0]).val() + pair[1]));
|
$label.text($label.text().replace(/:.*/, ': ' + JQ('#' + pair[0]).val() + pair[1]));
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function updateQrCode() {
|
const update_qrcode = () => {
|
||||||
var options = {
|
const options = {
|
||||||
render: jq('#render').val(),
|
render: JQ('#render').val(),
|
||||||
ecLevel: jq('#eclevel').val(),
|
ecLevel: JQ('#eclevel').val(),
|
||||||
minVersion: parseInt(jq('#minversion').val(), 10),
|
minVersion: parseInt(JQ('#minversion').val(), 10),
|
||||||
|
|
||||||
fill: jq('#fill').val(),
|
fill: JQ('#fill').val(),
|
||||||
background: jq('#background').val(),
|
background: JQ('#background').val(),
|
||||||
// fill: jq('#img-buffer')[0],
|
|
||||||
|
|
||||||
text: jq('#text').val(),
|
text: JQ('#text').val(),
|
||||||
size: parseInt(jq('#size').val(), 10),
|
size: parseInt(JQ('#size').val(), 10),
|
||||||
radius: parseInt(jq('#radius').val(), 10) * 0.01,
|
radius: parseInt(JQ('#radius').val(), 10) * 0.01,
|
||||||
quiet: parseInt(jq('#quiet').val(), 10),
|
quiet: parseInt(JQ('#quiet').val(), 10),
|
||||||
|
|
||||||
mode: parseInt(jq('#mode').val(), 10),
|
mode: parseInt(JQ('#mode').val(), 10),
|
||||||
|
|
||||||
mSize: parseInt(jq('#msize').val(), 10) * 0.01,
|
mSize: parseInt(JQ('#msize').val(), 10) * 0.01,
|
||||||
mPosX: parseInt(jq('#mposx').val(), 10) * 0.01,
|
mPosX: parseInt(JQ('#mposx').val(), 10) * 0.01,
|
||||||
mPosY: parseInt(jq('#mposy').val(), 10) * 0.01,
|
mPosY: parseInt(JQ('#mposy').val(), 10) * 0.01,
|
||||||
|
|
||||||
label: jq('#label').val(),
|
label: JQ('#label').val(),
|
||||||
fontname: jq('#font').val(),
|
fontname: JQ('#font').val(),
|
||||||
fontcolor: jq('#fontcolor').val(),
|
fontcolor: JQ('#fontcolor').val(),
|
||||||
|
|
||||||
image: jq('#img-buffer')[0]
|
image: JQ('#img-buffer')[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
jq('#container').empty().qrcode(options);
|
// options.fill = JQ('#img-buffer')[0];
|
||||||
}
|
// options.fill = 'rgba(255,0,0,0.5)';
|
||||||
|
// options.background = JQ('#img-buffer')[0];
|
||||||
|
// options.background = 'rgba(255,0,0,0.5)';
|
||||||
|
|
||||||
function update() {
|
JQ('#container').empty().qrcode(options);
|
||||||
updateGui();
|
};
|
||||||
updateQrCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onImageInput() {
|
const update = () => {
|
||||||
var input = jq('#image')[0];
|
update_gui();
|
||||||
if (input.files && input.files[0]) {
|
update_qrcode();
|
||||||
var reader = new FileReader();
|
};
|
||||||
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() {
|
const on_img_input = () => {
|
||||||
jq('#download').attr('href', jq('#container canvas')[0].toDataURL('image/png'));
|
const input = JQ('#image')[0];
|
||||||
|
if (input.files && input.files[0]) {
|
||||||
|
const reader = new WIN.FileReader();
|
||||||
|
reader.onload = event => {
|
||||||
|
JQ('#img-buffer').attr('src', event.target.result);
|
||||||
|
JQ('#mode').val('4');
|
||||||
|
setTimeout(update, 250);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(input.files[0]);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function init() {
|
const init = () => {
|
||||||
jq('#download').on('click', download);
|
JQ('#image').on('change', on_img_input);
|
||||||
jq('#image').on('change', onImageInput);
|
JQ('input, textarea, select').on('input change', update);
|
||||||
jq('input, textarea, select').on('input change', update);
|
JQ(WIN).on('load', update);
|
||||||
jq(window).on('load', update);
|
update();
|
||||||
update();
|
};
|
||||||
}
|
|
||||||
|
|
||||||
jq(init);
|
JQ(init);
|
||||||
}());
|
|
||||||
|
@ -1,449 +1,415 @@
|
|||||||
(function (vendor_qrcode) {
|
const WIN = window; // eslint-disable-line
|
||||||
'use strict';
|
const JQ = WIN.jQuery;
|
||||||
|
|
||||||
var jq = window.jQuery;
|
const is_img_el = x => x && typeof x.tagName === 'string' && x.tagName.toUpperCase() === 'IMG';
|
||||||
|
|
||||||
// Check if canvas is available in the browser (as Modernizr does)
|
// Wrapper for the original QR code generator.
|
||||||
var hasCanvas = (function () {
|
const create_qrcode = (text, level, version, quiet) => {
|
||||||
var elem = document.createElement('canvas');
|
const qr = {};
|
||||||
return !!(elem.getContext && elem.getContext('2d'));
|
|
||||||
}());
|
|
||||||
|
|
||||||
// Wrapper for the original QR code generator.
|
const qr_gen = require('qrcode-generator');
|
||||||
function createQRCode(text, level, version, quiet) {
|
qr_gen.stringToBytes = qr_gen.stringToBytesFuncs['UTF-8'];
|
||||||
var qr = {};
|
const vqr = qr_gen(version, level);
|
||||||
|
vqr.addData(text);
|
||||||
|
vqr.make();
|
||||||
|
|
||||||
var vqr = vendor_qrcode(version, level);
|
quiet = quiet || 0;
|
||||||
vqr.addData(text);
|
|
||||||
vqr.make();
|
|
||||||
|
|
||||||
quiet = quiet || 0;
|
const module_count = vqr.getModuleCount();
|
||||||
|
const quiet_module_count = module_count + 2 * quiet;
|
||||||
|
|
||||||
var qrModuleCount = vqr.getModuleCount();
|
const is_dark = (row, col) => {
|
||||||
var quietModuleCount = vqr.getModuleCount() + 2 * quiet;
|
row -= quiet;
|
||||||
|
col -= quiet;
|
||||||
|
return row >= 0 && row < module_count && col >= 0 && col < module_count && vqr.isDark(row, col);
|
||||||
|
};
|
||||||
|
|
||||||
function isDark(row, col) {
|
const add_blank = (l, t, r, b) => {
|
||||||
row -= quiet;
|
const prev_is_dark = qr.is_dark;
|
||||||
col -= quiet;
|
const module_size = 1 / quiet_module_count;
|
||||||
|
|
||||||
if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) {
|
qr.is_dark = (row, col) => {
|
||||||
return false;
|
const ml = col * module_size;
|
||||||
}
|
const mt = row * module_size;
|
||||||
return vqr.isDark(row, col);
|
const mr = ml + module_size;
|
||||||
}
|
const mb = mt + module_size;
|
||||||
|
return prev_is_dark(row, col) && (l > mr || ml > r || t > mb || mt > b);
|
||||||
function addBlank(l, t, r, b) {
|
};
|
||||||
var prevIsDark = qr.isDark;
|
};
|
||||||
var moduleSize = 1 / quietModuleCount;
|
|
||||||
|
|
||||||
qr.isDark = function (row, col) {
|
qr.text = text;
|
||||||
var ml = col * moduleSize;
|
qr.level = level;
|
||||||
var mt = row * moduleSize;
|
qr.version = version;
|
||||||
var mr = ml + moduleSize;
|
qr.module_count = quiet_module_count;
|
||||||
var mb = mt + moduleSize;
|
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, ctx, settings) => {
|
||||||
|
const size = settings.size;
|
||||||
|
const font = 'bold ' + settings.mSize * size + 'px ' + settings.fontname;
|
||||||
|
const tmp_ctx = JQ('<canvas/>')[0].getContext('2d');
|
||||||
|
|
||||||
|
tmp_ctx.font = font;
|
||||||
|
|
||||||
|
const w = tmp_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);
|
||||||
|
}
|
||||||
|
|
||||||
return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b);
|
ctx.fillStyle = settings.fontcolor;
|
||||||
};
|
ctx.font = font;
|
||||||
}
|
ctx.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
|
||||||
|
};
|
||||||
|
|
||||||
|
const draw_background_img = (qr, ctx, settings) => {
|
||||||
|
const size = settings.size;
|
||||||
|
const w = settings.image.naturalWidth || 1;
|
||||||
|
const h = settings.image.naturalHeight || 1;
|
||||||
|
const sh = settings.mSize;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
qr.text = text;
|
ctx.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
|
||||||
qr.level = level;
|
};
|
||||||
qr.version = version;
|
|
||||||
qr.moduleCount = quietModuleCount;
|
|
||||||
qr.isDark = isDark;
|
|
||||||
qr.addBlank = addBlank;
|
|
||||||
|
|
||||||
return qr;
|
const draw_background = (qr, ctx, settings) => {
|
||||||
|
if (is_img_el(settings.background)) {
|
||||||
|
ctx.drawImage(settings.background, 0, 0, settings.size, settings.size);
|
||||||
|
} else if (settings.background) {
|
||||||
|
ctx.fillStyle = settings.background;
|
||||||
|
ctx.fillRect(settings.left, settings.top, settings.size, settings.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a minimal QR code for the given text starting with version `minVersion`.
|
const mode = settings.mode;
|
||||||
// Returns `undefined` if `text` is too long to be encoded in `maxVersion`.
|
if (mode === 1 || mode === 2) {
|
||||||
function createMinQRCode(text, level, minVersion, maxVersion, quiet) {
|
draw_background_label(qr, ctx, settings);
|
||||||
minVersion = Math.max(1, minVersion || 1);
|
} else if (is_img_el(settings.image) && (mode === 3 || mode === 4)) {
|
||||||
maxVersion = Math.min(40, maxVersion || 40);
|
draw_background_img(qr, ctx, settings);
|
||||||
for (var version = minVersion; version <= maxVersion; version += 1) {
|
|
||||||
try {
|
|
||||||
return createQRCode(text, level, version, quiet);
|
|
||||||
} catch (err) {/* empty */}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function drawBackgroundLabel(qr, context, settings) {
|
const draw_modules_default = (qr, ctx, settings, left, top, width, row, col) => {
|
||||||
var size = settings.size;
|
if (qr.is_dark(row, col)) {
|
||||||
var font = 'bold ' + settings.mSize * size + 'px ' + settings.fontname;
|
ctx.r(left, top, width, width);
|
||||||
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_modules_rounded_dark = (ctx, l, t, r, b, rad, nw, ne, se, sw) => {
|
||||||
context.font = font;
|
if (nw) {
|
||||||
context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
|
ctx.m(l + rad, t);
|
||||||
|
} else {
|
||||||
|
ctx.m(l, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawBackgroundImage(qr, context, settings) {
|
if (ne) {
|
||||||
var size = settings.size;
|
ctx.l(r - rad, t).a(r, t, r, b, rad);
|
||||||
var w = settings.image.naturalWidth || 1;
|
} else {
|
||||||
var h = settings.image.naturalHeight || 1;
|
ctx.l(r, t);
|
||||||
var sh = settings.mSize;
|
}
|
||||||
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);
|
if (se) {
|
||||||
|
ctx.l(r, b - rad).a(r, b, l, b, rad);
|
||||||
|
} else {
|
||||||
|
ctx.l(r, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawBackground(qr, context, settings) {
|
if (sw) {
|
||||||
if (jq(settings.background).is('img')) {
|
ctx.l(l + rad, b).a(l, b, l, t, rad);
|
||||||
context.drawImage(settings.background, 0, 0, settings.size, settings.size);
|
} else {
|
||||||
} else if (settings.background) {
|
ctx.l(l, b);
|
||||||
context.fillStyle = settings.background;
|
}
|
||||||
context.fillRect(settings.left, settings.top, settings.size, settings.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
var mode = settings.mode;
|
if (nw) {
|
||||||
if (mode === 1 || mode === 2) {
|
ctx.l(l, t + rad).a(l, t, r, t, rad);
|
||||||
drawBackgroundLabel(qr, context, settings);
|
} else {
|
||||||
} else if (mode === 3 || mode === 4) {
|
ctx.l(l, t);
|
||||||
drawBackgroundImage(qr, context, settings);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function drawModuleDefault(qr, context, settings, left, top, width, row, col) {
|
const draw_modules_rounded_light = (ctx, l, t, r, b, rad, nw, ne, se, sw) => {
|
||||||
if (qr.isDark(row, col)) {
|
if (nw) {
|
||||||
context.rect(left, top, width, width);
|
ctx.m(l + rad, t).l(l, t).l(l, t + rad).a(l, t, l + rad, t, rad);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) {
|
if (ne) {
|
||||||
if (nw) {
|
ctx.m(r - rad, t).l(r, t).l(r, t + rad).a(r, t, r - rad, t, rad);
|
||||||
ctx.moveTo(l + rad, t);
|
}
|
||||||
} else {
|
|
||||||
ctx.moveTo(l, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ne) {
|
if (se) {
|
||||||
ctx.lineTo(r - rad, t);
|
ctx.m(r - rad, b).l(r, b).l(r, b - rad).a(r, b, r - rad, b, rad);
|
||||||
ctx.arcTo(r, t, r, b, rad);
|
}
|
||||||
} else {
|
|
||||||
ctx.lineTo(r, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (se) {
|
if (sw) {
|
||||||
ctx.lineTo(r, b - rad);
|
ctx.m(l + rad, b).l(l, b).l(l, b - rad).a(l, b, l + rad, b, rad);
|
||||||
ctx.arcTo(r, b, l, b, rad);
|
}
|
||||||
} else {
|
};
|
||||||
ctx.lineTo(r, b);
|
|
||||||
}
|
const draw_modules_rounded = (qr, ctx, settings, left, top, width, row, col) => {
|
||||||
|
const right = left + width;
|
||||||
|
const bottom = top + width;
|
||||||
|
const rad = settings.radius * width;
|
||||||
|
|
||||||
|
const row_n = row - 1;
|
||||||
|
const row_s = row + 1;
|
||||||
|
const col_w = col - 1;
|
||||||
|
const col_e = col + 1;
|
||||||
|
|
||||||
|
const is_dark = qr.is_dark;
|
||||||
|
const d_center = is_dark(row, col);
|
||||||
|
const d_nw = is_dark(row_n, col_w);
|
||||||
|
const d_n = is_dark(row_n, col);
|
||||||
|
const d_ne = is_dark(row_n, col_e);
|
||||||
|
const d_e = is_dark(row, col_e);
|
||||||
|
const d_se = is_dark(row_s, col_e);
|
||||||
|
const d_s = is_dark(row_s, col);
|
||||||
|
const d_sw = is_dark(row_s, col_w);
|
||||||
|
const d_w = is_dark(row, col_w);
|
||||||
|
|
||||||
|
if (d_center) {
|
||||||
|
draw_modules_rounded_dark(ctx, left, top, right, bottom, rad, !d_n && !d_w, !d_n && !d_e, !d_s && !d_e, !d_s && !d_w);
|
||||||
|
} else {
|
||||||
|
draw_modules_rounded_light(ctx, left, top, right, bottom, rad, d_n && d_w && d_nw, d_n && d_e && d_ne, d_s && d_e && d_se, d_s && d_w && d_sw);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (sw) {
|
const draw_modules = (qr, ctx, settings) => {
|
||||||
ctx.lineTo(l + rad, b);
|
const module_count = qr.module_count;
|
||||||
ctx.arcTo(l, b, l, t, rad);
|
const module_size = settings.size / module_count;
|
||||||
} else {
|
|
||||||
ctx.lineTo(l, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nw) {
|
let fn = draw_modules_default;
|
||||||
ctx.lineTo(l, t + rad);
|
if (settings.radius > 0 && settings.radius <= 0.5) {
|
||||||
ctx.arcTo(l, t, r, t, rad);
|
fn = draw_modules_rounded;
|
||||||
} else {
|
|
||||||
ctx.lineTo(l, t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) {
|
const draw_ctx = {
|
||||||
if (nw) {
|
m(x, y) {ctx.moveTo(x, y); return draw_ctx;},
|
||||||
ctx.moveTo(l + rad, t);
|
l(x, y) {ctx.lineTo(x, y); return draw_ctx;},
|
||||||
ctx.lineTo(l, t);
|
a(...args) {ctx.arcTo(...args); return draw_ctx;},
|
||||||
ctx.lineTo(l, t + rad);
|
r(...args) {ctx.rect(...args); return draw_ctx;}
|
||||||
ctx.arcTo(l, t, l + rad, t, rad);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if (ne) {
|
|
||||||
ctx.moveTo(r - rad, t);
|
|
||||||
ctx.lineTo(r, t);
|
|
||||||
ctx.lineTo(r, t + rad);
|
|
||||||
ctx.arcTo(r, t, r - rad, t, rad);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (se) {
|
ctx.beginPath();
|
||||||
ctx.moveTo(r - rad, b);
|
for (let row = 0; row < module_count; row += 1) {
|
||||||
ctx.lineTo(r, b);
|
for (let 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, draw_ctx, 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) {
|
ctx.strokeStyle = 'rgba(0,0,0,0.5)';
|
||||||
var isDark = qr.isDark;
|
ctx.lineWidth = 2;
|
||||||
var right = left + width;
|
ctx.stroke();
|
||||||
var bottom = top + width;
|
const prev = ctx.globalCompositeOperation;
|
||||||
var radius = settings.radius * width;
|
ctx.globalCompositeOperation = 'destination-out';
|
||||||
var rowT = row - 1;
|
ctx.fill();
|
||||||
var rowB = row + 1;
|
ctx.globalCompositeOperation = prev;
|
||||||
var colL = col - 1;
|
|
||||||
var colR = col + 1;
|
ctx.clip();
|
||||||
var center = isDark(row, col);
|
ctx.drawImage(settings.fill, 0, 0, settings.size, settings.size);
|
||||||
var northwest = isDark(rowT, colL);
|
ctx.restore();
|
||||||
var north = isDark(rowT, col);
|
} else {
|
||||||
var northeast = isDark(rowT, colR);
|
ctx.fillStyle = settings.fill;
|
||||||
var east = isDark(row, colR);
|
ctx.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();
|
|
||||||
for (row = 0; row < moduleCount; row += 1) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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.
|
const $canvas = JQ(canvas).data('qrcode', qr);
|
||||||
function drawOnCanvas(canvas, settings) {
|
const ctx = $canvas[0].getContext('2d');
|
||||||
var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
|
||||||
if (!qr) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $canvas = jq(canvas).data('qrcode', qr);
|
draw_background(qr, ctx, settings);
|
||||||
var context = $canvas[0].getContext('2d');
|
draw_modules(qr, ctx, settings);
|
||||||
|
|
||||||
drawBackground(qr, context, settings);
|
return $canvas;
|
||||||
drawModules(qr, context, settings);
|
};
|
||||||
|
|
||||||
return $canvas;
|
// Returns a `canvas` element representing the QR code for the given settings.
|
||||||
}
|
const create_canvas = settings => {
|
||||||
|
const $canvas = JQ('<canvas/>').attr('width', settings.size).attr('height', settings.size);
|
||||||
|
return draw_on_canvas($canvas, settings);
|
||||||
|
};
|
||||||
|
|
||||||
// Returns a `canvas` element representing the QR code for the given settings.
|
// Returns an `image` element representing the QR code for the given settings.
|
||||||
function createCanvas(settings) {
|
const create_img = settings => {
|
||||||
var $canvas = jq('<canvas/>').attr('width', settings.size).attr('height', settings.size);
|
return JQ('<img/>').attr('src', create_canvas(settings)[0].toDataURL('image/png'));
|
||||||
return drawOnCanvas($canvas, settings);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Returns an `image` element representing the QR code for the given settings.
|
// Returns a `div` element representing the QR code for the given settings.
|
||||||
function createImage(settings) {
|
const create_div = settings => {
|
||||||
return jq('<img/>').attr('src', createCanvas(settings)[0].toDataURL('image/png'));
|
const qr = create_min_qrcode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
||||||
|
if (!qr) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a `div` element representing the QR code for the given settings.
|
// some shortcuts to improve compression
|
||||||
function createDiv(settings) {
|
const settings_size = settings.size;
|
||||||
var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
const settings_bgColor = settings.background;
|
||||||
if (!qr) {
|
const math_floor = Math.floor;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// some shortcuts to improve compression
|
const module_count = qr.module_count;
|
||||||
var settings_size = settings.size;
|
const module_size = math_floor(settings_size / module_count);
|
||||||
var settings_bgColor = settings.background;
|
const offset = math_floor(0.5 * (settings_size - module_size * module_count));
|
||||||
var math_floor = Math.floor;
|
|
||||||
|
|
||||||
var moduleCount = qr.moduleCount;
|
|
||||||
var moduleSize = math_floor(settings_size / moduleCount);
|
|
||||||
var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount));
|
|
||||||
|
|
||||||
var row;
|
|
||||||
var col;
|
|
||||||
|
|
||||||
var containerCSS = {
|
|
||||||
position: 'relative',
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
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 container_css = {
|
||||||
|
position: 'relative',
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
padding: 0,
|
||||||
|
margin: 0,
|
||||||
|
width: settings_size,
|
||||||
|
height: settings_size
|
||||||
|
};
|
||||||
|
const dark_css = {
|
||||||
|
position: 'absolute',
|
||||||
|
padding: 0,
|
||||||
|
margin: 0,
|
||||||
|
width: module_size,
|
||||||
|
height: module_size,
|
||||||
|
'background-color': settings.fill
|
||||||
|
};
|
||||||
|
|
||||||
if (settings_bgColor) {
|
const $div = JQ('<div/>').data('qrcode', qr).css(container_css);
|
||||||
$div.css('background-color', settings_bgColor);
|
|
||||||
}
|
if (settings_bgColor) {
|
||||||
|
$div.css('background-color', settings_bgColor);
|
||||||
|
}
|
||||||
|
|
||||||
for (row = 0; row < moduleCount; row += 1) {
|
for (let row = 0; row < module_count; row += 1) {
|
||||||
for (col = 0; col < moduleCount; col += 1) {
|
for (let 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 (settings.render === 'canvas') {
|
||||||
|
return create_canvas(settings);
|
||||||
|
} else if (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
|
|
||||||
}()));
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,59 +0,0 @@
|
|||||||
//---------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// QR Code Generator for JavaScript UTF8 Support (optional)
|
|
||||||
//
|
|
||||||
// Copyright (c) 2011 Kazuhiko Arase
|
|
||||||
//
|
|
||||||
// URL: http://www.d-project.com/
|
|
||||||
//
|
|
||||||
// Licensed under the MIT license:
|
|
||||||
// http://www.opensource.org/licenses/mit-license.php
|
|
||||||
//
|
|
||||||
// The word 'QR Code' is registered trademark of
|
|
||||||
// DENSO WAVE INCORPORATED
|
|
||||||
// http://www.denso-wave.com/qrcode/faqpatent-e.html
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
!function(qrcode) {
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// overwrite qrcode.stringToBytes
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
qrcode.stringToBytes = function(s) {
|
|
||||||
// http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
|
|
||||||
function toUTF8Array(str) {
|
|
||||||
var utf8 = [];
|
|
||||||
for (var i=0; i < str.length; i++) {
|
|
||||||
var charcode = str.charCodeAt(i);
|
|
||||||
if (charcode < 0x80) utf8.push(charcode);
|
|
||||||
else if (charcode < 0x800) {
|
|
||||||
utf8.push(0xc0 | (charcode >> 6),
|
|
||||||
0x80 | (charcode & 0x3f));
|
|
||||||
}
|
|
||||||
else if (charcode < 0xd800 || charcode >= 0xe000) {
|
|
||||||
utf8.push(0xe0 | (charcode >> 12),
|
|
||||||
0x80 | ((charcode>>6) & 0x3f),
|
|
||||||
0x80 | (charcode & 0x3f));
|
|
||||||
}
|
|
||||||
// surrogate pair
|
|
||||||
else {
|
|
||||||
i++;
|
|
||||||
// UTF-16 encodes 0x10000-0x10FFFF by
|
|
||||||
// subtracting 0x10000 and splitting the
|
|
||||||
// 20 bits of 0x0-0xFFFFF into two halves
|
|
||||||
charcode = 0x10000 + (((charcode & 0x3ff)<<10)
|
|
||||||
| (str.charCodeAt(i) & 0x3ff));
|
|
||||||
utf8.push(0xf0 | (charcode >>18),
|
|
||||||
0x80 | ((charcode>>12) & 0x3f),
|
|
||||||
0x80 | ((charcode>>6) & 0x3f),
|
|
||||||
0x80 | (charcode & 0x3f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return utf8;
|
|
||||||
}
|
|
||||||
return toUTF8Array(s);
|
|
||||||
};
|
|
||||||
|
|
||||||
}(qrcode);
|
|
Loading…
Reference in New Issue