@nddeps/barcode-scanner 0.1.0 → 0.2.0

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/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { default as BarcodeScanner } from './barcode-scanner';
1
+ import { BarcodeScanner } from './barcode-scanner';
2
2
  export type * from './barcode-detector.type';
3
3
  export type * from './barcode-scanner.types';
4
+ export * as utils from './utils';
4
5
  export { BarcodeScanner };
5
6
  export default BarcodeScanner;
package/dist/index.js CHANGED
@@ -1,4 +1,76 @@
1
- var barcode_scanner_default = class {
1
+ var __defProp = Object.defineProperty, __export = (t, n) => {
2
+ let r = {};
3
+ for (var i in t) __defProp(r, i, {
4
+ get: t[i],
5
+ enumerable: !0
6
+ });
7
+ return n && __defProp(r, Symbol.toStringTag, { value: "Module" }), r;
8
+ };
9
+ function getVideoRenderedOffset(e, t) {
10
+ let [n, r] = window.getComputedStyle(e).objectPosition.split(" ").map((n, r) => n.endsWith("%") ? (r === 0 ? e.offsetWidth - t.width : e.offsetHeight - t.height) * parseFloat(n) / 100 : parseFloat(n));
11
+ return {
12
+ x: n,
13
+ y: r
14
+ };
15
+ }
16
+ function getVideoRenderedSize(e) {
17
+ let t = window.getComputedStyle(e), n = e.offsetWidth / e.offsetHeight, r = e.videoWidth / e.videoHeight;
18
+ switch (t.objectFit) {
19
+ case "contain": return {
20
+ height: r < n ? e.offsetHeight : e.offsetWidth / r,
21
+ width: r < n ? e.offsetHeight * r : e.offsetWidth
22
+ };
23
+ case "cover": return {
24
+ height: r > n ? e.offsetHeight : e.offsetWidth / r,
25
+ width: r > n ? e.offsetHeight * r : e.offsetWidth
26
+ };
27
+ case "fill": return {
28
+ height: e.offsetHeight,
29
+ width: e.offsetWidth
30
+ };
31
+ case "none": return {
32
+ height: e.videoHeight,
33
+ width: e.videoWidth
34
+ };
35
+ case "scale-down": return {
36
+ height: Math.min(r < n ? e.offsetHeight : e.offsetWidth / r, e.videoHeight),
37
+ width: Math.min(r < n ? e.offsetHeight * r : e.offsetWidth, e.videoWidth)
38
+ };
39
+ default: return {
40
+ height: e.videoHeight,
41
+ width: e.videoWidth
42
+ };
43
+ }
44
+ }
45
+ function convertToElementArea(e, t) {
46
+ let i = /scaleX\(-1\)/.test(e.style.transform), a = e.videoHeight, o = e.videoWidth, s = getVideoRenderedSize(e), c = getVideoRenderedOffset(e, s), l = i ? o - t.x : t.x, u = t.y;
47
+ return {
48
+ height: t.height / a * s.height,
49
+ width: t.width / o * s.width,
50
+ x: l / o * s.width + c.x,
51
+ y: u / a * s.height + c.y
52
+ };
53
+ }
54
+ function convertToVideoArea(e, t) {
55
+ let i = /scaleX\(-1\)/.test(e.style.transform), a = e.videoHeight, o = e.videoWidth, s = getVideoRenderedSize(e), c = getVideoRenderedOffset(e, s), l = o / s.width, u = a / s.height, d = t.x - c.x, f = i ? s.width - d - t.width : d, p = t.y - c.y;
56
+ return {
57
+ height: t.height * u,
58
+ width: t.width * l,
59
+ x: f * l,
60
+ y: p * u
61
+ };
62
+ }
63
+ function isBarcodeDetectorAvailable(e) {
64
+ return "BarcodeDetector" in e;
65
+ }
66
+ var utils_exports = /* @__PURE__ */ __export({
67
+ convertToElementArea: () => convertToElementArea,
68
+ convertToVideoArea: () => convertToVideoArea,
69
+ getVideoRenderedOffset: () => getVideoRenderedOffset,
70
+ getVideoRenderedSize: () => getVideoRenderedSize,
71
+ isBarcodeDetectorAvailable: () => isBarcodeDetectorAvailable
72
+ }, 1), BarcodeScanner = class {
73
+ calcScanArea;
2
74
  canvas;
3
75
  canvasContext;
4
76
  debug;
@@ -10,7 +82,6 @@ var barcode_scanner_default = class {
10
82
  onDecodeError;
11
83
  onVisibilityChange;
12
84
  requestFrame;
13
- resizeObserver;
14
85
  resumeOnVisibilityChange;
15
86
  scanArea;
16
87
  scanRate;
@@ -25,9 +96,7 @@ var barcode_scanner_default = class {
25
96
  this.canvas = document.createElement("canvas");
26
97
  let i = this.canvas.getContext("2d", { willReadFrequently: !0 });
27
98
  if (!i) throw Error("Failed to get canvas context");
28
- this.canvasContext = i, this.debug = n?.debug, this.decodeTimeout = n?.decodeTimeout ?? 1e3, this.isDecodeFrameProcessed = !1, this.isDestroyed = !1, this.onDecode = e, this.onDecodeError = t, this.requestFrame = r.requestVideoFrameCallback ? r.requestVideoFrameCallback.bind(r) : requestAnimationFrame, this.decodeFrameRequestTimestamp = performance.now(), this.resumeOnVisibilityChange = !1, this.scanArea = this.getScanArea(r), this.scanRate = n?.scanRate ?? 24, this.video = r, this.video.autoplay = !0, this.video.disablePictureInPicture = !0, this.video.hidden = !1, this.video.muted = !0, this.video.playsInline = !0, this.videoActive = !1, this.videoPaused = !1, this.resizeObserver = new ResizeObserver(() => {
29
- this.scanArea = this.getScanArea(this.video);
30
- }), this.resizeObserver.observe(this.video), this.onVisibilityChange = () => {
99
+ this.calcScanArea = n?.calcScanArea ?? this.getScanArea, this.canvasContext = i, this.debug = n?.debug, this.decodeTimeout = n?.decodeTimeout ?? 1e3, this.isDecodeFrameProcessed = !1, this.isDestroyed = !1, this.onDecode = e, this.onDecodeError = t, this.requestFrame = r.requestVideoFrameCallback ? r.requestVideoFrameCallback.bind(r) : requestAnimationFrame, this.decodeFrameRequestTimestamp = performance.now(), this.resumeOnVisibilityChange = !1, this.scanArea = this.calcScanArea(r), this.scanRate = n?.scanRate ?? 24, this.video = r, this.video.autoplay = !0, this.video.disablePictureInPicture = !0, this.video.hidden = !1, this.video.muted = !0, this.video.playsInline = !0, this.videoActive = !1, this.videoPaused = !1, this.onVisibilityChange = () => {
31
100
  document.visibilityState === "hidden" ? (this.videoActive && this.videoPaused === !1 && (this.resumeOnVisibilityChange = !0), this.pause()) : this.resumeOnVisibilityChange && (this.resumeOnVisibilityChange = !1, this.start());
32
101
  }, document.addEventListener("visibilitychange", this.onVisibilityChange), this.worker = new Worker(new URL(
33
102
  /* @vite-ignore */
@@ -51,7 +120,7 @@ var barcode_scanner_default = class {
51
120
  });
52
121
  }
53
122
  async destroy() {
54
- this.isDestroyed ||= (await this.stop(), document.removeEventListener("visibilitychange", this.onVisibilityChange), this.resizeObserver.disconnect(), this.worker.terminate(), !0);
123
+ this.isDestroyed ||= (await this.stop(), document.removeEventListener("visibilitychange", this.onVisibilityChange), this.worker.terminate(), !0);
55
124
  }
56
125
  async getCameraAccess() {
57
126
  if (await this.hasCameraAccess()) return !0;
@@ -72,35 +141,6 @@ var barcode_scanner_default = class {
72
141
  y: Math.round((e.videoHeight - t) / 2)
73
142
  };
74
143
  }
75
- getScanAreaPosition(e = this.scanArea) {
76
- let t = window.getComputedStyle(this.video), n = /scaleX\(-1\)/.test(this.video.style.transform), r = t.objectFit, i = t.objectPosition, a = this.video.offsetLeft, o = this.video.offsetTop, s = this.video.offsetHeight, c = this.video.offsetWidth, l = c / s, u = this.video.videoHeight, d = this.video.videoWidth, f = d / u, p = e.width || d, m = e.height || u, h = e.x || 0, g = e.y || 0, _, v;
77
- switch (r) {
78
- case "contain":
79
- case "cover": {
80
- let e = r === "contain" ? f < l : f > l;
81
- _ = e ? s : c / f, v = e ? s * f : c;
82
- break;
83
- }
84
- case "none":
85
- _ = u, v = d;
86
- break;
87
- case "scale-down": {
88
- let e = f < l;
89
- _ = Math.min(e ? c / f : s, u), v = Math.min(e ? s * f : c, d);
90
- break;
91
- }
92
- default:
93
- _ = s, v = c;
94
- break;
95
- }
96
- let [y, b] = i.split(" ").map((e, t) => e.endsWith("%") ? (t === 0 ? c - v : s - _) * parseFloat(e) / 100 : parseFloat(e)), x = (n ? h : d - h - p) / d * v, S = g / u * _, C = v / d;
97
- return {
98
- height: _ / u * m,
99
- width: p * C,
100
- x: a + (n ? y : c - y - v) + x,
101
- y: o + b + S
102
- };
103
- }
104
144
  async hasCameraAccess() {
105
145
  try {
106
146
  return (await navigator.permissions.query({ name: "camera" })).state === "granted";
@@ -113,7 +153,7 @@ var barcode_scanner_default = class {
113
153
  }
114
154
  async start({ facingMode: e = "environment" } = {}) {
115
155
  if (!await this.getCameraAccess()) throw Error("No camera access");
116
- this.video.srcObject instanceof MediaStream && this.videoActive && this.videoPaused === !1 || (this.video.srcObject instanceof MediaStream || (this.video.srcObject = await navigator.mediaDevices.getUserMedia({ video: { facingMode: e } })), await this.video.play(), this.scanArea = this.getScanArea(this.video), this.video.style.transform = e === "user" ? "scaleX(-1)" : "none", this.videoActive = !0, this.videoPaused = !1, this.decodeFrame());
156
+ this.video.srcObject instanceof MediaStream && this.videoActive && this.videoPaused === !1 || (this.video.srcObject instanceof MediaStream || (this.video.srcObject = await navigator.mediaDevices.getUserMedia({ video: { facingMode: e } })), await this.video.play(), this.video.style.transform = e === "user" ? "scaleX(-1)" : "none", this.videoActive = !0, this.videoPaused = !1, this.decodeFrame());
117
157
  }
118
158
  async stop() {
119
159
  this.video.srcObject instanceof MediaStream && this.video.srcObject.getTracks().forEach((e) => e.stop()), this.video.poster = "", this.video.srcObject = null, this.videoActive = !1, this.videoPaused = !1;
@@ -124,18 +164,18 @@ var barcode_scanner_default = class {
124
164
  this.decodeFrameRequestTimestamp = performance.now(), this.decodeFrame();
125
165
  return;
126
166
  }
127
- this.isDecodeFrameProcessed = !0, this.canvas.height = this.scanArea.height, this.canvas.width = this.scanArea.width, this.canvasContext.clearRect(0, 0, this.canvas.width, this.canvas.height), this.canvasContext.drawImage(this.video, this.scanArea.x, this.scanArea.y, this.scanArea.width, this.scanArea.height, 0, 0, this.canvas.width, this.canvas.height);
167
+ this.isDecodeFrameProcessed = !0, this.scanArea = this.calcScanArea(this.video), this.canvas.height = this.scanArea.height, this.canvas.width = this.scanArea.width, this.canvasContext.clearRect(0, 0, this.canvas.width, this.canvas.height), this.canvasContext.drawImage(this.video, this.scanArea.x, this.scanArea.y, this.scanArea.width, this.scanArea.height, 0, 0, this.canvas.width, this.canvas.height);
128
168
  let e = this.canvasContext.getImageData(0, 0, this.canvas.width, this.canvas.height);
129
169
  this.debug && window.dispatchEvent(new CustomEvent("barcode-scanner:decode-frame", { detail: { imageData: e } })), this.decode(e).then((e) => {
130
170
  if (e) {
131
171
  let t = e.cornerPoints.map((e) => e.x), n = e.cornerPoints.map((e) => e.y);
132
- this.onDecode(e.rawValue, this.getScanAreaPosition({
172
+ this.onDecode(e.rawValue, convertToElementArea(this.video, {
133
173
  height: Math.max(...n) - Math.min(...n),
134
174
  width: Math.max(...t) - Math.min(...t),
135
175
  x: Math.min(...t) + this.scanArea.x,
136
176
  y: Math.min(...n) + this.scanArea.y
137
177
  }));
138
- } else this.onDecode(null);
178
+ } else this.onDecode(null, convertToElementArea(this.video, this.scanArea));
139
179
  }).catch(() => {
140
180
  this.onDecodeError?.();
141
181
  }).finally(() => {
@@ -143,5 +183,5 @@ var barcode_scanner_default = class {
143
183
  });
144
184
  });
145
185
  }
146
- }, lib_default = barcode_scanner_default;
147
- export { barcode_scanner_default as BarcodeScanner, lib_default as default };
186
+ }, lib_default = BarcodeScanner;
187
+ export { BarcodeScanner, lib_default as default, utils_exports as utils };
@@ -0,0 +1,3 @@
1
+ import type { ScanArea } from '../barcode-scanner.types';
2
+ declare function convertToElementArea(video: HTMLVideoElement, scanArea: ScanArea): ScanArea;
3
+ export { convertToElementArea };
@@ -0,0 +1,3 @@
1
+ import type { ScanArea } from '../barcode-scanner.types';
2
+ declare function convertToVideoArea(video: HTMLVideoElement, scanArea: ScanArea): ScanArea;
3
+ export { convertToVideoArea };
@@ -0,0 +1,8 @@
1
+ declare function getVideoRenderedOffset(video: HTMLVideoElement, scaledSize: {
2
+ height: number;
3
+ width: number;
4
+ }): {
5
+ x: number;
6
+ y: number;
7
+ };
8
+ export { getVideoRenderedOffset };
@@ -0,0 +1,5 @@
1
+ declare function getVideoRenderedSize(video: HTMLVideoElement): {
2
+ height: number;
3
+ width: number;
4
+ };
5
+ export { getVideoRenderedSize };
@@ -0,0 +1,5 @@
1
+ export * from './convert-to-element-area';
2
+ export * from './convert-to-video-area';
3
+ export * from './get-video-rendered-offset';
4
+ export * from './get-video-rendered-size';
5
+ export * from './is-barcode-detector-available';
@@ -0,0 +1,5 @@
1
+ import type { BarcodeDetector } from '../barcode-detector.type';
2
+ declare function isBarcodeDetectorAvailable<T extends object>(value: T): value is {
3
+ BarcodeDetector: BarcodeDetector;
4
+ } & T;
5
+ export { isBarcodeDetectorAvailable };
package/package.json CHANGED
@@ -1,63 +1,66 @@
1
- {
2
- "name": "@nddeps/barcode-scanner",
3
- "version": "0.1.0",
4
- "private": false,
5
- "keywords": [
6
- "barcode",
7
- "scanner",
8
- "barcode-scanner"
9
- ],
10
- "homepage": "https://github.com/No-Deprecated-Dependencies/barcode-scanner",
11
- "repository": {
12
- "type": "git",
13
- "url": "https://github.com/No-Deprecated-Dependencies/barcode-scanner.git"
14
- },
15
- "license": "MIT",
16
- "author": "Aleksei Saenko",
17
- "type": "module",
18
- "exports": {
19
- ".": {
20
- "types": "./dist/index.d.ts",
21
- "import": "./dist/index.js"
22
- }
23
- },
24
- "main": "./dist/index.js",
25
- "types": "./dist/index.d.ts",
26
- "files": [
27
- "./dist"
28
- ],
29
- "scripts": {
30
- "build": "vite build && tsc -b",
31
- "dev": "vite",
32
- "preview": "vite preview"
33
- },
34
- "overrides": {
35
- "vite": "npm:rolldown-vite@7.2.11"
36
- },
37
- "dependencies": {
38
- "jsqr": "^1.4.0"
39
- },
40
- "devDependencies": {
41
- "@eslint/css": "^0.14.1",
42
- "@eslint/js": "^9.39.2",
43
- "@eslint/json": "^0.14.0",
44
- "@eslint/markdown": "^7.5.1",
45
- "@types/node": "^25.0.2",
46
- "eslint": "^9.39.2",
47
- "eslint-config-prettier": "^10.1.8",
48
- "eslint-plugin-perfectionist": "^4.15.1",
49
- "eslint-plugin-prettier": "^5.5.4",
50
- "globals": "^16.5.0",
51
- "jiti": "^2.6.1",
52
- "prettier": "3.7.4",
53
- "sort-package-json": "^3.5.1",
54
- "stylelint": "^16.26.1",
55
- "stylelint-config-recess-order": "^7.4.0",
56
- "stylelint-config-standard": "^39.0.1",
57
- "stylelint-config-standard-scss": "^16.0.0",
58
- "stylelint-order": "^7.0.0",
59
- "typescript": "~5.9.3",
60
- "typescript-eslint": "^8.49.0",
61
- "vite": "npm:rolldown-vite@7.2.11"
62
- }
63
- }
1
+ {
2
+ "name": "@nddeps/barcode-scanner",
3
+ "version": "0.2.0",
4
+ "private": false,
5
+ "keywords": [
6
+ "barcode",
7
+ "scanner",
8
+ "barcode-scanner"
9
+ ],
10
+ "homepage": "https://github.com/No-Deprecated-Dependencies/barcode-scanner",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/No-Deprecated-Dependencies/barcode-scanner.git"
14
+ },
15
+ "license": "MIT",
16
+ "author": "Aleksei Saenko",
17
+ "type": "module",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
24
+ "main": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "files": [
27
+ "./dist"
28
+ ],
29
+ "scripts": {
30
+ "build": "vite build && tsc -b",
31
+ "dev": "vite",
32
+ "preview": "vite preview"
33
+ },
34
+ "overrides": {
35
+ "vite": "npm:rolldown-vite@7.2.11"
36
+ },
37
+ "dependencies": {
38
+ "barcode-detector": "^3.0.8",
39
+ "jsqr": "^1.4.0",
40
+ "zxing-wasm": "^2.2.4"
41
+ },
42
+ "devDependencies": {
43
+ "@eslint/css": "^0.14.1",
44
+ "@eslint/js": "^9.39.2",
45
+ "@eslint/json": "^0.14.0",
46
+ "@eslint/markdown": "^7.5.1",
47
+ "@types/emscripten": "^1.41.5",
48
+ "@types/node": "^25.0.2",
49
+ "eslint": "^9.39.2",
50
+ "eslint-config-prettier": "^10.1.8",
51
+ "eslint-plugin-perfectionist": "^4.15.1",
52
+ "eslint-plugin-prettier": "^5.5.4",
53
+ "globals": "^16.5.0",
54
+ "jiti": "^2.6.1",
55
+ "prettier": "3.7.4",
56
+ "sort-package-json": "^3.5.1",
57
+ "stylelint": "^16.26.1",
58
+ "stylelint-config-recess-order": "^7.4.0",
59
+ "stylelint-config-standard": "^39.0.1",
60
+ "stylelint-config-standard-scss": "^16.0.0",
61
+ "stylelint-order": "^7.0.0",
62
+ "typescript": "~5.9.3",
63
+ "typescript-eslint": "^8.49.0",
64
+ "vite": "npm:rolldown-vite@7.2.11"
65
+ }
66
+ }