@qrcode-js/core
Advanced tools
Comparing version 0.2.2 to 0.3.0
@@ -17,8 +17,7 @@ /// <reference types="node" /> | ||
static defaultOptions: Options; | ||
constructor(canvas: HTMLCanvasElement | any, createCanvas: ((width: number, height: number) => HTMLCanvasElement) | Function, loadImage: Function, options: Options); | ||
constructor(canvas: any, createCanvas: (width: number, height: number) => any, loadImage: any, options: Options); | ||
draw(): Promise<Buffer | string>; | ||
private _clear; | ||
static _removeColor(canvasContext: CanvasRenderingContext2D): void; | ||
static _removePortion(canvasContext: CanvasRenderingContext2D): void; | ||
static _prepareRoundedCornerClip(canvasContext: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number): void; | ||
private static _getAverageRGB; | ||
static _drawDot(canvasContext: CanvasRenderingContext2D, left: number, top: number, nSize: number, scale: number, round: number): void; | ||
@@ -25,0 +24,0 @@ static _drawTelegramDot(canvasContext: CanvasRenderingContext2D, left: number, top: number, nSize: number, round: number, otherCells: { |
import { QRCodeModel, QRErrorCorrectLevel, QRUtil } from "./qrcode.js"; | ||
import merge from "lodash/merge.js"; | ||
import cloneDeep from "lodash/cloneDeep.js"; | ||
const defaultScale = 0.4; | ||
export class AwesomeQR { | ||
constructor(canvas, createCanvas, loadImage, options) { | ||
const _options = cloneDeep(AwesomeQR.defaultOptions); | ||
merge(_options, options); | ||
// Save arguments | ||
this.canvas = canvas; | ||
this.createCanvas = createCanvas; | ||
this.loadImage = loadImage; | ||
this.options = _options; | ||
this.canvas = canvas; | ||
this.options = options; | ||
this.canvas.width = this.options.size; | ||
this.canvas.height = this.options.size; | ||
this.canvasContext = this.canvas.getContext("2d"); | ||
this.qrCode = new QRCodeModel(-1, this.options.qr.correctLevel); | ||
if (Number.isInteger(this.options.qr.maskPattern)) { | ||
this.qrCode.maskPattern = this.options.qr.maskPattern; | ||
const correctLevel = this.options.qr?.correctLevel ?? | ||
AwesomeQR.defaultOptions.qr?.correctLevel ?? | ||
0; | ||
this.qrCode = new QRCodeModel(-1, correctLevel); | ||
const maskPattern = this.options.qr?.maskPattern ?? | ||
AwesomeQR.defaultOptions.qr?.maskPattern ?? | ||
0; | ||
if (Number.isInteger(maskPattern)) { | ||
this.qrCode.maskPattern = maskPattern; | ||
} | ||
if (Number.isInteger(this.options.qr.version)) { | ||
this.qrCode.typeNumber = this.options.qr.version; | ||
const version = this.options.qr?.version ?? AwesomeQR.defaultOptions.qr?.version ?? 0; | ||
if (Number.isInteger(version)) { | ||
this.qrCode.typeNumber = version; | ||
} | ||
@@ -32,3 +35,3 @@ this.qrCode.addData(this.options.text); | ||
} | ||
static _removeColor(canvasContext) { | ||
static _removePortion(canvasContext) { | ||
const oldGlobalCompositeOperation = canvasContext.globalCompositeOperation; | ||
@@ -51,47 +54,2 @@ const oldFillStyle = canvasContext.fillStyle; | ||
} | ||
static _getAverageRGB(createCanvas, image) { | ||
const blockSize = 5; | ||
const defaultRGB = { | ||
r: 0, | ||
g: 0, | ||
b: 0, | ||
}; | ||
let width, height; | ||
let i = -4; | ||
const rgb = { | ||
r: 0, | ||
g: 0, | ||
b: 0, | ||
}; | ||
let count = 0; | ||
height = image.naturalHeight || image.height; | ||
width = image.naturalWidth || image.width; | ||
const canvas = createCanvas(width, height); | ||
const context = canvas.getContext("2d"); | ||
if (!context) { | ||
return defaultRGB; | ||
} | ||
context.drawImage(image, 0, 0); | ||
let data; | ||
try { | ||
data = context.getImageData(0, 0, width, height); | ||
} | ||
catch (e) { | ||
return defaultRGB; | ||
} | ||
while ((i += blockSize * 4) < data.data.length) { | ||
if (data.data[i] > 200 || | ||
data.data[i + 1] > 200 || | ||
data.data[i + 2] > 200) | ||
continue; | ||
++count; | ||
rgb.r += data.data[i]; | ||
rgb.g += data.data[i + 1]; | ||
rgb.b += data.data[i + 2]; | ||
} | ||
rgb.r = ~~(rgb.r / count); | ||
rgb.g = ~~(rgb.g / count); | ||
rgb.b = ~~(rgb.b / count); | ||
return rgb; | ||
} | ||
static _drawDot(canvasContext, left, top, nSize, scale, round) { | ||
@@ -115,4 +73,6 @@ AwesomeQR._prepareRoundedCornerClip(canvasContext, (left + (1 - scale) / 2) * nSize, (top + (1 - scale) / 2) * nSize, scale * nSize, scale * nSize, 0.5 * scale * round * nSize); | ||
_drawPoint(canvasContext, left, top, nSize, parameters, otherCells) { | ||
const scale = this.options.dots.scale || defaultScale; | ||
const round = this.options.dots.round || 0; | ||
let scale = this.options.dots?.scale ?? AwesomeQR.defaultOptions.dots?.scale ?? 1; | ||
scale = Math.min(Math.max(scale, 0), 1); | ||
let round = this.options.dots?.round ?? AwesomeQR.defaultOptions.dots?.round ?? 0; | ||
round = Math.min(Math.max(round, 0), 1); | ||
const drawFunction = this.options.drawFunction; | ||
@@ -131,29 +91,48 @@ if (drawFunction === undefined) { | ||
// range [0-1] | ||
const rounded = Math.min(Math.max(this.options.finder.round || 0, 0), 1); | ||
AwesomeQR._prepareRoundedCornerClip(canvasContext, left * size, top * size, 7 * size, 7 * size, 3.5 * rounded * size); | ||
let round = this.options.finder?.round ?? AwesomeQR.defaultOptions.finder?.round ?? 0; | ||
round = Math.min(Math.max(round, 0), 1); | ||
AwesomeQR._prepareRoundedCornerClip(canvasContext, left * size, top * size, 7 * size, 7 * size, 3.5 * round * size); | ||
canvasContext.fill(); | ||
AwesomeQR._prepareRoundedCornerClip(canvasContext, (left + 1) * size, (top + 1) * size, 5 * size, 5 * size, 2.5 * rounded * size); | ||
AwesomeQR._removeColor(canvasContext); | ||
AwesomeQR._prepareRoundedCornerClip(canvasContext, (left + 2) * size, (top + 2) * size, 3 * size, 3 * size, 1.5 * rounded * size); | ||
AwesomeQR._prepareRoundedCornerClip(canvasContext, (left + 1) * size, (top + 1) * size, 5 * size, 5 * size, 2.5 * round * size); | ||
AwesomeQR._removePortion(canvasContext); | ||
AwesomeQR._prepareRoundedCornerClip(canvasContext, (left + 2) * size, (top + 2) * size, 3 * size, 3 * size, 1.5 * round * size); | ||
canvasContext.fill(); | ||
} | ||
async _draw() { | ||
/** | ||
* Count of the squares | ||
*/ | ||
const nCount = this.qrCode.moduleCount; | ||
const rawSize = this.options.size; | ||
let rawMargin = this.options.margin; | ||
if (rawMargin < 0 || rawMargin * 2 >= rawSize) { | ||
rawMargin = 0; | ||
/** | ||
* Original size | ||
*/ | ||
const size = this.options.size ?? AwesomeQR.defaultOptions.size ?? 0; | ||
/** | ||
* Original margin | ||
*/ | ||
let margin = this.options.margin?.size ?? AwesomeQR.defaultOptions.margin?.size ?? 0; | ||
if (margin < 0 || margin * 2 >= size) { | ||
margin = 0; | ||
} | ||
const rawViewportSize = rawSize - 2 * rawMargin; | ||
const margin = Math.ceil(rawMargin); | ||
const nSize = Math.ceil(rawViewportSize / nCount); | ||
const marginCeiled = Math.ceil(margin); | ||
/** | ||
* Size of a single dot | ||
*/ | ||
const nSize = Math.ceil((size - 2 * margin) / nCount); | ||
/** | ||
* Internal size (no margin) | ||
*/ | ||
const viewportSize = nSize * nCount; | ||
const size = viewportSize + 2 * margin; | ||
const mainCanvas = this.createCanvas(size, size); | ||
/** | ||
* Internal size + 2 * margin | ||
*/ | ||
const totalSize = viewportSize + 2 * marginCeiled; | ||
const mainCanvas = this.createCanvas(totalSize, totalSize); | ||
const mainCanvasContext = mainCanvas.getContext("2d"); | ||
mainCanvasContext.fillStyle = this.options.colorDark; | ||
mainCanvasContext.fillStyle = | ||
this.options.color ?? AwesomeQR.defaultOptions.color ?? ""; | ||
this._clear(); | ||
// Translate to make the top and left margins off the viewport | ||
mainCanvasContext.save(); | ||
mainCanvasContext.translate(margin, margin); | ||
mainCanvasContext.translate(marginCeiled, marginCeiled); | ||
if (this.options.onEvent) { | ||
@@ -166,6 +145,7 @@ this.options.onEvent("start-foreground", mainCanvasContext, { | ||
const alignmentPatternCenters = QRUtil.getPatternPosition(this.qrCode.typeNumber); | ||
var logoSide = nCount / 2; | ||
if (!!this.options.logo.image) { | ||
const logoScale = Math.min(Math.max(this.options.logo.scale, 0), 1); | ||
let logoMargin = this.options.logo.margin; | ||
let logoSide = nCount / 2; | ||
if (this.options.logo?.image) { | ||
let logoScale = this.options.logo.scale ?? AwesomeQR.defaultOptions.logo?.scale ?? 0; | ||
logoScale = Math.min(Math.max(logoScale, 0), 1); | ||
let logoMargin = this.options.logo.margin ?? AwesomeQR.defaultOptions.logo?.margin ?? 0; | ||
if (logoMargin < 0) { | ||
@@ -214,3 +194,3 @@ logoMargin = 0; | ||
} | ||
const bIsDark = this.qrCode.isDark(row, col); | ||
const bIsDark = !!this.qrCode.isDark(row, col); | ||
if (bIsDark) { | ||
@@ -241,7 +221,7 @@ this._drawPoint(mainCanvasContext, col, row, nSize, { | ||
} | ||
// - FINDER | ||
// - FINDERS | ||
this._drawFinder(mainCanvasContext, 0, 0, nSize); | ||
this._drawFinder(mainCanvasContext, nCount - 7, 0, nSize); | ||
this._drawFinder(mainCanvasContext, 0, nCount - 7, nSize); | ||
if (this.options.gradient !== undefined) { | ||
if (typeof this.options.gradient === "function") { | ||
const gradient = this.options.gradient(mainCanvasContext, viewportSize); | ||
@@ -254,21 +234,23 @@ mainCanvasContext.fillStyle = gradient; | ||
// Fill the margin | ||
if (this.options.whiteMargin) { | ||
mainCanvasContext.fillStyle = "#FFFFFF"; | ||
mainCanvasContext.fillRect(-margin, -margin, size, margin); | ||
mainCanvasContext.fillRect(-margin, viewportSize, size, margin); | ||
mainCanvasContext.fillRect(viewportSize, -margin, margin, size); | ||
mainCanvasContext.fillRect(-margin, -margin, margin, size); | ||
if (this.options.margin?.color) { | ||
mainCanvasContext.fillStyle = this.options.margin.color; | ||
mainCanvasContext.fillRect(-marginCeiled, -marginCeiled, totalSize - marginCeiled, marginCeiled); | ||
mainCanvasContext.fillRect(viewportSize, -marginCeiled, marginCeiled, totalSize - marginCeiled); | ||
mainCanvasContext.fillRect(0, viewportSize, totalSize - marginCeiled, marginCeiled); | ||
mainCanvasContext.fillRect(-marginCeiled, 0, marginCeiled, totalSize - marginCeiled); | ||
} | ||
if (!!this.options.logo.image) { | ||
if (this.options.logo?.image) { | ||
const logoImage = await this.loadImage(this.options.logo.image); | ||
const logoScale = Math.min(Math.max(this.options.logo.scale, 0), 1); | ||
let logoMargin = this.options.logo.margin; | ||
const logoCornerRadius = Math.min(Math.max(this.options.logo.round, 0), 1); | ||
let logoScale = this.options.logo.scale ?? AwesomeQR.defaultOptions.logo?.scale ?? 1; | ||
logoScale = Math.min(Math.max(logoScale, 0), 1); | ||
let logoMargin = this.options.logo.margin ?? AwesomeQR.defaultOptions.logo?.margin ?? 0; | ||
if (logoMargin < 0) { | ||
logoMargin = 0; | ||
} | ||
let logoCornerRound = this.options.logo.round ?? AwesomeQR.defaultOptions.logo?.round ?? 0; | ||
logoCornerRound = Math.min(Math.max(logoCornerRound, 0), 1); | ||
const logoSize = viewportSize * logoScale; | ||
const logoX = 0.5 * (viewportSize - logoSize); | ||
// Draw logo image | ||
AwesomeQR._prepareRoundedCornerClip(mainCanvasContext, logoX, logoX, logoSize, logoSize, logoCornerRadius * logoSize * 0.5); | ||
AwesomeQR._prepareRoundedCornerClip(mainCanvasContext, logoX, logoX, logoSize, logoSize, logoCornerRound * logoSize * 0.5); | ||
mainCanvasContext.clip(); | ||
@@ -283,38 +265,25 @@ mainCanvasContext.drawImage(logoImage, logoX, logoX, logoSize, logoSize); | ||
} | ||
const backgroundCanvas = this.createCanvas(size, size); | ||
const backgroundCanvasContext = backgroundCanvas.getContext("2d"); | ||
if (this.options.onEvent) { | ||
this.options.onEvent("start-background", backgroundCanvasContext, { | ||
nCount, | ||
nSize, | ||
}); | ||
} | ||
if (!!this.options.background.image) { | ||
const backgroundImage = await this.loadImage(this.options.background.image); | ||
const backgroundDimming = this.options.background.dimming; | ||
if (this.options.autoColor) { | ||
const avgRGB = AwesomeQR._getAverageRGB(this.createCanvas, backgroundImage); | ||
this.options.colorDark = `rgb(${avgRGB.r},${avgRGB.g},${avgRGB.b})`; | ||
if (this.options.background) { | ||
if (this.options.onEvent) { | ||
this.options.onEvent("start-background", this.canvasContext, {}); | ||
} | ||
backgroundCanvasContext.drawImage(backgroundImage, 0, 0, size, size); | ||
backgroundCanvasContext.rect(0, 0, size, size); | ||
backgroundCanvasContext.fillStyle = backgroundDimming; | ||
backgroundCanvasContext.fill(); | ||
if (this.options.background.colorBelow) { | ||
this.canvasContext.fillStyle = this.options.background.colorBelow; | ||
this.canvasContext.fillRect(0, 0, size, size); | ||
} | ||
if (this.options.background.image) { | ||
const backgroundImage = await this.loadImage(this.options.background.image); | ||
this.canvasContext.drawImage(backgroundImage, 0, 0, totalSize, totalSize); | ||
} | ||
if (this.options.background.colorAbove) { | ||
this.canvasContext.fillStyle = this.options.background.colorAbove; | ||
this.canvasContext.fillRect(0, 0, size, size); | ||
} | ||
if (this.options.onEvent) { | ||
this.options.onEvent("end-background", this.canvasContext, {}); | ||
} | ||
} | ||
else { | ||
backgroundCanvasContext.rect(0, 0, size, size); | ||
backgroundCanvasContext.fillStyle = this.options.colorLight; | ||
backgroundCanvasContext.fill(); | ||
} | ||
// Apply foreground to final canvas | ||
this.canvasContext.drawImage(mainCanvas, 0, 0, size, size); | ||
if (this.options.onEvent) { | ||
this.options.onEvent("end-background", backgroundCanvasContext, { | ||
nCount, | ||
nSize, | ||
}); | ||
} | ||
// Apply foreground to background canvas | ||
backgroundCanvasContext.drawImage(mainCanvas, 0, 0); | ||
// Scale the final image | ||
this.canvasContext.drawImage(backgroundCanvas, 0, 0, rawSize, rawSize); | ||
if (this.options.onEvent) { | ||
this.options.onEvent("final-canvas", this.canvasContext, { | ||
@@ -335,12 +304,8 @@ nCount, | ||
size: 400, | ||
margin: 20, | ||
colorDark: "#000000", | ||
colorLight: "rgba(0,0,0,0)", | ||
margin: { size: 20 }, | ||
color: "#000000", | ||
qr: { | ||
correctLevel: QRErrorCorrectLevel.M, | ||
}, | ||
background: { dimming: "rgba(0,0,0,0)" }, | ||
logo: { scale: 0.2, margin: 10, round: 0.4 }, | ||
whiteMargin: false, | ||
autoColor: true, | ||
logo: { scale: 0.2, margin: 10, round: 0.4, image: "" }, | ||
dots: { | ||
@@ -347,0 +312,0 @@ scale: 1, |
@@ -41,6 +41,6 @@ //--------------------------------------------------------------------- | ||
function _getTypeNumber(sText, nCorrectLevel) { | ||
var nType = 1; | ||
var length = _getUTF8Length(sText); | ||
for (var i = 0, len = QRCodeLimitLength.length; i < len; i++) { | ||
var nLimit = 0; | ||
let nType = 1; | ||
const length = _getUTF8Length(sText); | ||
for (let i = 0, len = QRCodeLimitLength.length; i < len; i++) { | ||
let nLimit = 0; | ||
switch (nCorrectLevel) { | ||
@@ -73,5 +73,5 @@ case QRErrorCorrectLevel.L: | ||
function _getUTF8Length(sText) { | ||
var replacedText = encodeURI(sText) | ||
const replacedText = encodeURI(sText) | ||
.toString() | ||
.replace(/\%[0-9a-fA-F]{2}/g, "a"); | ||
.replace(/%[0-9a-fA-F]{2}/g, "a"); | ||
return replacedText.length + (replacedText.length != Number(sText) ? 3 : 0); | ||
@@ -261,9 +261,9 @@ } | ||
const bits = QRUtil.getBCHTypeNumber(this.typeNumber); | ||
for (var i = 0; i < 18; i++) { | ||
var mod = !test && ((bits >> i) & 1) == 1; | ||
for (let i = 0; i < 18; i++) { | ||
const mod = !test && ((bits >> i) & 1) == 1; | ||
this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = | ||
mod; | ||
} | ||
for (var i = 0; i < 18; i++) { | ||
var mod = !test && ((bits >> i) & 1) == 1; | ||
for (let i = 0; i < 18; i++) { | ||
const mod = !test && ((bits >> i) & 1) == 1; | ||
this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = | ||
@@ -276,4 +276,4 @@ mod; | ||
const bits = QRUtil.getBCHTypeInfo(data); | ||
for (var i = 0; i < 15; i++) { | ||
var mod = !test && ((bits >> i) & 1) == 1; | ||
for (let i = 0; i < 15; i++) { | ||
const mod = !test && ((bits >> i) & 1) == 1; | ||
if (i < 6) { | ||
@@ -289,4 +289,4 @@ this.modules[i][8] = mod; | ||
} | ||
for (var i = 0; i < 15; i++) { | ||
var mod = !test && ((bits >> i) & 1) == 1; | ||
for (let i = 0; i < 15; i++) { | ||
const mod = !test && ((bits >> i) & 1) == 1; | ||
if (i < 8) { | ||
@@ -312,3 +312,4 @@ this.modules[8][this.moduleCount - i - 1] = mod; | ||
col--; | ||
while (true) { | ||
const whileCondition = true; | ||
while (whileCondition) { | ||
for (let c = 0; c < 2; c++) { | ||
@@ -344,3 +345,3 @@ if (this.modules[row][col - c] == null) { | ||
const buffer = new QRBitBuffer(); | ||
for (var i = 0; i < dataList.length; i++) { | ||
for (let i = 0; i < dataList.length; i++) { | ||
const data = dataList[i]; | ||
@@ -352,3 +353,3 @@ buffer.put(data.mode, 4); | ||
let totalDataCount = 0; | ||
for (var i = 0; i < rsBlocks.length; i++) { | ||
for (let i = 0; i < rsBlocks.length; i++) { | ||
totalDataCount += rsBlocks[i].dataCount; | ||
@@ -365,3 +366,4 @@ } | ||
} | ||
while (true) { | ||
const whileCondition = true; | ||
while (whileCondition) { | ||
if (buffer.getLengthInBits() >= totalDataCount * 8) { | ||
@@ -384,3 +386,3 @@ break; | ||
const ecdata = new Array(rsBlocks.length); | ||
for (var r = 0; r < rsBlocks.length; r++) { | ||
for (let r = 0; r < rsBlocks.length; r++) { | ||
const dcCount = rsBlocks[r].dataCount; | ||
@@ -391,3 +393,3 @@ const ecCount = rsBlocks[r].totalCount - dcCount; | ||
dcdata[r] = new Array(dcCount); | ||
for (var i = 0; i < dcdata[r].length; i++) { | ||
for (let i = 0; i < dcdata[r].length; i++) { | ||
dcdata[r][i] = 0xff & buffer.buffer[i + offset]; | ||
@@ -400,3 +402,3 @@ } | ||
ecdata[r] = new Array(rsPoly.getLength() - 1); | ||
for (var i = 0; i < ecdata[r].length; i++) { | ||
for (let i = 0; i < ecdata[r].length; i++) { | ||
const modIndex = i + modPoly.getLength() - ecdata[r].length; | ||
@@ -407,3 +409,3 @@ ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0; | ||
let totalCodeCount = 0; | ||
for (var i = 0; i < rsBlocks.length; i++) { | ||
for (let i = 0; i < rsBlocks.length; i++) { | ||
totalCodeCount += rsBlocks[i].totalCount; | ||
@@ -413,4 +415,4 @@ } | ||
let index = 0; | ||
for (var i = 0; i < maxDcCount; i++) { | ||
for (var r = 0; r < rsBlocks.length; r++) { | ||
for (let i = 0; i < maxDcCount; i++) { | ||
for (let r = 0; r < rsBlocks.length; r++) { | ||
if (i < dcdata[r].length) { | ||
@@ -421,4 +423,4 @@ data[index++] = dcdata[r][i]; | ||
} | ||
for (var i = 0; i < maxEcCount; i++) { | ||
for (var r = 0; r < rsBlocks.length; r++) { | ||
for (let i = 0; i < maxEcCount; i++) { | ||
for (let r = 0; r < rsBlocks.length; r++) { | ||
if (i < ecdata[r].length) { | ||
@@ -558,4 +560,4 @@ data[index++] = ecdata[r][i]; | ||
let lostPoint = 0; | ||
for (var row = 0; row < moduleCount; row++) { | ||
for (var col = 0; col < moduleCount; col++) { | ||
for (let row = 0; row < moduleCount; row++) { | ||
for (let col = 0; col < moduleCount; col++) { | ||
let sameCount = 0; | ||
@@ -584,4 +586,4 @@ const dark = qrCode.isDark(row, col); | ||
} | ||
for (var row = 0; row < moduleCount - 1; row++) { | ||
for (var col = 0; col < moduleCount - 1; col++) { | ||
for (let row = 0; row < moduleCount - 1; row++) { | ||
for (let col = 0; col < moduleCount - 1; col++) { | ||
let count = 0; | ||
@@ -601,4 +603,4 @@ if (qrCode.isDark(row, col)) | ||
} | ||
for (var row = 0; row < moduleCount; row++) { | ||
for (var col = 0; col < moduleCount - 6; col++) { | ||
for (let row = 0; row < moduleCount; row++) { | ||
for (let col = 0; col < moduleCount - 6; col++) { | ||
if (qrCode.isDark(row, col) && | ||
@@ -615,4 +617,4 @@ !qrCode.isDark(row, col + 1) && | ||
} | ||
for (var col = 0; col < moduleCount; col++) { | ||
for (var row = 0; row < moduleCount - 6; row++) { | ||
for (let col = 0; col < moduleCount; col++) { | ||
for (let row = 0; row < moduleCount - 6; row++) { | ||
if (qrCode.isDark(row, col) && | ||
@@ -630,4 +632,4 @@ !qrCode.isDark(row + 1, col) && | ||
let darkCount = 0; | ||
for (var col = 0; col < moduleCount; col++) { | ||
for (var row = 0; row < moduleCount; row++) { | ||
for (let col = 0; col < moduleCount; col++) { | ||
for (let row = 0; row < moduleCount; row++) { | ||
if (qrCode.isDark(row, col)) { | ||
@@ -715,6 +717,6 @@ darkCount++; | ||
QRMath._constructor = (function () { | ||
for (var i = 0; i < 8; i++) { | ||
for (let i = 0; i < 8; i++) { | ||
QRMath.EXP_TABLE[i] = 1 << i; | ||
} | ||
for (var i = 8; i < 256; i++) { | ||
for (let i = 8; i < 256; i++) { | ||
QRMath.EXP_TABLE[i] = | ||
@@ -726,3 +728,3 @@ QRMath.EXP_TABLE[i - 4] ^ | ||
} | ||
for (var i = 0; i < 255; i++) { | ||
for (let i = 0; i < 255; i++) { | ||
QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i; | ||
@@ -766,6 +768,6 @@ } | ||
const num = new Array(this.getLength()); | ||
for (var i = 0; i < this.getLength(); i++) { | ||
for (let i = 0; i < this.getLength(); i++) { | ||
num[i] = this.get(i); | ||
} | ||
for (var i = 0; i < e.getLength(); i++) { | ||
for (let i = 0; i < e.getLength(); i++) { | ||
num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio); | ||
@@ -772,0 +774,0 @@ } |
@@ -14,7 +14,25 @@ /// <reference types="node" /> | ||
/** | ||
* Size of margins around the QR code body in pixel. | ||
* | ||
* @defaultValue 20 | ||
* Margin options | ||
*/ | ||
margin?: number; | ||
margin?: { | ||
/** | ||
* Size of margins around the QR code body in pixel. | ||
* | ||
* @defaultValue 20 | ||
*/ | ||
size?: number; | ||
/** | ||
* Color of the margins. | ||
* | ||
* Accepts a CSS <color>. | ||
* | ||
* For more information about CSS <color>, please refer to [https://developer.mozilla.org/en-US/docs/Web/CSS/color_value](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). | ||
* | ||
* @defaultValue "transparent" | ||
*/ | ||
color?: string; | ||
}; | ||
/** | ||
* QR options | ||
*/ | ||
qr?: { | ||
@@ -91,28 +109,8 @@ /** | ||
*/ | ||
colorDark?: string; | ||
color?: string; | ||
/** | ||
* Color of the empty areas on the QR code. | ||
* Function for creating a gradient as foreground color | ||
* | ||
* Accepts a CSS <color>. | ||
* Must return a CanvasGradient | ||
* | ||
* For more information about CSS <color>, please refer to [https://developer.mozilla.org/en-US/docs/Web/CSS/color_value](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). | ||
* | ||
* @defaultValue "#ffffff" | ||
*/ | ||
colorLight?: string; | ||
/** | ||
* Automatically calculate the _colorLight_ value from the QR code's background. | ||
* | ||
* @defaultValue true | ||
*/ | ||
autoColor?: boolean; | ||
/** | ||
* Use a white margin instead of a transparent one which reveals the background of the QR code on margins. | ||
* | ||
* @defaultValue false | ||
*/ | ||
whiteMargin?: boolean; | ||
/** | ||
* Function for creating a gradient as foreground color | ||
* Must return a CanvasGradient | ||
* Overrides colorDark option | ||
@@ -140,3 +138,11 @@ */ | ||
*/ | ||
dimming?: string; | ||
colorAbove?: string; | ||
/** | ||
* Color of the background of the QR. | ||
* | ||
* Goes behind an eventually image with `background.image` option | ||
* | ||
* @defaultValue "transparent" | ||
*/ | ||
colorBelow?: string; | ||
}; | ||
@@ -154,3 +160,3 @@ /** | ||
*/ | ||
image?: string | Buffer; | ||
image: string | Buffer; | ||
/** | ||
@@ -206,2 +212,3 @@ * Ratio of the logo size to the QR code size. | ||
* Actually called when: | ||
* | ||
* - starting painting foreground | ||
@@ -212,5 +219,5 @@ * - end painting foreground | ||
*/ | ||
onEvent?: (type: EventTypes, canvasContext: CanvasRenderingContext2D, parameters: object) => undefined; | ||
onEvent?: (type: EventTypes, canvasContext: CanvasRenderingContext2D, parameters: object) => void; | ||
}; | ||
declare type EventTypes = "start-foreground" | "end-foreground" | "start-background" | "end-background" | "final-canvas"; | ||
export {}; |
{ | ||
"name": "@qrcode-js/core", | ||
"version": "0.2.2", | ||
"author": "qrcode-js team", | ||
"bugs": { | ||
"url": "https://github.com/qrcode-js/core/issues" | ||
}, | ||
"dependencies": { | ||
"buffer": "^6.0.3", | ||
"lodash": "^4.17.21" | ||
}, | ||
"description": "An awesome but simple QR code generator written in JavaScript.", | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "tsc -w --preserveWatchOutput", | ||
"build": "tsc", | ||
"prepublishOnly": "npm run build" | ||
"devDependencies": { | ||
"@types/lodash": "^4.14.184", | ||
"@types/node": "^16.0.14" | ||
}, | ||
@@ -16,6 +18,3 @@ "files": [ | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/qrcode-js/core.git" | ||
}, | ||
"homepage": "https://github.com/qrcode-js/core#readme", | ||
"keywords": [ | ||
@@ -26,17 +25,18 @@ "qr", | ||
], | ||
"author": "qrcode-js team", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/qrcode-js/core/issues" | ||
"main": "lib/index.js", | ||
"name": "@qrcode-js/core", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/qrcode-js/core.git" | ||
}, | ||
"homepage": "https://github.com/qrcode-js/core#readme", | ||
"dependencies": { | ||
"buffer": "^6.0.3", | ||
"lodash": "^4.17.21" | ||
"scripts": { | ||
"build": "tsc", | ||
"dev": "tsc -w --preserveWatchOutput", | ||
"prepublishOnly": "npm run build" | ||
}, | ||
"devDependencies": { | ||
"@types/lodash": "^4.14.184", | ||
"@types/node": "^16.0.14" | ||
}, | ||
"gitHead": "194d638d7f5b238bec7ead1c8871489edf4c8dd8" | ||
"type": "module", | ||
"types": "lib/index.d.ts", | ||
"version": "0.3.0", | ||
"gitHead": "4c2a87a31815a9d5efccfa378a4e6bd76c6e9055" | ||
} |
105
README.md
<!-- Auto-generated README. Do not edit directly --> | ||
# @qrcode-js/core | ||
@@ -18,12 +19,12 @@ | ||
## API | ||
```typescript | ||
type Options = { | ||
text: string; | ||
autoColor?: boolean; | ||
background?: { | ||
dimming?: string; | ||
colorAbove?: string; | ||
colorBelow?: string; | ||
image?: Union; | ||
}; | ||
colorDark?: string; | ||
colorLight?: string; | ||
color?: string; | ||
dots?: { | ||
@@ -39,3 +40,3 @@ round?: number; | ||
logo?: { | ||
image?: Union; | ||
image: Union; | ||
margin?: number; | ||
@@ -45,3 +46,6 @@ round?: number; | ||
}; | ||
margin?: number; | ||
margin?: { | ||
color?: string; | ||
size?: number; | ||
}; | ||
onEvent?: Function; | ||
@@ -54,5 +58,4 @@ qr?: { | ||
size?: number; | ||
whiteMargin?: boolean; | ||
} | ||
type EventTypes = | ||
}; | ||
type EventTypes = | ||
| "start-foreground" | ||
@@ -64,2 +67,3 @@ | "end-foreground" | ||
``` | ||
### text | ||
@@ -75,12 +79,2 @@ | ||
### autoColor | ||
**Type** `boolean` | ||
**defaultValue** `true` | ||
Automatically calculate the _colorLight_ value from the QR code's background. | ||
<hr /> | ||
### background | ||
@@ -94,3 +88,3 @@ | ||
### background.dimming | ||
### background.colorAbove | ||
@@ -109,2 +103,14 @@ **Type** `string` | ||
### background.colorBelow | ||
**Type** `string` | ||
**defaultValue** `"transparent"` | ||
Color of the background of the QR. | ||
Goes behind an eventually image with `background.image` option | ||
<hr /> | ||
### background.image | ||
@@ -120,3 +126,3 @@ | ||
### colorDark | ||
### color | ||
@@ -135,16 +141,2 @@ **Type** `string` | ||
### colorLight | ||
**Type** `string` | ||
**defaultValue** `"#ffffff"` | ||
Color of the empty areas on the QR code. | ||
Accepts a CSS <color>. | ||
For more information about CSS <color>, please refer to [https://developer.mozilla.org/en-US/docs/Web/CSS/color_value](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). | ||
<hr /> | ||
### dots | ||
@@ -246,3 +238,5 @@ | ||
Function for creating a gradient as foreground color | ||
Must return a CanvasGradient | ||
Overrides colorDark option | ||
@@ -264,2 +258,4 @@ | ||
**Required** | ||
Logo image to be displayed at the center of the QR code. | ||
@@ -307,2 +303,24 @@ | ||
**Type** `Object` | ||
Margin options | ||
<hr /> | ||
### margin.color | ||
**Type** `string` | ||
**defaultValue** `"transparent"` | ||
Color of the margins. | ||
Accepts a CSS <color>. | ||
For more information about CSS <color>, please refer to [https://developer.mozilla.org/en-US/docs/Web/CSS/color_value](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). | ||
<hr /> | ||
### margin.size | ||
**Type** `number` | ||
@@ -322,3 +340,3 @@ | ||
parameters: object | ||
) => undefined` | ||
) => void` | ||
@@ -328,2 +346,3 @@ Custom function called at certain phases of drawing the QR. | ||
Actually called when: | ||
- starting painting foreground | ||
@@ -340,2 +359,4 @@ - end painting foreground | ||
QR options | ||
<hr /> | ||
@@ -396,13 +417,1 @@ | ||
<hr /> | ||
### whiteMargin | ||
**Type** `boolean` | ||
**defaultValue** `false` | ||
Use a white margin instead of a transparent one which reveals the background of the QR code on margins. | ||
<hr /> | ||
401
71239
1698