@feugene/granularity-media 0.2.0 → 0.2.1

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.
@@ -1,11 +1,11 @@
1
1
  import { a as e, c as t, l as n, n as r, o as i, r as a, s as o, u as s } from "../../../chunks/config-CZ4ZDG0_.js";
2
2
  import { computed as c, createBlock as l, createCommentVNode as u, createElementBlock as d, createElementVNode as f, createTextVNode as p, createVNode as m, defineComponent as h, normalizeClass as g, normalizeStyle as _, onBeforeUnmount as v, onMounted as y, openBlock as b, ref as x, renderSlot as S, shallowRef as C, toDisplayString as w, unref as T, withCtx as E } from "vue";
3
3
  import D from "@feugene/granularity/components/GrButton";
4
- import { useAnnouncer as O } from "@feugene/granularity/composables/useAnnouncer";
5
- import { useGrComponentSize as k } from "@feugene/granularity/composables/useGrComponentConfig";
6
- import { useGranularityTranslations as A } from "@feugene/granularity/composables/useGranularityTranslations";
4
+ import { useAnnouncer as ee } from "@feugene/granularity/composables/useAnnouncer";
5
+ import { useGrComponentSize as te } from "@feugene/granularity/composables/useGrComponentConfig";
6
+ import { useGranularityTranslations as ne } from "@feugene/granularity/composables/useGranularityTranslations";
7
7
  //#region src/components/GrCameraCapture/cameraState.ts
