Compare commits
No commits in common. 'master' and 'v0.13.3' have entirely different histories.
@ -1,4 +1,5 @@
|
|||||||
/build/
|
**/build/**
|
||||||
/coverage/
|
**/coverage/**
|
||||||
/dist/
|
**/dist/**
|
||||||
/node_modules/
|
**/vendor/**
|
||||||
|
**/node_modules/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/build/
|
bower_components
|
||||||
/coverage/
|
build
|
||||||
/local/
|
local
|
||||||
/node_modules/
|
node_modules
|
||||||
/npm-debug.log
|
npm-debug.log
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "jquery-qrcode",
|
||||||
|
"description": "Generate QR codes dynamically.",
|
||||||
|
"homepage": "https://larsjung.de/jquery-qrcode/",
|
||||||
|
"authors": [
|
||||||
|
"Lars Jung <lrsjng@gmail.com> (https://larsjung.de)"
|
||||||
|
],
|
||||||
|
"main": "dist/jquery.qrcode.js",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/lrsjng/jquery-qrcode.git"
|
||||||
|
},
|
||||||
|
"ignore": [
|
||||||
|
"*",
|
||||||
|
"!dist/*",
|
||||||
|
"!*.md"
|
||||||
|
]
|
||||||
|
}
|
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
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
env:
|
||||||
|
browser: true
|
||||||
|
|
||||||
|
rules:
|
||||||
|
func-names: 0
|
||||||
|
func-style: 0
|
||||||
|
no-var: 0
|
||||||
|
prefer-arrow-callback: 0
|
||||||
|
strict: 0
|
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 13 KiB |
@ -1,81 +1,83 @@
|
|||||||
const WIN = global.window;
|
(function () {
|
||||||
const JQ = WIN.jQuery;
|
'use strict';
|
||||||
|
|
||||||
const GUI_VALUE_PAIRS = [
|
var $ = jQuery; // eslint-disable-line no-undef
|
||||||
['size', 'px'],
|
var guiValuePairs = [
|
||||||
['minversion', ''],
|
['size', 'px'],
|
||||||
['quiet', ' modules'],
|
['minversion', ''],
|
||||||
['radius', '%'],
|
['quiet', ' modules'],
|
||||||
['msize', '%'],
|
['radius', '%'],
|
||||||
['mposx', '%'],
|
['msize', '%'],
|
||||||
['mposy', '%']
|
['mposx', '%'],
|
||||||
];
|
['mposy', '%']
|
||||||
|
];
|
||||||
|
|
||||||
const update_gui = () => {
|
function updateGui() {
|
||||||
JQ.each(GUI_VALUE_PAIRS, (idx, pair) => {
|
$.each(guiValuePairs, function (idx, pair) {
|
||||||
const $label = JQ('label[for="' + pair[0] + '"]');
|
var $label = $('label[for="' + pair[0] + '"]');
|
||||||
$label.text($label.text().replace(/:.*/, ': ' + JQ('#' + pair[0]).val() + pair[1]));
|
$label.text($label.text().replace(/:.*/, ': ' + $('#' + pair[0]).val() + pair[1]));
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
const update_qrcode = () => {
|
function updateQrCode() {
|
||||||
const options = {
|
var options = {
|
||||||
render: JQ('#render').val(),
|
render: $('#render').val(),
|
||||||
ecLevel: JQ('#eclevel').val(),
|
ecLevel: $('#eclevel').val(),
|
||||||
minVersion: parseInt(JQ('#minversion').val(), 10),
|
minVersion: parseInt($('#minversion').val(), 10),
|
||||||
|
|
||||||
fill: JQ('#fill').val(),
|
fill: $('#fill').val(),
|
||||||
background: JQ('#background').val(),
|
background: $('#background').val(),
|
||||||
|
// fill: $('#img-buffer')[0],
|
||||||
|
|
||||||
text: JQ('#text').val(),
|
text: $('#text').val(),
|
||||||
size: parseInt(JQ('#size').val(), 10),
|
size: parseInt($('#size').val(), 10),
|
||||||
radius: parseInt(JQ('#radius').val(), 10) * 0.01,
|
radius: parseInt($('#radius').val(), 10) * 0.01,
|
||||||
quiet: parseInt(JQ('#quiet').val(), 10),
|
quiet: parseInt($('#quiet').val(), 10),
|
||||||
|
|
||||||
mode: parseInt(JQ('#mode').val(), 10),
|
mode: parseInt($('#mode').val(), 10),
|
||||||
|
|
||||||
mSize: parseInt(JQ('#msize').val(), 10) * 0.01,
|
mSize: parseInt($('#msize').val(), 10) * 0.01,
|
||||||
mPosX: parseInt(JQ('#mposx').val(), 10) * 0.01,
|
mPosX: parseInt($('#mposx').val(), 10) * 0.01,
|
||||||
mPosY: parseInt(JQ('#mposy').val(), 10) * 0.01,
|
mPosY: parseInt($('#mposy').val(), 10) * 0.01,
|
||||||
|
|
||||||
label: JQ('#label').val(),
|
label: $('#label').val(),
|
||||||
fontname: JQ('#font').val(),
|
fontname: $('#font').val(),
|
||||||
fontcolor: JQ('#fontcolor').val(),
|
fontcolor: $('#fontcolor').val(),
|
||||||
|
|
||||||
image: JQ('#img-buffer')[0]
|
image: $('#img-buffer')[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
// options.fill = JQ('#img-buffer')[0];
|
$('#container').empty().qrcode(options);
|
||||||
// options.fill = 'rgba(255,0,0,0.5)';
|
}
|
||||||
// options.background = JQ('#img-buffer')[0];
|
|
||||||
// options.background = 'rgba(255,0,0,0.5)';
|
|
||||||
|
|
||||||
JQ('#container').empty().qrcode(options);
|
function update() {
|
||||||
};
|
updateGui();
|
||||||
|
updateQrCode();
|
||||||
|
}
|
||||||
|
|
||||||
const update = () => {
|
function onImageInput() {
|
||||||
update_gui();
|
var input = $('#image')[0];
|
||||||
update_qrcode();
|
if (input.files && input.files[0]) {
|
||||||
};
|
var reader = new FileReader();
|
||||||
|
reader.onload = function (event) {
|
||||||
|
$('#img-buffer').attr('src', event.target.result);
|
||||||
|
$('#mode').val('4');
|
||||||
|
setTimeout(update, 250);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(input.files[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const on_img_input = () => {
|
function download() {
|
||||||
const input = JQ('#image')[0];
|
$('#download').attr('href', $('#container canvas')[0].toDataURL('image/png'));
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const init = () => {
|
|
||||||
JQ('#image').on('change', on_img_input);
|
|
||||||
JQ('input, textarea, select').on('input change', update);
|
|
||||||
JQ(WIN).on('load', update);
|
|
||||||
update();
|
|
||||||
};
|
|
||||||
|
|
||||||
JQ(init);
|
$(function () {
|
||||||
|
$('#download').on('click', download);
|
||||||
|
$('#image').on('change', onImageInput);
|
||||||
|
$('input, textarea, select').on('input change', update);
|
||||||
|
$(window).load(update);
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
@ -1,415 +1,446 @@
|
|||||||
const WIN = window; // eslint-disable-line
|
(function (vendor_qrcode) {
|
||||||
const JQ = WIN.jQuery;
|
'use strict';
|
||||||
|
|
||||||
const is_img_el = x => x && typeof x.tagName === 'string' && x.tagName.toUpperCase() === 'IMG';
|
var $ = jQuery; // eslint-disable-line no-undef
|
||||||
|
|
||||||
// Wrapper for the original QR code generator.
|
// Wrapper for the original QR code generator.
|
||||||
const create_qrcode = (text, level, version, quiet) => {
|
function QRCode(text, level, version, quiet) {
|
||||||
const qr = {};
|
var qr = vendor_qrcode(version, level);
|
||||||
|
qr.addData(text);
|
||||||
|
qr.make();
|
||||||
|
|
||||||
const qr_gen = require('qrcode-generator');
|
quiet = quiet || 0;
|
||||||
qr_gen.stringToBytes = qr_gen.stringToBytesFuncs['UTF-8'];
|
|
||||||
const vqr = qr_gen(version, level);
|
|
||||||
vqr.addData(text);
|
|
||||||
vqr.make();
|
|
||||||
|
|
||||||
quiet = quiet || 0;
|
var qrModuleCount = qr.getModuleCount();
|
||||||
|
var quietModuleCount = qr.getModuleCount() + 2 * quiet;
|
||||||
|
|
||||||
const module_count = vqr.getModuleCount();
|
function isDark(row, col) {
|
||||||
const quiet_module_count = module_count + 2 * quiet;
|
row -= quiet;
|
||||||
|
col -= quiet;
|
||||||
|
|
||||||
const is_dark = (row, col) => {
|
if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) {
|
||||||
row -= quiet;
|
return false;
|
||||||
col -= quiet;
|
}
|
||||||
return row >= 0 && row < module_count && col >= 0 && col < module_count && vqr.isDark(row, col);
|
|
||||||
};
|
return qr.isDark(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
var addBlank = function (l, t, r, b) {
|
||||||
|
var prevIsDark = this.isDark; // eslint-disable-line no-invalid-this
|
||||||
|
var moduleSize = 1 / quietModuleCount;
|
||||||
|
|
||||||
const add_blank = (l, t, r, b) => {
|
this.isDark = function (row, col) { // eslint-disable-line no-invalid-this
|
||||||
const prev_is_dark = qr.is_dark;
|
var ml = col * moduleSize;
|
||||||
const module_size = 1 / quiet_module_count;
|
var mt = row * moduleSize;
|
||||||
|
var mr = ml + moduleSize;
|
||||||
|
var mb = mt + moduleSize;
|
||||||
|
|
||||||
qr.is_dark = (row, col) => {
|
return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b);
|
||||||
const ml = col * module_size;
|
};
|
||||||
const mt = row * module_size;
|
|
||||||
const mr = ml + module_size;
|
|
||||||
const mb = mt + module_size;
|
|
||||||
return prev_is_dark(row, col) && (l > mr || ml > r || t > mb || mt > b);
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
qr.text = text;
|
this.text = text;
|
||||||
qr.level = level;
|
this.level = level;
|
||||||
qr.version = version;
|
this.version = version;
|
||||||
qr.module_count = quiet_module_count;
|
this.moduleCount = quietModuleCount;
|
||||||
qr.is_dark = is_dark;
|
this.isDark = isDark;
|
||||||
qr.add_blank = add_blank;
|
this.addBlank = addBlank;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.fillStyle = settings.fontcolor;
|
// Check if canvas is available in the browser (as Modernizr does)
|
||||||
ctx.font = font;
|
var hasCanvas = (function () {
|
||||||
ctx.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
|
var elem = document.createElement('canvas');
|
||||||
};
|
return Boolean(elem.getContext && elem.getContext('2d'));
|
||||||
|
}());
|
||||||
const draw_background_img = (qr, ctx, settings) => {
|
|
||||||
const size = settings.size;
|
// Returns a minimal QR code for the given text starting with version `minVersion`.
|
||||||
const w = settings.image.naturalWidth || 1;
|
// Returns `undefined` if `text` is too long to be encoded in `maxVersion`.
|
||||||
const h = settings.image.naturalHeight || 1;
|
function createQRCode(text, level, minVersion, maxVersion, quiet) {
|
||||||
const sh = settings.mSize;
|
minVersion = Math.max(1, minVersion || 1);
|
||||||
const sw = sh * w / h;
|
maxVersion = Math.min(40, maxVersion || 40);
|
||||||
const sl = (1 - sw) * settings.mPosX;
|
for (var version = minVersion; version <= maxVersion; version += 1) {
|
||||||
const st = (1 - sh) * settings.mPosY;
|
try {
|
||||||
const sr = sl + sw;
|
return new QRCode(text, level, version, quiet);
|
||||||
const sb = st + sh;
|
} catch (err) {/* empty */}
|
||||||
const pad = 0.01;
|
}
|
||||||
|
return null;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
|
function drawBackgroundLabel(qr, context, settings) {
|
||||||
};
|
var size = settings.size;
|
||||||
|
var font = 'bold ' + (settings.mSize * size) + 'px ' + settings.fontname;
|
||||||
|
var ctx = $('<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);
|
||||||
|
}
|
||||||
|
|
||||||
const draw_background = (qr, ctx, settings) => {
|
context.fillStyle = settings.fontcolor;
|
||||||
if (is_img_el(settings.background)) {
|
context.font = font;
|
||||||
ctx.drawImage(settings.background, 0, 0, settings.size, settings.size);
|
context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
|
||||||
} else if (settings.background) {
|
|
||||||
ctx.fillStyle = settings.background;
|
|
||||||
ctx.fillRect(settings.left, settings.top, settings.size, settings.size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const mode = settings.mode;
|
function drawBackgroundImage(qr, context, settings) {
|
||||||
if (mode === 1 || mode === 2) {
|
var size = settings.size;
|
||||||
draw_background_label(qr, ctx, settings);
|
var w = settings.image.naturalWidth || 1;
|
||||||
} else if (is_img_el(settings.image) && (mode === 3 || mode === 4)) {
|
var h = settings.image.naturalHeight || 1;
|
||||||
draw_background_img(qr, ctx, settings);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
const draw_modules_default = (qr, ctx, settings, left, top, width, row, col) => {
|
context.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
|
||||||
if (qr.is_dark(row, col)) {
|
|
||||||
ctx.r(left, top, width, width);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const draw_modules_rounded_dark = (ctx, l, t, r, b, rad, nw, ne, se, sw) => {
|
function drawBackground(qr, context, settings) {
|
||||||
if (nw) {
|
if ($(settings.background).is('img')) {
|
||||||
ctx.m(l + rad, t);
|
context.drawImage(settings.background, 0, 0, settings.size, settings.size);
|
||||||
} else {
|
} else if (settings.background) {
|
||||||
ctx.m(l, t);
|
context.fillStyle = settings.background;
|
||||||
}
|
context.fillRect(settings.left, settings.top, settings.size, settings.size);
|
||||||
|
}
|
||||||
|
|
||||||
if (ne) {
|
var mode = settings.mode;
|
||||||
ctx.l(r - rad, t).a(r, t, r, b, rad);
|
if (mode === 1 || mode === 2) {
|
||||||
} else {
|
drawBackgroundLabel(qr, context, settings);
|
||||||
ctx.l(r, t);
|
} else if (mode === 3 || mode === 4) {
|
||||||
|
drawBackgroundImage(qr, context, settings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (se) {
|
function drawModuleDefault(qr, context, settings, left, top, width, row, col) {
|
||||||
ctx.l(r, b - rad).a(r, b, l, b, rad);
|
if (qr.isDark(row, col)) {
|
||||||
} else {
|
context.rect(left, top, width, width);
|
||||||
ctx.l(r, b);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sw) {
|
function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) {
|
||||||
ctx.l(l + rad, b).a(l, b, l, t, rad);
|
if (nw) {
|
||||||
} else {
|
ctx.moveTo(l + rad, t);
|
||||||
ctx.l(l, b);
|
} else {
|
||||||
}
|
ctx.moveTo(l, t);
|
||||||
|
}
|
||||||
|
|
||||||
if (nw) {
|
if (ne) {
|
||||||
ctx.l(l, t + rad).a(l, t, r, t, rad);
|
ctx.lineTo(r - rad, t);
|
||||||
} else {
|
ctx.arcTo(r, t, r, b, rad);
|
||||||
ctx.l(l, t);
|
} else {
|
||||||
}
|
ctx.lineTo(r, t);
|
||||||
};
|
}
|
||||||
|
|
||||||
const draw_modules_rounded_light = (ctx, l, t, r, b, rad, nw, ne, se, sw) => {
|
if (se) {
|
||||||
if (nw) {
|
ctx.lineTo(r, b - rad);
|
||||||
ctx.m(l + rad, t).l(l, t).l(l, t + rad).a(l, t, l + rad, t, rad);
|
ctx.arcTo(r, b, l, b, rad);
|
||||||
}
|
} else {
|
||||||
|
ctx.lineTo(r, b);
|
||||||
|
}
|
||||||
|
|
||||||
if (ne) {
|
if (sw) {
|
||||||
ctx.m(r - rad, t).l(r, t).l(r, t + rad).a(r, t, r - rad, t, rad);
|
ctx.lineTo(l + rad, b);
|
||||||
}
|
ctx.arcTo(l, b, l, t, rad);
|
||||||
|
} else {
|
||||||
|
ctx.lineTo(l, b);
|
||||||
|
}
|
||||||
|
|
||||||
if (se) {
|
if (nw) {
|
||||||
ctx.m(r - rad, b).l(r, b).l(r, b - rad).a(r, b, r - rad, b, rad);
|
ctx.lineTo(l, t + rad);
|
||||||
|
ctx.arcTo(l, t, r, t, rad);
|
||||||
|
} else {
|
||||||
|
ctx.lineTo(l, t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sw) {
|
function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) {
|
||||||
ctx.m(l + rad, b).l(l, b).l(l, b - rad).a(l, b, l + rad, b, rad);
|
if (nw) {
|
||||||
}
|
ctx.moveTo(l + rad, t);
|
||||||
};
|
ctx.lineTo(l, t);
|
||||||
|
ctx.lineTo(l, t + rad);
|
||||||
const draw_modules_rounded = (qr, ctx, settings, left, top, width, row, col) => {
|
ctx.arcTo(l, t, l + rad, t, rad);
|
||||||
const right = left + width;
|
}
|
||||||
const bottom = top + width;
|
|
||||||
const rad = settings.radius * width;
|
if (ne) {
|
||||||
|
ctx.moveTo(r - rad, t);
|
||||||
const row_n = row - 1;
|
ctx.lineTo(r, t);
|
||||||
const row_s = row + 1;
|
ctx.lineTo(r, t + rad);
|
||||||
const col_w = col - 1;
|
ctx.arcTo(r, t, r - rad, t, rad);
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const draw_modules = (qr, ctx, settings) => {
|
if (se) {
|
||||||
const module_count = qr.module_count;
|
ctx.moveTo(r - rad, b);
|
||||||
const module_size = settings.size / module_count;
|
ctx.lineTo(r, b);
|
||||||
|
ctx.lineTo(r, b - rad);
|
||||||
|
ctx.arcTo(r, b, r - rad, b, rad);
|
||||||
|
}
|
||||||
|
|
||||||
let fn = draw_modules_default;
|
if (sw) {
|
||||||
if (settings.radius > 0 && settings.radius <= 0.5) {
|
ctx.moveTo(l + rad, b);
|
||||||
fn = draw_modules_rounded;
|
ctx.lineTo(l, b);
|
||||||
|
ctx.lineTo(l, b - rad);
|
||||||
|
ctx.arcTo(l, b, l + rad, b, rad);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const draw_ctx = {
|
function drawModuleRounded(qr, context, settings, left, top, width, row, col) {
|
||||||
m(x, y) {ctx.moveTo(x, y); return draw_ctx;},
|
var isDark = qr.isDark;
|
||||||
l(x, y) {ctx.lineTo(x, y); return draw_ctx;},
|
var right = left + width;
|
||||||
a(...args) {ctx.arcTo(...args); return draw_ctx;},
|
var bottom = top + width;
|
||||||
r(...args) {ctx.rect(...args); return draw_ctx;}
|
var radius = settings.radius * width;
|
||||||
};
|
var rowT = row - 1;
|
||||||
|
var rowB = row + 1;
|
||||||
|
var colL = col - 1;
|
||||||
|
var colR = col + 1;
|
||||||
|
var center = isDark(row, col);
|
||||||
|
var northwest = isDark(rowT, colL);
|
||||||
|
var north = isDark(rowT, col);
|
||||||
|
var northeast = isDark(rowT, colR);
|
||||||
|
var east = isDark(row, colR);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ctx.beginPath();
|
function drawModules(qr, context, settings) {
|
||||||
for (let row = 0; row < module_count; row += 1) {
|
var moduleCount = qr.moduleCount;
|
||||||
for (let col = 0; col < module_count; col += 1) {
|
var moduleSize = settings.size / moduleCount;
|
||||||
const l = settings.left + col * module_size;
|
var fn = drawModuleDefault;
|
||||||
const t = settings.top + row * module_size;
|
var row;
|
||||||
const w = module_size;
|
var col;
|
||||||
|
|
||||||
fn(qr, draw_ctx, settings, l, t, w, row, col);
|
if (settings.radius > 0 && settings.radius <= 0.5) {
|
||||||
|
fn = drawModuleRounded;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (is_img_el(settings.fill)) {
|
|
||||||
ctx.strokeStyle = 'rgba(0,0,0,0.5)';
|
|
||||||
ctx.lineWidth = 2;
|
|
||||||
ctx.stroke();
|
|
||||||
const prev = ctx.globalCompositeOperation;
|
|
||||||
ctx.globalCompositeOperation = 'destination-out';
|
|
||||||
ctx.fill();
|
|
||||||
ctx.globalCompositeOperation = prev;
|
|
||||||
|
|
||||||
ctx.clip();
|
|
||||||
ctx.drawImage(settings.fill, 0, 0, settings.size, settings.size);
|
|
||||||
ctx.restore();
|
|
||||||
} else {
|
|
||||||
ctx.fillStyle = settings.fill;
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Draws QR code to the given `canvas` and returns it.
|
context.beginPath();
|
||||||
const draw_on_canvas = (canvas, settings) => {
|
for (row = 0; row < moduleCount; row += 1) {
|
||||||
const qr = create_min_qrcode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
for (col = 0; col < moduleCount; col += 1) {
|
||||||
if (!qr) {
|
var l = settings.left + col * moduleSize;
|
||||||
return null;
|
var t = settings.top + row * moduleSize;
|
||||||
}
|
var w = moduleSize;
|
||||||
|
|
||||||
const $canvas = JQ(canvas).data('qrcode', qr);
|
fn(qr, context, settings, l, t, w, row, col);
|
||||||
const ctx = $canvas[0].getContext('2d');
|
}
|
||||||
|
}
|
||||||
|
if ($(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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
draw_background(qr, ctx, settings);
|
// Draws QR code to the given `canvas` and returns it.
|
||||||
draw_modules(qr, ctx, settings);
|
function drawOnCanvas(canvas, settings) {
|
||||||
|
var qr = createQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
||||||
|
if (!qr) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $canvas;
|
var $canvas = $(canvas).data('qrcode', qr);
|
||||||
};
|
var context = $canvas[0].getContext('2d');
|
||||||
|
|
||||||
// Returns a `canvas` element representing the QR code for the given settings.
|
drawBackground(qr, context, settings);
|
||||||
const create_canvas = settings => {
|
drawModules(qr, context, settings);
|
||||||
const $canvas = JQ('<canvas/>').attr('width', settings.size).attr('height', settings.size);
|
|
||||||
return draw_on_canvas($canvas, settings);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns an `image` element representing the QR code for the given settings.
|
return $canvas;
|
||||||
const create_img = settings => {
|
}
|
||||||
return JQ('<img/>').attr('src', create_canvas(settings)[0].toDataURL('image/png'));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a `div` element representing the QR code for the given settings.
|
// Returns a `canvas` element representing the QR code for the given settings.
|
||||||
const create_div = settings => {
|
function createCanvas(settings) {
|
||||||
const qr = create_min_qrcode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
var $canvas = $('<canvas/>').attr('width', settings.size).attr('height', settings.size);
|
||||||
if (!qr) {
|
return drawOnCanvas($canvas, settings);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// some shortcuts to improve compression
|
// Returns an `image` element representing the QR code for the given settings.
|
||||||
const settings_size = settings.size;
|
function createImage(settings) {
|
||||||
const settings_bgColor = settings.background;
|
return $('<img/>').attr('src', createCanvas(settings)[0].toDataURL('image/png'));
|
||||||
const math_floor = Math.floor;
|
}
|
||||||
|
|
||||||
const module_count = qr.module_count;
|
// Returns a `div` element representing the QR code for the given settings.
|
||||||
const module_size = math_floor(settings_size / module_count);
|
function createDiv(settings) {
|
||||||
const offset = math_floor(0.5 * (settings_size - module_size * module_count));
|
var qr = createQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
|
||||||
|
if (!qr) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const container_css = {
|
// some shortcuts to improve compression
|
||||||
position: 'relative',
|
var settings_size = settings.size;
|
||||||
left: 0,
|
var settings_bgColor = settings.background;
|
||||||
top: 0,
|
var math_floor = Math.floor;
|
||||||
padding: 0,
|
|
||||||
margin: 0,
|
var moduleCount = qr.moduleCount;
|
||||||
width: settings_size,
|
var moduleSize = math_floor(settings_size / moduleCount);
|
||||||
height: settings_size
|
var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount));
|
||||||
};
|
|
||||||
const dark_css = {
|
var row;
|
||||||
position: 'absolute',
|
var col;
|
||||||
padding: 0,
|
|
||||||
margin: 0,
|
var containerCSS = {
|
||||||
width: module_size,
|
position: 'relative',
|
||||||
height: module_size,
|
left: 0,
|
||||||
'background-color': settings.fill
|
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
|
||||||
|
};
|
||||||
|
|
||||||
const $div = JQ('<div/>').data('qrcode', qr).css(container_css);
|
var $div = $('<div/>').data('qrcode', qr).css(containerCSS);
|
||||||
|
|
||||||
if (settings_bgColor) {
|
if (settings_bgColor) {
|
||||||
$div.css('background-color', settings_bgColor);
|
$div.css('background-color', settings_bgColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let row = 0; row < module_count; row += 1) {
|
for (row = 0; row < moduleCount; row += 1) {
|
||||||
for (let col = 0; col < module_count; col += 1) {
|
for (col = 0; col < moduleCount; col += 1) {
|
||||||
if (qr.is_dark(row, col)) {
|
if (qr.isDark(row, col)) {
|
||||||
JQ('<div/>')
|
$('<div/>')
|
||||||
.css(dark_css)
|
.css(darkCSS)
|
||||||
.css({
|
.css({
|
||||||
left: offset + col * module_size,
|
left: offset + col * moduleSize,
|
||||||
top: offset + row * module_size
|
top: offset + row * moduleSize
|
||||||
})
|
})
|
||||||
.appendTo($div);
|
.appendTo($div);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $div;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $div;
|
function createHTML(settings) {
|
||||||
};
|
if (hasCanvas && settings.render === 'canvas') {
|
||||||
|
return createCanvas(settings);
|
||||||
|
} else if (hasCanvas && settings.render === 'image') {
|
||||||
|
return createImage(settings);
|
||||||
|
}
|
||||||
|
|
||||||
const create_html = settings => {
|
return createDiv(settings);
|
||||||
if (settings.render === 'canvas') {
|
|
||||||
return create_canvas(settings);
|
|
||||||
} else if (settings.render === 'image') {
|
|
||||||
return create_img(settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_div(settings);
|
// Plugin
|
||||||
};
|
// ======
|
||||||
|
|
||||||
const DEFAULTS = {
|
// Default settings
|
||||||
// render method: `'canvas'`, `'image'` or `'div'`
|
// ----------------
|
||||||
render: 'canvas',
|
var defaults = {
|
||||||
|
// 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: '#fff',
|
background: null,
|
||||||
|
|
||||||
// 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
|
||||||
};
|
};
|
||||||
|
|
||||||
JQ.fn.qrcode = module.exports = function main(options) {
|
// Register the plugin
|
||||||
const settings = JQ.extend({}, DEFAULTS, options);
|
// -------------------
|
||||||
|
$.fn.qrcode = function (options) {
|
||||||
|
var settings = $.extend({}, defaults, options);
|
||||||
|
|
||||||
return this.each((idx, el) => {
|
return this.each(function () {
|
||||||
if (el.nodeName.toLowerCase() === 'canvas') {
|
if (this.nodeName.toLowerCase() === 'canvas') { // eslint-disable-line no-invalid-this
|
||||||
draw_on_canvas(el, settings);
|
drawOnCanvas(this, settings); // eslint-disable-line no-invalid-this
|
||||||
} else {
|
} else {
|
||||||
JQ(el).append(create_html(settings));
|
$(this).append(createHTML(settings)); // eslint-disable-line no-invalid-this
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
}(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 one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,59 @@
|
|||||||
|
//---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 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