@wirunrom/hqr-generate 0.2.23 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +230 -151
- package/index.bundler.js +59 -34
- package/index.d.ts +29 -22
- package/index.web.js +61 -42
- package/package.json +66 -64
- package/pkg/bundler/LICENSE +21 -0
- package/pkg/bundler/README.md +230 -151
- package/pkg/bundler/hqr_generate.d.ts +2 -0
- package/pkg/bundler/hqr_generate.js +1 -1
- package/pkg/bundler/hqr_generate_bg.js +32 -0
- package/pkg/bundler/hqr_generate_bg.wasm +0 -0
- package/pkg/bundler/hqr_generate_bg.wasm.d.ts +3 -2
- package/pkg/bundler/package.json +1 -1
- package/pkg/web/LICENSE +21 -0
- package/pkg/web/README.md +230 -151
- package/pkg/web/hqr_generate.d.ts +5 -2
- package/pkg/web/hqr_generate.js +32 -0
- package/pkg/web/hqr_generate_bg.wasm +0 -0
- package/pkg/web/hqr_generate_bg.wasm.d.ts +3 -2
- package/pkg/web/package.json +1 -1
- package/react/index.d.ts +12 -17
- package/react/index.js +4 -91
- package/react/useQrDecodeFromImageData.d.ts +5 -0
- package/react/useQrDecodeFromImageData.js +47 -0
- package/react/useQrDecodeFromImageSrc.d.ts +6 -0
- package/react/useQrDecodeFromImageSrc.js +59 -0
- package/react/useQrPngBlobUrl.d.ts +6 -0
- package/react/useQrPngBlobUrl.js +52 -0
- package/react/useQrPngDataUrl.d.ts +6 -0
- package/react/useQrPngDataUrl.js +41 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { useQrDecodeFromImageData } from "./useQrDecodeFromImageData.js";
|
|
3
|
+
|
|
4
|
+
async function loadImageData(src) {
|
|
5
|
+
const img = new Image();
|
|
6
|
+
img.crossOrigin = "anonymous";
|
|
7
|
+
img.src = src;
|
|
8
|
+
await img.decode();
|
|
9
|
+
|
|
10
|
+
const canvas = document.createElement("canvas");
|
|
11
|
+
canvas.width = img.width;
|
|
12
|
+
canvas.height = img.height;
|
|
13
|
+
|
|
14
|
+
const ctx = canvas.getContext("2d");
|
|
15
|
+
if (!ctx) throw new Error("Canvas not supported");
|
|
16
|
+
|
|
17
|
+
ctx.drawImage(img, 0, 0);
|
|
18
|
+
return ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function useQrDecodeFromImageSrc(src) {
|
|
22
|
+
const [imageData, setImageData] = useState(null);
|
|
23
|
+
const [loadError, setLoadError] = useState(null);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!src) {
|
|
27
|
+
setImageData(null);
|
|
28
|
+
setLoadError(null);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let alive = true;
|
|
33
|
+
|
|
34
|
+
loadImageData(src)
|
|
35
|
+
.then((data) => {
|
|
36
|
+
if (alive) {
|
|
37
|
+
setImageData(data);
|
|
38
|
+
setLoadError(null);
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
.catch((err) => {
|
|
42
|
+
if (alive) {
|
|
43
|
+
setImageData(null);
|
|
44
|
+
setLoadError(err);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return () => {
|
|
49
|
+
alive = false;
|
|
50
|
+
};
|
|
51
|
+
}, [src]);
|
|
52
|
+
|
|
53
|
+
const decode = useQrDecodeFromImageData(imageData);
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
...decode,
|
|
57
|
+
loadError,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { qr_png_bytes } from "../index.web.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* React hook for QR Code as Blob URL (browser-only).
|
|
6
|
+
* Faster + lower memory than base64 data URL for frequent updates / large images.
|
|
7
|
+
* @param {string} text
|
|
8
|
+
* @param {{size?:number, margin?:number, ecc?:"L"|"M"|"Q"|"H"}} [opts]
|
|
9
|
+
*/
|
|
10
|
+
export function useQrPngBlobUrl(text, opts) {
|
|
11
|
+
const size = opts?.size ?? 320;
|
|
12
|
+
const margin = opts?.margin ?? 4;
|
|
13
|
+
const ecc = opts?.ecc ?? "Q";
|
|
14
|
+
|
|
15
|
+
const [src, setSrc] = useState("");
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
let alive = true;
|
|
19
|
+
let objectUrl = "";
|
|
20
|
+
|
|
21
|
+
if (!text) {
|
|
22
|
+
setSrc("");
|
|
23
|
+
return () => {
|
|
24
|
+
alive = false;
|
|
25
|
+
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
qr_png_bytes(text, size, margin, ecc)
|
|
30
|
+
.then((bytes) => {
|
|
31
|
+
if (!alive) return;
|
|
32
|
+
|
|
33
|
+
// revoke old url (if any)
|
|
34
|
+
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
35
|
+
|
|
36
|
+
objectUrl = URL.createObjectURL(
|
|
37
|
+
new Blob([bytes], { type: "image/png" }),
|
|
38
|
+
);
|
|
39
|
+
setSrc(objectUrl);
|
|
40
|
+
})
|
|
41
|
+
.catch(() => {
|
|
42
|
+
if (alive) setSrc("");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return () => {
|
|
46
|
+
alive = false;
|
|
47
|
+
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
48
|
+
};
|
|
49
|
+
}, [text, size, margin, ecc]);
|
|
50
|
+
|
|
51
|
+
return src;
|
|
52
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { qr_png_data_url } from "../index.web.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* React hook for QR Code Data URL (browser-only).
|
|
6
|
+
* Backward-compatible, but heavier than Blob URL due to base64.
|
|
7
|
+
* @param {string} text
|
|
8
|
+
* @param {{size?:number, margin?:number, ecc?:"L"|"M"|"Q"|"H"}} [opts]
|
|
9
|
+
*/
|
|
10
|
+
export function useQrPngDataUrl(text, opts) {
|
|
11
|
+
const size = opts?.size ?? 320;
|
|
12
|
+
const margin = opts?.margin ?? 4;
|
|
13
|
+
const ecc = opts?.ecc ?? "Q";
|
|
14
|
+
|
|
15
|
+
const [src, setSrc] = useState("");
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
let alive = true;
|
|
19
|
+
|
|
20
|
+
if (!text) {
|
|
21
|
+
setSrc("");
|
|
22
|
+
return () => {
|
|
23
|
+
alive = false;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
qr_png_data_url(text, size, margin, ecc)
|
|
28
|
+
.then((res) => {
|
|
29
|
+
if (alive) setSrc(res);
|
|
30
|
+
})
|
|
31
|
+
.catch(() => {
|
|
32
|
+
if (alive) setSrc("");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return () => {
|
|
36
|
+
alive = false;
|
|
37
|
+
};
|
|
38
|
+
}, [text, size, margin, ecc]);
|
|
39
|
+
|
|
40
|
+
return src;
|
|
41
|
+
}
|