8
- function j(e) {
8
+ function O(e) {
9
9
  switch (e instanceof Error ? e.name : "") {
10
10
  case "NotAllowedError":
11
11
  case "SecurityError":
@@ -19,13 +19,13 @@ function j(e) {
19
19
  default: return "error";
20
20
  }
21
21
  }
22
- function M(e) {
22
+ function k(e) {
23
23
  return typeof e?.mediaDevices?.getUserMedia == "function";
24
24
  }
25
- function N(e, t) {
25
+ function A(e, t) {
26
26
  return t ?? e === "user";
27
27
  }
28
- function P(e, t) {
28
+ function j(e, t) {
29
29
  let n = t > 0 ? t : 1;
30
30
  if (e.width <= 0 || e.height <= 0) return {
31
31
  sx: 0,
@@ -52,16 +52,16 @@ function P(e, t) {
52
52
  }
53
53
  //#endregion
54
54
  //#region src/components/GrCameraCapture/GrCameraCapture.vue?vue&type=script&setup=true&lang.ts
55
- var F = ["aria-label"], I = /* @__PURE__ */ h({
55
+ var M = ["aria-label"], N = /* @__PURE__ */ h({
56
56
  __name: "GrCameraCapture",
57
57
  props: {
58
58
  facing: { default: "user" },
59
59
  deviceId: { default: void 0 },
60
+ aspectRatio: { default: void 0 },
60
61
  autoStart: {
61
62
  type: Boolean,
62
63
  default: !1
63
64
  },
64
- aspectRatio: { default: 4 / 3 },
65
65
  mirror: {
66
66
  type: Boolean,
67
67
  default: void 0
@@ -80,118 +80,122 @@ var F = ["aria-label"], I = /* @__PURE__ */ h({
80
80
  "stop",
81
81
  "statusChange"
82
82
  ],
83
- setup(h, { expose: I, emit: L }) {
84
- let R = h, z = L, { t: B } = A(), { announce: V } = O(), H = k(() => R.size, { component: "GrCameraCapture" }), U = x(null), W = C(null), G = x("idle"), K = c(() => N(R.facing, R.mirror)), q = c(() => G.value === "live"), J = c(() => {
85
- switch (G.value) {
86
- case "starting": return B("grMedia.camera.starting", "Requesting camera access…");
87
- case "denied": return B("grMedia.camera.denied", "Camera access is blocked. Allow it in the browser settings for this site.");
88
- case "missing": return B("grMedia.camera.missing", "No camera found on this device.");
89
- case "busy": return B("grMedia.camera.busy", "The camera is busy in another application.");
90
- case "insecure": return B("grMedia.camera.insecure", "The camera works only over HTTPS.");
91
- case "error": return B("grMedia.camera.error", "The camera could not be started.");
92
- default: return B("grMedia.camera.idle", "The camera is off.");
83
+ setup(h, { expose: N, emit: P }) {
84
+ let F = h, I = P, { t: L } = ne(), { announce: R } = ee(), z = te(() => F.size, { component: "GrCameraCapture" }), B = x(null), V = C(null), H = x("idle"), U = x(null), W = c(() => F.aspectRatio ?? U.value ?? 4 / 3), G = c(() => A(F.facing, F.mirror)), K = c(() => H.value === "live"), q = c(() => {
85
+ switch (H.value) {
86
+ case "starting": return L("grMedia.camera.starting", "Requesting camera access…");
87
+ case "denied": return L("grMedia.camera.denied", "Camera access is blocked. Allow it in the browser settings for this site.");
88
+ case "missing": return L("grMedia.camera.missing", "No camera found on this device.");
89
+ case "busy": return L("grMedia.camera.busy", "The camera is busy in another application.");
90
+ case "insecure": return L("grMedia.camera.insecure", "The camera works only over HTTPS.");
91
+ case "error": return L("grMedia.camera.error", "The camera could not be started.");
92
+ default: return L("grMedia.camera.idle", "The camera is off.");
93
93
  }
94
94
  });
95
- function Y(e) {
96
- G.value !== e && (G.value = e, z("statusChange", e));
95
+ function J(e) {
96
+ H.value !== e && (H.value = e, I("statusChange", e));
97
+ }
98
+ function Y() {
99
+ let e = B.value;
100
+ !e || e.videoWidth <= 0 || e.videoHeight <= 0 || (U.value = e.videoWidth / e.videoHeight);
97
101
  }
98
102
  function X() {
99
- W.value?.getTracks().forEach((e) => e.stop()), W.value = null, U.value && (U.value.srcObject = null);
103
+ V.value?.getTracks().forEach((e) => e.stop()), V.value = null, U.value = null, B.value && (B.value.srcObject = null);
100
104
  }
101
105
  async function Z() {
102
- if (!(R.disabled || G.value === "starting" || G.value === "live")) {
103
- if (!M(navigator)) {
104
- Y("insecure");
106
+ if (!(F.disabled || H.value === "starting" || H.value === "live")) {
107
+ if (!k(navigator)) {
108
+ J("insecure");
105
109
  return;
106
110
  }
107
- Y("starting");
111
+ J("starting");
108
112
  try {
109
113
  let e = await navigator.mediaDevices.getUserMedia({
110
- video: R.deviceId ? { deviceId: { exact: R.deviceId } } : { facingMode: R.facing },
114
+ video: F.deviceId ? { deviceId: { exact: F.deviceId } } : { facingMode: F.facing },
111
115
  audio: !1
112
116
  });
113
- W.value = e, U.value && (U.value.srcObject = e, await U.value.play().catch(() => void 0)), Y("live"), z("start"), V(B("grMedia.camera.live", "Camera is on"));
117
+ V.value = e, B.value && (B.value.srcObject = e, B.value.addEventListener("loadedmetadata", Y, { once: !0 }), await B.value.play().catch(() => void 0), Y()), J("live"), I("start"), R(L("grMedia.camera.live", "Camera is on"));
114
118
  } catch (e) {
115
- X(), Y(j(e)), V(J.value, { politeness: "assertive" });
119
+ X(), J(O(e)), R(q.value, { politeness: "assertive" });
116
120
  }
117
121
  }
118
122
  }
119
123
  function Q() {
120
- W.value && (X(), Y("idle"), z("stop"));
124
+ V.value && (X(), J("idle"), I("stop"));
121
125
  }
122
126
  async function $() {
123
- let e = U.value;
124
- if (!e || !q.value) return null;
125
- let t = P({
127
+ let e = B.value;
128
+ if (!e || !K.value) return null;
129
+ let t = j({
126
130
  width: e.videoWidth,
127
131
  height: e.videoHeight
128
- }, R.aspectRatio);
132
+ }, W.value);
129
133
  if (t.sw <= 0) return null;
130
134
  let n = document.createElement("canvas");
131
- n.width = Math.max(1, Math.round(R.output?.width ?? t.sw)), n.height = Math.max(1, Math.round(R.output?.height ?? t.sh));
135
+ n.width = Math.max(1, Math.round(F.output?.width ?? t.sw)), n.height = Math.max(1, Math.round(F.output?.height ?? t.sh));
132
136
  let r = n.getContext("2d");
133
137
  if (!r) return null;
134
138
  r.drawImage(e, t.sx, t.sy, t.sw, t.sh, 0, 0, n.width, n.height);
135
139
  let i = await new Promise((e) => {
136
- n.toBlob(e, R.output?.type ?? "image/jpeg", R.output?.quality ?? .92);
140
+ n.toBlob(e, F.output?.type ?? "image/jpeg", F.output?.quality ?? .92);
137
141
  });
138
- return i && (z("capture", i), V(B("grMedia.camera.captured", "Photo taken"))), i;
142
+ return i && (I("capture", i), R(L("grMedia.camera.captured", "Photo taken"))), i;
139
143
  }
140
144
  return y(() => {
141
- R.autoStart && Z();
142
- }), v(X), I({
145
+ F.autoStart && Z();
146
+ }), v(X), N({
143
147
  start: Z,
144
148
  stop: Q,
145
149
  capture: $,
146
- status: G
150
+ status: H
147
151
  }), (c, v) => (b(), d("div", {
148
152
  class: g(T(i)),
149
153
  role: "group",
150
- "aria-label": h.ariaLabel ?? T(B)("grMedia.camera.label", "Camera")
154
+ "aria-label": h.ariaLabel ?? T(L)("grMedia.camera.label", "Camera")
151
155
  }, [f("div", {
152
156
  class: g(T(a)),
153
- style: _({ aspectRatio: String(h.aspectRatio) })
157
+ style: _({ aspectRatio: String(W.value) })
154
158
  }, [f("video", {
155
159
  ref_key: "videoEl",
156
- ref: U,
157
- class: g([T(s), K.value ? T(e) : ""]),
160
+ ref: B,
161
+ class: g([T(s), G.value ? T(e) : ""]),
158
162
  playsinline: "",
159
163
  muted: "",
160
164
  autoplay: ""
161
- }, null, 2), q.value ? u("", !0) : (b(), d("div", {
165
+ }, null, 2), K.value ? u("", !0) : (b(), d("div", {
162
166
  key: 0,
163
167
  class: g(T(t))
164
- }, [f("p", { class: g([T(n), T(o)[T(H)]]) }, w(J.value), 3), G.value !== "starting" && G.value !== "insecure" && G.value !== "missing" ? (b(), l(T(D), {
168
+ }, [f("p", { class: g([T(n), T(o)[T(z)]]) }, w(q.value), 3), H.value !== "starting" && H.value !== "insecure" && H.value !== "missing" ? (b(), l(T(D), {
165
169
  key: 0,
166
- size: T(H),
170
+ size: T(z),
167
171
  disabled: h.disabled,
168
172
  onClick: Z
169
173
  }, {
170
- default: E(() => [p(w(G.value === "idle" ? T(B)("grMedia.camera.start", "Turn on camera") : T(B)("grMedia.camera.retry", "Try again")), 1)]),
174
+ default: E(() => [p(w(H.value === "idle" ? T(L)("grMedia.camera.start", "Turn on camera") : T(L)("grMedia.camera.retry", "Try again")), 1)]),
171
175
  _: 1
172
176
  }, 8, ["size", "disabled"])) : u("", !0)], 2))], 6), f("div", { class: g(T(r)) }, [S(c.$slots, "controls", {
173
- status: G.value,
177
+ status: H.value,
174
178
  start: Z,
175
179
  stop: Q,
176
180
  capture: $
177
181
  }, () => [m(T(D), {
178
- size: T(H),
179
- disabled: h.disabled || !q.value,
182
+ size: T(z),
183
+ disabled: h.disabled || !K.value,
180
184
  onClick: $
181
185
  }, {
182
- default: E(() => [p(w(T(B)("grMedia.camera.capture", "Take photo")), 1)]),
186
+ default: E(() => [p(w(T(L)("grMedia.camera.capture", "Take photo")), 1)]),
183
187
  _: 1
184
- }, 8, ["size", "disabled"]), q.value ? (b(), l(T(D), {
188
+ }, 8, ["size", "disabled"]), K.value ? (b(), l(T(D), {
185
189
  key: 0,
186
190
  variant: "outline",
187
- size: T(H),
191
+ size: T(z),
188
192
  disabled: h.disabled,
189
193
  onClick: Q
190
194
  }, {
191
- default: E(() => [p(w(T(B)("grMedia.camera.stop", "Turn off")), 1)]),
195
+ default: E(() => [p(w(T(L)("grMedia.camera.stop", "Turn off")), 1)]),
192
196
  _: 1
193
- }, 8, ["size", "disabled"])) : u("", !0)])], 2)], 10, F));
197
+ }, 8, ["size", "disabled"])) : u("", !0)])], 2)], 10, M));
194
198
  }
195
199
  });
196
200
  //#endregion
197
- export { N as a, M as i, P as n, j as r, I as t };
201
+ export { A as a, k as i, j as n, O as r, N as t };
@@ -1,3 +1,3 @@
1
- import { a as e, i as t, n, r, t as i } from "./chunks/GrCameraCapture-DJKFrVfw.js";
1
+ import { a as e, i as t, n, r, t as i } from "./chunks/GrCameraCapture-B9EPXm7r.js";
2
2
  import { i as a, t as o } from "../../chunks/config-CZ4ZDG0_.js";
3
3
  export { i as GrCameraCapture, i as default, n as cameraFrameRect, r as cameraStatusFromError, t as cameraSupported, o as grCameraCaptureConfig, a as grCameraCaptureSafelist, e as shouldMirrorPreview };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as e, i as t, n, r, t as i } from "./components/GrCameraCapture/chunks/GrCameraCapture-DJKFrVfw.js";
1
+ import { a as e, i as t, n, r, t as i } from "./components/GrCameraCapture/chunks/GrCameraCapture-B9EPXm7r.js";
2
2
  import { i as a, t as o } from "./chunks/config-CZ4ZDG0_.js";
3
3
  import { a as s, i as c, n as l, o as u, r as d, s as f, t as p } from "./components/GrImageCrop/chunks/GrImageCrop-Fo2qrX2n.js";
4
4
  import { a as m, t as h } from "./chunks/config-Be_Mh801.js";
@@ -11,6 +11,13 @@ export interface GrCameraCaptureProps {
11
11
  facing?: GrCameraFacing;
12
12
  /** Конкретное устройство, если приложение его уже выбрало. */
13
13
  deviceId?: string;
14
+ /**
15
+ * Соотношение сторон рамки и снимка.
16
+ *
17
+ * Без него рамка принимает соотношение самого потока: камеры отдают то 4:3,
18
+ * то 16:9, и любое зашитое число показало бы обрезанный кадр как настоящий.
19
+ */
20
+ aspectRatio?: number;
14
21
  /**
15
22
  * Включать камеру сразу.
16
23
  *
@@ -18,7 +25,6 @@ export interface GrCameraCaptureProps {
18
25
  * отклоняют не глядя, а второй раз браузер уже не спросит.
19
26
  */
20
27
  autoStart?: boolean;
21
- aspectRatio?: number;
22
28
  /** Зеркалить превью. По умолчанию — только фронтальную камеру. */
23
29
  mirror?: boolean;
24
30
  output?: GrCameraCaptureOutput;
@@ -55,7 +61,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
55
61
  facing: string;
56
62
  deviceId: undefined;
57
63
  autoStart: boolean;
58
- aspectRatio: number;
64
+ aspectRatio: undefined;
59
65
  mirror: undefined;
60
66
  output: undefined;
61
67
  size: undefined;
@@ -75,7 +81,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
75
81
  facing: string;
76
82
  deviceId: undefined;
77
83
  autoStart: boolean;
78
- aspectRatio: number;
84
+ aspectRatio: undefined;
79
85
  mirror: undefined;
80
86
  output: undefined;
81
87
  size: undefined;
@@ -89,8 +95,8 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
89
95
  }>, {
90
96
  facing: GrCameraFacing;
91
97
  deviceId: string;
92
- autoStart: boolean;
93
98
  aspectRatio: number;
99
+ autoStart: boolean;
94
100
  mirror: boolean;
95
101
  output: GrCameraCaptureOutput;
96
102
  size: GrCameraCaptureSize;
@@ -85,12 +85,12 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
85
85
  ariaLabel: undefined;
86
86
  }>>> & Readonly<{
87
87
  onError?: ((error: unknown) => any) | undefined;
88
- "onUpdate:zoom"?: ((value: number) => any) | undefined;
89
88
  onChange?: ((rect: GrCropRect) => any) | undefined;
90
89
  onLoad?: ((size: {
91
90
  width: number;
92
91
  height: number;
93
92
  }) => any) | undefined;
93
+ "onUpdate:zoom"?: ((value: number) => any) | undefined;
94
94
  }>, {
95
95
  aspectRatio: number;
96
96
  output: GrImageCropOutput;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@feugene/granularity-media",
3
3
  "description": "Media components for @feugene/granularity: image cropping, camera capture, code scanning and video playback.",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": {
7
7
  "name": "Evgeniy Fureev",