Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions es/QR.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { qrcode, qrDetectMode } from "./qrcode.js";

const MAX_TYPE_NUMBER = 40;

// data: data or array of data
// errorCorrectionLevel 0: L, 1: M, 2: Q, 3: H
// typeNumber 1 to 40
// mode: null (auto detect) "Byte" 'Numeric' 'Alphanumeric' 'Kanji' or array of mode
const encode = (data, errorCorrectionLevel, typeNumber, mode) => {
if (typeof errorCorrectionLevel == "number") {
errorCorrectionLevel = "LMQH".charAt(errorCorrectionLevel);
}
errorCorrectionLevel = errorCorrectionLevel || "L";
if (Array.isArray(data)) {
if (mode == null) {
mode = new Array(data.length);
for (let i = 0; i < data.length; i++) {
mode[i] = qrDetectMode(data[i]);
}
} else if (Array.isArray(mode)) {
for (let i = 0; i < data.length; i++) {
mode[i] = mode[i] || qrDetectMode(data[i]);
}
} else {
const orgmode = mode;
mode = new Array(data.length);
for (let i = 0; i < data.length; i++) {
mode[i] = orgmode;
}
}
} else {
mode = mode || qrDetectMode(data);
}
const makeQR = (typenum, errorCorrectionLevel) => {
const qr = qrcode(typenum, errorCorrectionLevel);
if (Array.isArray(data)) {
for (let i = 0; i < data.length; i++) {
qr.addData(data[i], mode[i]);
}
} else {
qr.addData(data, mode);
}
qr.make();
return qr;
};
const getQR = () => {
if (!typeNumber) {
for (let i = 1; i <= MAX_TYPE_NUMBER; i++) {
try {
return makeQR(i, errorCorrectionLevel);
} catch (e) {
if (!e.toString().startsWith("code length overflow.")) {
throw e;
}
}
}
throw Error("overflow");
} else {
return makeQR(typeNumber, errorCorrectionLevel);
}
};
const qr = getQR();
const w = qr.getModuleCount();
const res = [];
for (let i = 0; i < w; i++) {
const line = [];
for (let j = 0; j < w; j++) {
line.push(qr.isDark(i, j) ? 1 : 0);
}
res.push(line);
}
return res;
};

const QR = { encode };
export { QR };
8 changes: 8 additions & 0 deletions es/QRMode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const QRMode = {
MODE_NUMBER : 1 << 0,
MODE_ALPHA_NUM : 1 << 1,
MODE_8BIT_BYTE : 1 << 2,
MODE_KANJI : 1 << 3
};

export { QRMode };
36 changes: 36 additions & 0 deletions es/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# QR Code Generator ES Module

## Getting Started

```js
import { QR } from "https://taisukef.github.io/qrcode-generator/es/QR.js";

const data = QR.encode("Hi!");
console.log(data);
```

for browsers
```js
import { QRCode } from "https://taisukef.github.io/qrcode-generator/es/qr-code.js";

document.body.appendChild(new QRCode("abc"));
```

## API Documentation

#### encode(data, errorCorrectionLevel?, typeNumber?) => <code>QRCode</code>

Create a QRCode array data

| Param | Type | Description |
| -------------------- | --------------------------------- | ---------------------------------------------- |
| data | <code>string or Uint8Array</code> | Data |
| errorCorrectionLevel | <code>number</code> | Error correction level (0:L, 1:M, 2:Q, 3:H) |
| typeNumber | <code>number</code> | Type number (1 ~ 40), or 0 for auto detection. |

--

This implementation is based on JIS X 0510:1999.

The word 'QR Code' is registered trademark of DENSO WAVE INCORPORATED
<br/>http://www.denso-wave.com/qrcode/faqpatent-e.html
21 changes: 21 additions & 0 deletions es/bintest.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html><html lang="ja"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><link rel="icon" href="data:">
<body>
<script type="module">
import { QRCode } from "./qr-code.js";

const bin = new Uint8Array([128, 129, 130]);
document.body.appendChild(new QRCode(bin));

const kanji = "漢字";
document.body.appendChild(new QRCode(kanji));

const utf8 = "汉语";
document.body.appendChild(new QRCode(utf8));

const num = "123";
document.body.appendChild(new QRCode(num));

const abc = "ABC";
document.body.appendChild(new QRCode(abc));

</script>
14 changes: 14 additions & 0 deletions es/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script type="module" src="./qr-code.js"></script>
<qr-code id=qr></qr-code>

<br>
<button id=btn>toSVG</button>

<script type="module">
import { downloadFile } from "https://js.sabae.cc/downloadFile.js";

btn.onclick = () => {
const svg = qr.toSVG();
downloadFile("qr.svg", svg);
};
</script>
68 changes: 68 additions & 0 deletions es/qr-code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { QR } from "./QR.js";
import { qrdata2svg } from "./qrdata2svg.js";

export const encodeImageData = (code, r = 3, margin = 4) => {
const data = QR.encode(code);
const iw = data.length;
//const cw = Math.min(document.body.clientWidth, 600);
//const r = 3; // Math.floor(cw / (iw + w * 2)) || 1;
const qw = (iw + margin * 2) * r;

const idata = new Uint8ClampedArray(qw * qw * 4);
for (let i = 0; i < idata.length / 4; i++) {
idata[i * 4 + 0] = 255;
idata[i * 4 + 1] = 255;
idata[i * 4 + 2] = 255;
idata[i * 4 + 3] = 255;
}
for (let i = 0; i < iw; i++) {
for (let j = 0; j < iw; j++) {
const c = data[i][j] ? 0 : 255;
for (let k = 0; k < r * r; k++) {
const x = (i + margin) * r + Math.floor(k / r);
const y = (j + margin) * r + (k % r);
idata[(x + y * qw) * 4] = c;
idata[(x + y * qw) * 4 + 1] = c;
idata[(x + y * qw) * 4 + 2] = c;
idata[(x + y * qw) * 4 + 3] = 255;
}
}
}
const imgdata = new ImageData(idata, qw, qw);
return imgdata;
};

class QRCode extends HTMLElement {
constructor(value, pixelsize, margin) {
super();
value = this.getAttribute("value") || value;
this.pixelsize = pixelsize;
this.margin = margin;
this.canvas = document.createElement("canvas");
this.canvas.style.imageRendering = "pixelated";
this.g = this.canvas.getContext("2d");
this.appendChild(this.canvas);

if (value) {
this.value = value;
} else {
this.value = document.location.toString();
window.addEventListener("hashchange", () => this.value = document.location.toString(), false);
}
}
set value(value) {
this._value = value;
const imgdata = encodeImageData(value, this.pixelsize, this.margin);
this.canvas.width = this.canvas.height = imgdata.width;
this.g.putImageData(imgdata, 0, 0);
}
toSVG(dotw = 10) {
const data = QR.encode(this._value);
const svg = qrdata2svg(data, dotw);
return svg;
}
}

customElements.define('qr-code', QRCode);

export { QRCode };
19 changes: 19 additions & 0 deletions es/qr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading