ablok-components 0.3.128 → 0.3.131
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/ablok-components.css +1 -1
- package/dist/ablok-components.umd.js +2 -2
- package/dist/components/atoms/canvas-confetti/canvas-confetti.vue.d.ts +1 -1
- package/dist/components/molecules/base-camera/base-camera.js +5 -4
- package/dist/components/molecules/base-camera/base-camera.vue.d.ts +204 -66
- package/dist/components/molecules/base-camera/base-camera.vue_vue_type_script_setup_true_lang.js +410 -0
- package/dist/components/molecules/base-map/base-map.vue.d.ts +2 -2
- package/dist/components/molecules/camera-preview/camera-preview.js +7 -0
- package/dist/components/molecules/camera-preview/camera-preview.vue.d.ts +32 -0
- package/dist/components/molecules/camera-preview/camera-preview.vue_vue_type_script_setup_true_lang.js +67 -0
- package/dist/components/molecules/popover-tooltip/popover-tooltip.vue.d.ts +1 -1
- package/dist/composables/useCamera.d.ts +37 -0
- package/dist/composables/useCamera.js +44 -0
- package/dist/index.js +34 -34
- package/dist/symbol-defs.svg +6 -0
- package/dist/utilities/camera/CameraManager.d.ts +91 -0
- package/dist/utilities/camera/CameraManager.js +345 -0
- package/dist/utilities/camera/capture.d.ts +35 -0
- package/dist/utilities/camera/capture.js +82 -0
- package/dist/utilities/camera/constraints.d.ts +29 -0
- package/dist/utilities/camera/constraints.js +96 -0
- package/dist/utilities/camera/platform.d.ts +11 -0
- package/dist/utilities/camera/platform.js +20 -0
- package/dist/utilities/camera/types.d.ts +48 -0
- package/dist/utilities/camera/types.js +9 -0
- package/dist/utilities/helpers.js +10 -15
- package/package.json +1 -1
- package/dist/components/molecules/base-camera/base-camera.vue_vue_type_script_async_true_setup_true_lang.js +0 -537
package/dist/index.js
CHANGED
|
@@ -24,37 +24,37 @@ import S from "./components/molecules/input-color/input-color.js";
|
|
|
24
24
|
import C from "./components/molecules/color-palette/color-palette.js";
|
|
25
25
|
import w from "./components/molecules/input-dropdown/input-dropdown.js";
|
|
26
26
|
import T from "./components/molecules/auto-suggest/auto-suggest.js";
|
|
27
|
-
import
|
|
28
|
-
import D from "./components/molecules/base-
|
|
29
|
-
import O from "./components/molecules/
|
|
30
|
-
import k from "./components/molecules/
|
|
31
|
-
import A from "./components/molecules/
|
|
32
|
-
import j from "./components/
|
|
33
|
-
import M from "./components/
|
|
34
|
-
import N from "./components/molecules/image-
|
|
35
|
-
import P from "./components/molecules/image-crop/image-crop.js";
|
|
36
|
-
import F from "./components/
|
|
37
|
-
import I from "./components/
|
|
38
|
-
import L from "./components/molecules/
|
|
39
|
-
import R from "./components/
|
|
40
|
-
import z from "./components/
|
|
41
|
-
import B from "./components/
|
|
42
|
-
import V from "./
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import
|
|
46
|
-
import G from "./components/
|
|
47
|
-
import K from "./components/
|
|
48
|
-
import q from "./components/molecules/
|
|
49
|
-
import J from "./components/molecules/
|
|
50
|
-
import Y from "./components/molecules/
|
|
51
|
-
import X from "./components/molecules/popover-
|
|
52
|
-
import Z from "./components/molecules/
|
|
53
|
-
import Q from "./components/molecules/
|
|
54
|
-
import $ from "./components/molecules/
|
|
55
|
-
import ee from "./components/
|
|
56
|
-
import te from "./components/templates/
|
|
57
|
-
import ne from "./components/
|
|
58
|
-
import re from "./components/
|
|
59
|
-
import ie from "./
|
|
60
|
-
export { o as Accordion, a as AccordionItem,
|
|
27
|
+
import E from "./components/molecules/base-camera/base-camera.js";
|
|
28
|
+
import D from "./components/molecules/base-map/base-map.js";
|
|
29
|
+
import O from "./components/molecules/location-list/location-list.js";
|
|
30
|
+
import k from "./components/molecules/file-upload/file-upload.js";
|
|
31
|
+
import A from "./components/molecules/bulk-upload/bulk-upload.js";
|
|
32
|
+
import j from "./components/templates/sortable-list/sortable-list.js";
|
|
33
|
+
import M from "./components/molecules/image-resize/image-resize.js";
|
|
34
|
+
import N from "./components/molecules/image-crop/image-crop.js";
|
|
35
|
+
import P from "./components/molecules/image-crop-resize/image-crop-resize.js";
|
|
36
|
+
import F from "./components/templates/modal-dialog/modal-dialog.js";
|
|
37
|
+
import I from "./components/molecules/image-upload/image-upload.js";
|
|
38
|
+
import L from "./components/molecules/upload-group/upload-group.js";
|
|
39
|
+
import R from "./components/organisms/asset-uploader/asset-uploader.js";
|
|
40
|
+
import z from "./components/templates/popover-dialog/popover-dialog.js";
|
|
41
|
+
import B from "./components/organisms/preset-uploader/preset-uploader.js";
|
|
42
|
+
import { useDirections as V } from "./composables/useDirections.js";
|
|
43
|
+
import { useGeocoding as H } from "./composables/useGeocoding.js";
|
|
44
|
+
import { useGeolocation as U } from "./composables/useGeolocation.js";
|
|
45
|
+
import W from "./components/organisms/location-finder/location-finder.js";
|
|
46
|
+
import G from "./components/templates/base-carousel/base-carousel.js";
|
|
47
|
+
import K from "./components/molecules/media-thumbnails/media-thumbnails.js";
|
|
48
|
+
import q from "./components/molecules/progress-steps/progress-steps.js";
|
|
49
|
+
import J from "./components/molecules/hint-system/hint-system.js";
|
|
50
|
+
import Y from "./components/molecules/popover-tooltip/popover-tooltip.js";
|
|
51
|
+
import X from "./components/molecules/popover-notifications/popover-notifications.js";
|
|
52
|
+
import Z from "./components/molecules/dom-renderer/dom-renderer.js";
|
|
53
|
+
import Q from "./components/molecules/qr-code/qr-code.js";
|
|
54
|
+
import $ from "./components/molecules/link-sharing/link-sharing.js";
|
|
55
|
+
import ee from "./components/templates/base-form/base-form.js";
|
|
56
|
+
import te from "./components/templates/touch-wrapper/touch-wrapper.js";
|
|
57
|
+
import ne from "./components/atoms/canvas-confetti/canvas-confetti.js";
|
|
58
|
+
import re from "./components/molecules/image-zoom/image-zoom.js";
|
|
59
|
+
import { useCameraFilter as ie } from "./composables/useCameraFilter.js";
|
|
60
|
+
export { o as Accordion, a as AccordionItem, R as AssetUploader, T as AutoSuggest, s as BaseButton, E as BaseCamera, G as BaseCarousel, ee as BaseForm, r as BaseHeadline, n as BaseImage, c as BaseInput, D as BaseMap, i as BaseParagraph, A as BulkUpload, ne as CanvasConfetti, h as CheckGroup, C as ColorPalette, y as CustomHtml, Z as DomRenderer, k as FileUpload, J as HintSystem, N as ImageCrop, P as ImageCropResize, M as ImageResize, I as ImageUpload, re as ImageZoom, u as InputCheckbox, S as InputColor, f as InputDatepicker, d as InputDatetime, w as InputDropdown, v as InputFile, m as InputPasscode, p as InputPassword, l as InputTextarea, $ as LinkSharing, t as LoadingSpinner, W as LocationFinder, O as LocationList, K as MediaThumbnails, F as ModalDialog, z as PopoverDialog, X as PopoverNotifications, Y as PopoverTooltip, B as PresetUploader, q as ProgressSteps, Q as QrCode, _ as RadioButtons, g as RadioGroup, x as RteEditor, b as SelectMedia, j as SortableList, e as SvgIcon, te as TouchWrapper, L as UploadGroup, ie as useCameraFilter, V as useDirections, H as useGeocoding, U as useGeolocation };
|
package/dist/symbol-defs.svg
CHANGED
|
@@ -885,5 +885,11 @@
|
|
|
885
885
|
<symbol id="icon-crop" viewBox="0 0 32 32">
|
|
886
886
|
<path d="M7.593 1.409c-0.305 0.096-0.585 0.323-0.756 0.612l-0.144 0.245-0.016 2.2-0.015 2.2h-2.069c-2.249 0-2.383 0.015-2.751 0.295-0.107 0.081-0.26 0.259-0.339 0.393-0.121 0.208-0.144 0.307-0.144 0.645 0 0.341 0.021 0.437 0.148 0.652 0.081 0.137 0.231 0.315 0.333 0.392 0.364 0.277 0.425 0.284 2.704 0.287l2.119 0.003 0.029 12.773 0.125 0.373c0.439 1.307 1.395 2.263 2.701 2.701l0.373 0.125 12.769 0.029 0.015 2.203 0.016 2.203 0.161 0.263c0.091 0.147 0.273 0.337 0.415 0.433 0.628 0.421 1.469 0.228 1.876-0.433l0.161-0.263 0.016-2.204 0.015-2.204 2.119-0.003c2.277-0.003 2.339-0.009 2.703-0.287 0.103-0.077 0.252-0.255 0.333-0.392 0.127-0.215 0.148-0.311 0.148-0.652 0-0.339-0.023-0.437-0.144-0.645-0.079-0.135-0.232-0.312-0.339-0.393-0.368-0.28-0.501-0.295-2.751-0.295h-2.071l-0.029-12.773-0.125-0.373c-0.44-1.309-1.42-2.287-2.7-2.692l-0.428-0.135-12.716-0.029-0.015-2.199-0.016-2.199-0.144-0.245c-0.325-0.553-0.963-0.801-1.569-0.612zM21.747 9.415c0.372 0.111 0.728 0.467 0.839 0.839 0.071 0.237 0.081 1.064 0.081 6.344v6.071l-12.4-0.028-0.245-0.144c-0.135-0.079-0.309-0.229-0.388-0.332-0.315-0.412-0.3-0.088-0.3-6.731v-6.1h6.071c5.279 0 6.105 0.011 6.343 0.081z"></path>
|
|
887
887
|
</symbol>
|
|
888
|
+
<symbol id="icon-zap-off" viewBox="0 0 32 32">
|
|
889
|
+
<path d="M2.227 1.415c-0.296 0.108-0.56 0.331-0.723 0.607-0.123 0.208-0.144 0.305-0.143 0.645 0 0.283 0.029 0.455 0.099 0.587 0.053 0.103 1.643 1.735 3.531 3.627l3.435 3.44-2.565 2.64c-1.409 1.452-2.647 2.763-2.747 2.912-0.265 0.391-0.396 0.779-0.431 1.276-0.091 1.284 0.747 2.436 2.017 2.775 0.239 0.063 1.103 0.076 5.132 0.077 3.975 0 4.841 0.012 4.819 0.069-0.015 0.039-0.611 1.893-1.324 4.12-1.273 3.976-1.297 4.059-1.297 4.504-0.001 0.396 0.020 0.497 0.165 0.805 0.552 1.173 2.092 1.539 3.043 0.723 0.141-0.121 1.503-1.505 3.024-3.075s2.92-3.009 3.105-3.2l0.34-0.345 3.427 3.42c1.884 1.881 3.511 3.465 3.613 3.519 0.132 0.069 0.304 0.099 0.587 0.099 0.344 0.001 0.436-0.020 0.656-0.149 0.635-0.373 0.863-1.2 0.497-1.812-0.073-0.123-6.2-6.287-13.616-13.697-12.471-12.461-13.504-13.48-13.747-13.56-0.315-0.104-0.625-0.105-0.897-0.005zM17.533 1.388c-0.473 0.119-0.707 0.301-1.807 1.421-2.268 2.309-2.807 2.876-2.896 3.051-0.128 0.247-0.167 0.7-0.084 0.992 0.084 0.301 0.431 0.704 0.717 0.835 0.247 0.112 0.685 0.129 1.009 0.039 0.181-0.049 0.38-0.223 1.121-0.973 0.495-0.501 0.885-0.864 0.867-0.805s-0.252 0.791-0.519 1.627c-0.424 1.327-0.483 1.555-0.459 1.793 0.077 0.783 0.829 1.36 1.56 1.197 0.339-0.076 0.728-0.324 0.869-0.555 0.057-0.093 0.544-1.537 1.081-3.209 0.951-2.96 0.976-3.052 0.976-3.493 0.001-0.396-0.020-0.497-0.165-0.805-0.316-0.671-0.972-1.117-1.687-1.147-0.212-0.009-0.476 0.005-0.585 0.033zM20.533 12.049c-0.405 0.124-0.789 0.476-0.909 0.837-0.096 0.288-0.088 0.653 0.021 0.941 0.099 0.256 0.459 0.632 0.715 0.747 0.108 0.048 0.963 0.072 3.213 0.092l3.067 0.027-1.168 1.2c-1.272 1.307-1.376 1.456-1.376 1.967 0 0.412 0.133 0.711 0.44 0.987 0.412 0.369 0.965 0.453 1.453 0.221 0.232-0.109 2.663-2.577 2.919-2.961 0.357-0.536 0.515-1.371 0.373-1.979-0.241-1.040-1.103-1.888-2.104-2.071-0.365-0.067-6.428-0.073-6.644-0.008zM15.552 17.479c-0.009 0.009-0.087-0.013-0.171-0.051-0.12-0.053-1.247-0.073-5.088-0.095l-4.933-0.027 4.953-5.099 2.628 2.627c1.445 1.445 2.62 2.635 2.611 2.644zM19.787 21.716c0 0.039-4.232 4.415-4.252 4.396-0.007-0.007 0.387-1.257 0.875-2.781 0.979-3.060 1.025-3.28 0.852-3.941l-0.084-0.317 1.305 1.304c0.717 0.716 1.304 1.32 1.304 1.34z"></path>
|
|
890
|
+
</symbol>
|
|
891
|
+
<symbol id="icon-zap" viewBox="0 0 32 32">
|
|
892
|
+
<path d="M17.533 1.388c-0.467 0.117-0.712 0.307-1.707 1.316-3.275 3.323-12.561 12.94-12.715 13.168-0.1 0.149-0.231 0.399-0.291 0.555-0.14 0.371-0.189 1.068-0.103 1.445 0.24 1.029 1.071 1.86 2.071 2.069 0.195 0.040 1.785 0.059 5.085 0.059 3.939 0 4.799 0.012 4.776 0.069-0.015 0.039-0.611 1.893-1.324 4.12-1.273 3.976-1.297 4.059-1.297 4.504-0.001 0.396 0.020 0.497 0.165 0.805 0.552 1.173 2.089 1.537 3.044 0.723 0.472-0.404 13.463-13.816 13.649-14.093 0.1-0.149 0.231-0.399 0.291-0.555 0.14-0.371 0.189-1.068 0.103-1.445-0.241-1.040-1.103-1.888-2.104-2.071-0.212-0.039-1.901-0.057-5.087-0.057-3.856 0-4.764-0.013-4.743-0.068 0.015-0.037 0.611-1.892 1.324-4.12 1.275-3.977 1.299-4.060 1.299-4.505 0-0.397-0.020-0.497-0.165-0.805-0.316-0.671-0.972-1.117-1.687-1.147-0.212-0.009-0.476 0.005-0.585 0.033zM15.591 8.669c-0.955 2.988-1.008 3.228-0.873 3.877 0.181 0.872 0.861 1.641 1.744 1.976 0.312 0.117 0.317 0.117 5.245 0.144l4.933 0.027-5.547 5.715c-3.051 3.143-5.552 5.709-5.559 5.704-0.007-0.007 0.387-1.257 0.873-2.781 0.737-2.304 0.891-2.84 0.912-3.18 0.076-1.175-0.629-2.233-1.777-2.671l-0.316-0.12-9.867-0.053 5.547-5.715c3.051-3.143 5.552-5.709 5.559-5.704 0.005 0.005-0.388 1.257-0.875 2.781z"></path>
|
|
893
|
+
</symbol>
|
|
888
894
|
</defs>
|
|
889
895
|
</svg>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { CameraError, CameraDevice, CameraIntent, CameraPermission, CameraState, Facing, Resolution, StartOptions, ZoomCapability } from './types';
|
|
2
|
+
export interface CameraSnapshot {
|
|
3
|
+
state: CameraState;
|
|
4
|
+
intent: CameraIntent;
|
|
5
|
+
stream: MediaStream | null;
|
|
6
|
+
devices: CameraDevice[];
|
|
7
|
+
activeDeviceId: string | null;
|
|
8
|
+
activeFacing: Facing | null;
|
|
9
|
+
error: CameraError | null;
|
|
10
|
+
permission: CameraPermission;
|
|
11
|
+
zoom: number;
|
|
12
|
+
zoomCapability: ZoomCapability | null;
|
|
13
|
+
}
|
|
14
|
+
export interface CameraManagerOptions {
|
|
15
|
+
preferredFacing?: Facing;
|
|
16
|
+
resolution?: Resolution;
|
|
17
|
+
/** Non-fatal problems (e.g. first frame never painted) are reported here without changing state. */
|
|
18
|
+
onWarning?: (err: CameraError) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare class CameraManager {
|
|
21
|
+
private readonly listeners;
|
|
22
|
+
private readonly opts;
|
|
23
|
+
private state;
|
|
24
|
+
private intent;
|
|
25
|
+
private stream;
|
|
26
|
+
private devices;
|
|
27
|
+
private activeDeviceId;
|
|
28
|
+
private activeFacing;
|
|
29
|
+
private error;
|
|
30
|
+
private permission;
|
|
31
|
+
private zoom;
|
|
32
|
+
private zoomCapability;
|
|
33
|
+
private desiredZoom;
|
|
34
|
+
private video;
|
|
35
|
+
private seq;
|
|
36
|
+
private tearingDown;
|
|
37
|
+
private lastGood;
|
|
38
|
+
private autoCorrected;
|
|
39
|
+
private disposed;
|
|
40
|
+
/** facing confirmed by a real getUserMedia on that id (Android probe or the active stream). */
|
|
41
|
+
private readonly probeCache;
|
|
42
|
+
private refreshing;
|
|
43
|
+
private recoveryAttempts;
|
|
44
|
+
private recoveryTimer;
|
|
45
|
+
private stableTimer;
|
|
46
|
+
private healthTimer;
|
|
47
|
+
private deviceChangeTimer;
|
|
48
|
+
private watchdogCleanup;
|
|
49
|
+
private permissionStatus;
|
|
50
|
+
constructor(opts?: CameraManagerOptions);
|
|
51
|
+
subscribe(listener: (s: CameraSnapshot) => void): () => void;
|
|
52
|
+
snapshot(): CameraSnapshot;
|
|
53
|
+
static isSupported(): boolean;
|
|
54
|
+
attachVideo(el: HTMLVideoElement | null): void;
|
|
55
|
+
/** Resolves true when a stream is live; errors are surfaced through the snapshot. */
|
|
56
|
+
start(options?: StartOptions & {
|
|
57
|
+
strictDevice?: boolean;
|
|
58
|
+
}): Promise<boolean>;
|
|
59
|
+
stop(): void;
|
|
60
|
+
/** Freeze-frame: keep the camera open, stop rendering. */
|
|
61
|
+
pause(): void;
|
|
62
|
+
resume(): Promise<boolean>;
|
|
63
|
+
toggle(): Promise<boolean>;
|
|
64
|
+
switchCamera(): Promise<boolean>;
|
|
65
|
+
selectDevice(deviceId: string): Promise<boolean>;
|
|
66
|
+
/** Restart at a new resolution, keeping the active device. */
|
|
67
|
+
setResolution(resolution: Resolution): Promise<boolean>;
|
|
68
|
+
setZoom(value: number): Promise<boolean>;
|
|
69
|
+
refreshDevices(): Promise<void>;
|
|
70
|
+
dispose(): void;
|
|
71
|
+
private teardown;
|
|
72
|
+
private fail;
|
|
73
|
+
private setState;
|
|
74
|
+
private emit;
|
|
75
|
+
private bindStream;
|
|
76
|
+
private clearWatchdog;
|
|
77
|
+
private readonly onTrackEnded;
|
|
78
|
+
private readonly onVisibilityChange;
|
|
79
|
+
private readonly onPageShow;
|
|
80
|
+
private scheduleHealthCheck;
|
|
81
|
+
private healthCheck;
|
|
82
|
+
private scheduleRecovery;
|
|
83
|
+
private cancelRecovery;
|
|
84
|
+
/** Only a stream that survived a while proves the recovery loop has converged. */
|
|
85
|
+
private armStableTimer;
|
|
86
|
+
private readonly onDeviceChange;
|
|
87
|
+
private doRefreshDevices;
|
|
88
|
+
private probeDevice;
|
|
89
|
+
private initPermission;
|
|
90
|
+
private readZoomCapability;
|
|
91
|
+
}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { isAndroid as e, isIOS as t, supportsRVFC as n } from "./platform.js";
|
|
2
|
+
import { buildFallbackChain as r, classifyFacingFromLabel as i, dedupeByFacing as a, isFatalGumError as o, isTransientGumError as s, normalizeFacing as c, pickSwitchTarget as l, toErrorCode as u } from "./constraints.js";
|
|
3
|
+
import { CameraError as d } from "./types.js";
|
|
4
|
+
//#region src/utilities/camera/CameraManager.ts
|
|
5
|
+
var f = 1500, p = 2, m = 300, h = [
|
|
6
|
+
300,
|
|
7
|
+
1e3,
|
|
8
|
+
3e3
|
|
9
|
+
], g = 5e3, _ = 800, v = 500, y = {
|
|
10
|
+
width: { ideal: 160 },
|
|
11
|
+
height: { ideal: 120 }
|
|
12
|
+
}, b = () => void 0, x = (e) => new Promise((t) => setTimeout(t, e)), S = class S {
|
|
13
|
+
listeners = /* @__PURE__ */ new Set();
|
|
14
|
+
opts;
|
|
15
|
+
state = "idle";
|
|
16
|
+
intent = "stopped";
|
|
17
|
+
stream = null;
|
|
18
|
+
devices = [];
|
|
19
|
+
activeDeviceId = null;
|
|
20
|
+
activeFacing = null;
|
|
21
|
+
error = null;
|
|
22
|
+
permission = "unknown";
|
|
23
|
+
zoom = 1;
|
|
24
|
+
zoomCapability = null;
|
|
25
|
+
desiredZoom = null;
|
|
26
|
+
video = null;
|
|
27
|
+
seq = 0;
|
|
28
|
+
tearingDown = !1;
|
|
29
|
+
lastGood = null;
|
|
30
|
+
autoCorrected = !1;
|
|
31
|
+
disposed = !1;
|
|
32
|
+
probeCache = /* @__PURE__ */ new Map();
|
|
33
|
+
refreshing = null;
|
|
34
|
+
recoveryAttempts = 0;
|
|
35
|
+
recoveryTimer = null;
|
|
36
|
+
stableTimer = null;
|
|
37
|
+
healthTimer = null;
|
|
38
|
+
deviceChangeTimer = null;
|
|
39
|
+
watchdogCleanup = null;
|
|
40
|
+
permissionStatus = null;
|
|
41
|
+
constructor(e = {}) {
|
|
42
|
+
this.opts = e, typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibilityChange), window.addEventListener("pageshow", this.onPageShow)), typeof navigator < "u" && navigator.mediaDevices && (navigator.mediaDevices.addEventListener?.("devicechange", this.onDeviceChange), this.initPermission());
|
|
43
|
+
}
|
|
44
|
+
subscribe(e) {
|
|
45
|
+
return this.listeners.add(e), e(this.snapshot()), () => this.listeners.delete(e);
|
|
46
|
+
}
|
|
47
|
+
snapshot() {
|
|
48
|
+
return {
|
|
49
|
+
state: this.state,
|
|
50
|
+
intent: this.intent,
|
|
51
|
+
stream: this.stream,
|
|
52
|
+
devices: this.devices,
|
|
53
|
+
activeDeviceId: this.activeDeviceId,
|
|
54
|
+
activeFacing: this.activeFacing,
|
|
55
|
+
error: this.error,
|
|
56
|
+
permission: this.permission,
|
|
57
|
+
zoom: this.zoom,
|
|
58
|
+
zoomCapability: this.zoomCapability
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
static isSupported() {
|
|
62
|
+
return typeof navigator < "u" && !!navigator.mediaDevices?.getUserMedia;
|
|
63
|
+
}
|
|
64
|
+
attachVideo(e) {
|
|
65
|
+
this.video !== e && (this.clearWatchdog(), this.video && (this.video.srcObject = null), this.video = e, e && this.stream && this.state !== "paused" && this.bindStream());
|
|
66
|
+
}
|
|
67
|
+
async start(e = {}) {
|
|
68
|
+
if (this.disposed) return !1;
|
|
69
|
+
if (!S.isSupported()) return this.fail(new d("unsupported", "getUserMedia is not available in this browser")), !1;
|
|
70
|
+
let t = ++this.seq;
|
|
71
|
+
this.cancelRecovery(), this.intent = "live", this.teardown(), this.error = null, this.setState("starting");
|
|
72
|
+
let n = e.resolution ?? this.lastGood?.resolution ?? this.opts.resolution, a = !!(e.strictDevice && e.deviceId), l = a ? void 0 : e.facing ?? (e.deviceId ? void 0 : this.opts.preferredFacing), f = r({
|
|
73
|
+
deviceId: e.deviceId,
|
|
74
|
+
facing: l,
|
|
75
|
+
resolution: n,
|
|
76
|
+
strictDevice: a
|
|
77
|
+
}), p = null, h = null;
|
|
78
|
+
for (let e of f) {
|
|
79
|
+
if (t !== this.seq) return !1;
|
|
80
|
+
try {
|
|
81
|
+
p = await navigator.mediaDevices.getUserMedia(e.constraints);
|
|
82
|
+
break;
|
|
83
|
+
} catch (n) {
|
|
84
|
+
if (h = n, o(n)) break;
|
|
85
|
+
if (s(n)) {
|
|
86
|
+
if (await x(m), t !== this.seq) return !1;
|
|
87
|
+
try {
|
|
88
|
+
p = await navigator.mediaDevices.getUserMedia(e.constraints);
|
|
89
|
+
break;
|
|
90
|
+
} catch (e) {
|
|
91
|
+
if (h = e, o(e)) break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (t !== this.seq) return p?.getTracks().forEach((e) => e.stop()), !1;
|
|
97
|
+
if (!p) {
|
|
98
|
+
let e = u(h);
|
|
99
|
+
return e === "not-allowed" && (this.permission = "denied"), this.fail(new d(e, C(h), h)), !1;
|
|
100
|
+
}
|
|
101
|
+
let g = p.getVideoTracks()[0];
|
|
102
|
+
if (!g) return p.getTracks().forEach((e) => e.stop()), this.fail(new d("not-found", "Stream has no video track")), !1;
|
|
103
|
+
let _ = g.getSettings(), v = _.deviceId ?? e.deviceId ?? null, y = v ? this.probeCache.get(v) : void 0, b = c(_.facingMode) ?? y ?? i(g.label);
|
|
104
|
+
if (v && this.probeCache.set(v, b), this.stream = p, this.activeDeviceId = v, this.activeFacing = b, this.lastGood = {
|
|
105
|
+
deviceId: v,
|
|
106
|
+
resolution: n
|
|
107
|
+
}, this.permission !== "granted" && (this.permission = "granted"), g.onended = this.onTrackEnded, this.readZoomCapability(g), this.setState("live"), this.armStableTimer(), this.bindStream(), this.desiredZoom !== null && this.setZoom(this.desiredZoom), await this.refreshDevices(), t !== this.seq) return !1;
|
|
108
|
+
if (!e.deviceId && !this.autoCorrected && this.opts.preferredFacing && b && (this.autoCorrected = !0, b !== this.opts.preferredFacing)) {
|
|
109
|
+
let e = this.devices.find((e) => e.facing === this.opts.preferredFacing && e.deviceId !== v);
|
|
110
|
+
if (e) return this.start({
|
|
111
|
+
deviceId: e.deviceId,
|
|
112
|
+
resolution: n,
|
|
113
|
+
strictDevice: !0
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return !0;
|
|
117
|
+
}
|
|
118
|
+
stop() {
|
|
119
|
+
this.seq++, this.intent = "stopped", this.cancelRecovery(), this.teardown(), this.error = null, this.setState("idle");
|
|
120
|
+
}
|
|
121
|
+
pause() {
|
|
122
|
+
if (!(this.state !== "live" || !this.stream)) {
|
|
123
|
+
this.intent = "paused", this.clearWatchdog(), this.video?.pause();
|
|
124
|
+
for (let e of this.stream.getVideoTracks()) e.enabled = !1;
|
|
125
|
+
this.setState("paused");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async resume() {
|
|
129
|
+
if (this.state !== "paused") return this.state === "live";
|
|
130
|
+
this.intent = "live";
|
|
131
|
+
let e = this.stream?.getVideoTracks()[0];
|
|
132
|
+
return !e || e.readyState === "ended" ? this.start({ deviceId: this.lastGood?.deviceId ?? void 0 }) : (e.enabled = !0, this.setState("live"), this.bindStream(), !0);
|
|
133
|
+
}
|
|
134
|
+
async toggle() {
|
|
135
|
+
return this.state === "live" ? (this.pause(), !0) : this.state === "paused" ? this.resume() : this.start();
|
|
136
|
+
}
|
|
137
|
+
async switchCamera() {
|
|
138
|
+
if (this.state === "starting") return !1;
|
|
139
|
+
this.devices.length === 0 && await this.refreshDevices();
|
|
140
|
+
let e = l(this.devices, this.activeDeviceId, this.activeFacing);
|
|
141
|
+
return e ? this.selectDevice(e.deviceId) : !1;
|
|
142
|
+
}
|
|
143
|
+
async selectDevice(e) {
|
|
144
|
+
if (e === this.activeDeviceId && this.state === "live") return !0;
|
|
145
|
+
let t = this.lastGood, n = await this.start({
|
|
146
|
+
deviceId: e,
|
|
147
|
+
strictDevice: !0
|
|
148
|
+
});
|
|
149
|
+
if (n || !t?.deviceId || this.error?.code === "not-allowed") return n;
|
|
150
|
+
let r = this.error;
|
|
151
|
+
return await this.start({
|
|
152
|
+
deviceId: t.deviceId,
|
|
153
|
+
resolution: t.resolution,
|
|
154
|
+
strictDevice: !0
|
|
155
|
+
}) && r && this.opts.onWarning?.(r), !1;
|
|
156
|
+
}
|
|
157
|
+
async setResolution(e) {
|
|
158
|
+
let t = this.lastGood?.resolution?.width === e.width && this.lastGood?.resolution?.height === e.height;
|
|
159
|
+
return this.lastGood && (this.lastGood.resolution = e), t || this.state !== "live" && this.state !== "paused" ? this.state === "live" : this.start({
|
|
160
|
+
deviceId: this.activeDeviceId ?? void 0,
|
|
161
|
+
resolution: e
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
async setZoom(e) {
|
|
165
|
+
this.desiredZoom = e;
|
|
166
|
+
let t = this.stream?.getVideoTracks()[0], n = this.zoomCapability;
|
|
167
|
+
if (!t || !n) return !1;
|
|
168
|
+
let r = Math.min(n.max, Math.max(n.min, e));
|
|
169
|
+
try {
|
|
170
|
+
await t.applyConstraints({ advanced: [{ zoom: r }] });
|
|
171
|
+
} catch {
|
|
172
|
+
try {
|
|
173
|
+
await t.applyConstraints({ zoom: r });
|
|
174
|
+
} catch {
|
|
175
|
+
return !1;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return this.zoom = t.getSettings().zoom ?? r, this.emit(), !0;
|
|
179
|
+
}
|
|
180
|
+
async refreshDevices() {
|
|
181
|
+
return this.refreshing ||= this.doRefreshDevices().finally(() => {
|
|
182
|
+
this.refreshing = null;
|
|
183
|
+
}), this.refreshing;
|
|
184
|
+
}
|
|
185
|
+
dispose() {
|
|
186
|
+
this.disposed || (this.disposed = !0, this.stop(), this.listeners.clear(), typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibilityChange), window.removeEventListener("pageshow", this.onPageShow)), navigator.mediaDevices?.removeEventListener?.("devicechange", this.onDeviceChange), this.permissionStatus && (this.permissionStatus.onchange = null), this.deviceChangeTimer && clearTimeout(this.deviceChangeTimer), this.healthTimer && clearTimeout(this.healthTimer), this.video = null);
|
|
187
|
+
}
|
|
188
|
+
teardown() {
|
|
189
|
+
this.tearingDown = !0, this.clearWatchdog(), this.stableTimer && clearTimeout(this.stableTimer), this.stableTimer = null;
|
|
190
|
+
let e = this.stream;
|
|
191
|
+
if (this.stream = null, e) for (let t of e.getTracks()) t.onended = null, t.onmute = null, t.onunmute = null, t.stop();
|
|
192
|
+
this.video && (this.video.pause(), this.video.srcObject = null), this.zoomCapability = null, this.tearingDown = !1;
|
|
193
|
+
}
|
|
194
|
+
fail(e) {
|
|
195
|
+
this.teardown(), this.error = e, this.setState("error");
|
|
196
|
+
}
|
|
197
|
+
setState(e) {
|
|
198
|
+
this.state = e, this.emit();
|
|
199
|
+
}
|
|
200
|
+
emit() {
|
|
201
|
+
let e = this.snapshot();
|
|
202
|
+
for (let t of this.listeners) t(e);
|
|
203
|
+
}
|
|
204
|
+
bindStream(e = 0) {
|
|
205
|
+
let t = this.video, r = this.stream;
|
|
206
|
+
if (!t || !r) return;
|
|
207
|
+
this.clearWatchdog(), t.muted = !0, t.playsInline = !0, t.setAttribute("playsinline", ""), t.autoplay = !0, t.srcObject = r, t.load(), t.play().catch(b);
|
|
208
|
+
let i = !1, a = setTimeout(() => {
|
|
209
|
+
if (!i && (s(), this.stream === r && this.state === "live")) {
|
|
210
|
+
if (e < p) {
|
|
211
|
+
t.srcObject = null, t.offsetHeight, this.bindStream(e + 1);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
t.readyState >= 2 && t.videoWidth > 0 || this.opts.onWarning?.(new d("first-frame", "Video did not render its first frame"));
|
|
215
|
+
}
|
|
216
|
+
}, f), o = () => {
|
|
217
|
+
i || (i = !0, s());
|
|
218
|
+
}, s = () => {
|
|
219
|
+
clearTimeout(a), t.removeEventListener("loadeddata", o), t.removeEventListener("playing", o), this.watchdogCleanup = null;
|
|
220
|
+
};
|
|
221
|
+
this.watchdogCleanup = s, n(t) ? t.requestVideoFrameCallback(() => o()) : (t.addEventListener("loadeddata", o), t.addEventListener("playing", o));
|
|
222
|
+
}
|
|
223
|
+
clearWatchdog() {
|
|
224
|
+
this.watchdogCleanup?.(), this.watchdogCleanup = null;
|
|
225
|
+
}
|
|
226
|
+
onTrackEnded = () => {
|
|
227
|
+
this.tearingDown || this.intent !== "live" || this.scheduleRecovery();
|
|
228
|
+
};
|
|
229
|
+
onVisibilityChange = () => {
|
|
230
|
+
document.visibilityState === "visible" && this.scheduleHealthCheck(_);
|
|
231
|
+
};
|
|
232
|
+
onPageShow = (e) => {
|
|
233
|
+
e.persisted && this.scheduleHealthCheck(0);
|
|
234
|
+
};
|
|
235
|
+
scheduleHealthCheck(e) {
|
|
236
|
+
this.healthTimer && clearTimeout(this.healthTimer), this.healthTimer = setTimeout(() => {
|
|
237
|
+
this.healthTimer = null, this.healthCheck();
|
|
238
|
+
}, e);
|
|
239
|
+
}
|
|
240
|
+
healthCheck() {
|
|
241
|
+
if (this.disposed || this.intent !== "live" || this.state === "starting") return;
|
|
242
|
+
let e = this.stream?.getVideoTracks()[0];
|
|
243
|
+
if (!e || e.readyState === "ended" || e.muted) {
|
|
244
|
+
this.scheduleRecovery();
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
this.video && this.video.paused && this.video.play().catch(b);
|
|
248
|
+
}
|
|
249
|
+
scheduleRecovery() {
|
|
250
|
+
if (this.disposed || this.intent !== "live" || this.recoveryTimer) return;
|
|
251
|
+
if (this.recoveryAttempts >= h.length) {
|
|
252
|
+
this.fail(new d("not-readable", "Camera stopped and could not be re-acquired"));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
let e = h[this.recoveryAttempts] ?? 3e3;
|
|
256
|
+
this.recoveryAttempts++, this.recoveryTimer = setTimeout(() => {
|
|
257
|
+
this.recoveryTimer = null, this.intent === "live" && this.start({
|
|
258
|
+
deviceId: this.lastGood?.deviceId ?? void 0,
|
|
259
|
+
facing: this.activeFacing ?? this.opts.preferredFacing,
|
|
260
|
+
resolution: this.lastGood?.resolution
|
|
261
|
+
});
|
|
262
|
+
}, e);
|
|
263
|
+
}
|
|
264
|
+
cancelRecovery() {
|
|
265
|
+
this.recoveryTimer && clearTimeout(this.recoveryTimer), this.recoveryTimer = null;
|
|
266
|
+
}
|
|
267
|
+
armStableTimer() {
|
|
268
|
+
this.stableTimer && clearTimeout(this.stableTimer), this.stableTimer = setTimeout(() => {
|
|
269
|
+
this.stableTimer = null, this.recoveryAttempts = 0;
|
|
270
|
+
}, g);
|
|
271
|
+
}
|
|
272
|
+
onDeviceChange = () => {
|
|
273
|
+
this.deviceChangeTimer && clearTimeout(this.deviceChangeTimer), this.deviceChangeTimer = setTimeout(() => {
|
|
274
|
+
this.deviceChangeTimer = null, this.refreshDevices();
|
|
275
|
+
}, v);
|
|
276
|
+
};
|
|
277
|
+
async doRefreshDevices() {
|
|
278
|
+
if (this.disposed || !navigator.mediaDevices?.enumerateDevices || this.state === "starting") return;
|
|
279
|
+
let n;
|
|
280
|
+
try {
|
|
281
|
+
n = await navigator.mediaDevices.enumerateDevices();
|
|
282
|
+
} catch {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
let r = n.filter((e) => e.kind === "videoinput" && e.deviceId), o = new Set(r.map((e) => e.deviceId));
|
|
286
|
+
for (let e of [...this.probeCache.keys()]) o.has(e) || this.probeCache.delete(e);
|
|
287
|
+
let s = e() && !t() && this.permission !== "denied", c = [];
|
|
288
|
+
for (let e of r) {
|
|
289
|
+
if (this.disposed) return;
|
|
290
|
+
let t = this.probeCache.get(e.deviceId), n = t !== void 0;
|
|
291
|
+
if (!n && s) {
|
|
292
|
+
let r = await this.probeDevice(e.deviceId);
|
|
293
|
+
if (r === void 0) continue;
|
|
294
|
+
t = r, n = !0, this.probeCache.set(e.deviceId, r);
|
|
295
|
+
}
|
|
296
|
+
c.push({
|
|
297
|
+
deviceId: e.deviceId,
|
|
298
|
+
label: e.label,
|
|
299
|
+
facing: t ?? i(e.label),
|
|
300
|
+
probed: n
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
let l = s ? a(c, this.activeDeviceId) : c;
|
|
304
|
+
this.devices = l, this.emit();
|
|
305
|
+
}
|
|
306
|
+
async probeDevice(e) {
|
|
307
|
+
if (e === this.activeDeviceId && this.stream) return this.probeCache.get(e) ?? this.activeFacing;
|
|
308
|
+
let t = null;
|
|
309
|
+
try {
|
|
310
|
+
t = await navigator.mediaDevices.getUserMedia({ video: {
|
|
311
|
+
deviceId: { exact: e },
|
|
312
|
+
...y
|
|
313
|
+
} });
|
|
314
|
+
let n = t.getVideoTracks()[0];
|
|
315
|
+
return c(n?.getSettings().facingMode) ?? null;
|
|
316
|
+
} catch {
|
|
317
|
+
return;
|
|
318
|
+
} finally {
|
|
319
|
+
if (t) for (let e of t.getTracks()) e.onended = null, e.stop();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
async initPermission() {
|
|
323
|
+
try {
|
|
324
|
+
let e = await navigator.permissions.query({ name: "camera" });
|
|
325
|
+
this.permissionStatus = e, this.permission = e.state, e.onchange = () => {
|
|
326
|
+
this.permission = e.state, e.state === "denied" ? this.fail(new d("not-allowed", "Camera permission was revoked")) : (this.emit(), e.state === "granted" && this.refreshDevices());
|
|
327
|
+
}, this.emit();
|
|
328
|
+
} catch {
|
|
329
|
+
this.permission = "unknown";
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
readZoomCapability(e) {
|
|
333
|
+
let t = e.getCapabilities?.()?.zoom;
|
|
334
|
+
t && typeof t.min == "number" && typeof t.max == "number" && t.max > t.min ? (this.zoomCapability = {
|
|
335
|
+
min: t.min,
|
|
336
|
+
max: t.max,
|
|
337
|
+
step: t.step && t.step > 0 ? t.step : .1
|
|
338
|
+
}, this.zoom = e.getSettings().zoom ?? t.min) : (this.zoomCapability = null, this.zoom = 1);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
function C(e) {
|
|
342
|
+
return e instanceof Error ? e.message || e.name : "Camera could not be started";
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
345
|
+
export { S as CameraManager };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Filter } from './types';
|
|
2
|
+
export interface CropRect {
|
|
3
|
+
sx: number;
|
|
4
|
+
sy: number;
|
|
5
|
+
sw: number;
|
|
6
|
+
sh: number;
|
|
7
|
+
}
|
|
8
|
+
/** Source rect that fills dst (object-fit: cover), centered. */
|
|
9
|
+
export declare function coverCrop(srcW: number, srcH: number, dstW: number, dstH: number): CropRect;
|
|
10
|
+
export interface CaptureOptions {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
mirror?: boolean;
|
|
14
|
+
filter?: Filter;
|
|
15
|
+
tintColor?: string;
|
|
16
|
+
tintIntensity?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface TintPaint {
|
|
19
|
+
color: string;
|
|
20
|
+
opacity: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function resolveTintPaint(color: string, intensity: number): TintPaint;
|
|
23
|
+
/** Rotation the frame needs so that "up" in the image matches "up" on screen. */
|
|
24
|
+
export declare function orientationAngle(): number;
|
|
25
|
+
export declare function captureFrame(video: HTMLVideoElement, opts: CaptureOptions): HTMLCanvasElement;
|
|
26
|
+
export declare function cssFilter(filter: Filter): string;
|
|
27
|
+
/** Fallback for engines without ctx.filter (older Safari); matches CSS filter matrices. */
|
|
28
|
+
export declare function applyPixelFilter(ctx: CanvasRenderingContext2D, filter: Filter): void;
|
|
29
|
+
export declare function filterPixels(data: Uint8ClampedArray, filter: Filter): void;
|
|
30
|
+
export interface ExportOptions {
|
|
31
|
+
asBlob?: boolean;
|
|
32
|
+
type?: string;
|
|
33
|
+
quality?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare function exportCanvas(canvas: HTMLCanvasElement, opts?: ExportOptions): Promise<Blob | string>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { isIOS as e } from "./platform.js";
|
|
2
|
+
//#region src/utilities/camera/capture.ts
|
|
3
|
+
function t(e, t, n, r) {
|
|
4
|
+
let i = Math.max(n / e, r / t), a = n / i, o = r / i;
|
|
5
|
+
return {
|
|
6
|
+
sx: (e - a) / 2,
|
|
7
|
+
sy: (t - o) / 2,
|
|
8
|
+
sw: a,
|
|
9
|
+
sh: o
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function n(e, t) {
|
|
13
|
+
let n = Math.min(1, Math.max(0, t)), r = e.match(/^#([\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i)?.[1];
|
|
14
|
+
if (!r) return {
|
|
15
|
+
color: e,
|
|
16
|
+
opacity: n
|
|
17
|
+
};
|
|
18
|
+
let i = r.length <= 4 ? [...r].map((e) => e + e).join("") : r;
|
|
19
|
+
return {
|
|
20
|
+
color: `rgba(${Number.parseInt(i.slice(0, 2), 16)}, ${Number.parseInt(i.slice(2, 4), 16)}, ${Number.parseInt(i.slice(4, 6), 16)}, ${(i.length === 8 ? Number.parseInt(i.slice(6, 8), 16) / 255 : 1) * n})`,
|
|
21
|
+
opacity: 1
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function r() {
|
|
25
|
+
if (typeof window > "u") return 0;
|
|
26
|
+
let e = window.screen?.orientation?.angle;
|
|
27
|
+
if (typeof e == "number") return i(e);
|
|
28
|
+
let t = window.orientation;
|
|
29
|
+
return typeof t == "number" ? i(t) : 0;
|
|
30
|
+
}
|
|
31
|
+
function i(e) {
|
|
32
|
+
return (Math.round(e / 90) * 90 % 360 + 360) % 360;
|
|
33
|
+
}
|
|
34
|
+
function a(i, a) {
|
|
35
|
+
let c = i.videoWidth, l = i.videoHeight;
|
|
36
|
+
if (!c || !l) throw Error("Video has no frame to capture yet");
|
|
37
|
+
let u = document.createElement("canvas");
|
|
38
|
+
u.width = a.width, u.height = a.height;
|
|
39
|
+
let d = u.getContext("2d");
|
|
40
|
+
if (!d) throw Error("2D canvas context unavailable");
|
|
41
|
+
let f = e() ? r() : 0, p = f === 90 || f === 270, m = "filter" in d;
|
|
42
|
+
if (d.save(), a.mirror && (d.translate(a.width, 0), d.scale(-1, 1)), m && a.filter && a.filter !== "none" && (d.filter = o(a.filter)), p) {
|
|
43
|
+
d.translate(a.width / 2, a.height / 2), d.rotate(-f * Math.PI / 180);
|
|
44
|
+
let e = a.height, n = a.width, r = t(c, l, e, n);
|
|
45
|
+
d.drawImage(i, r.sx, r.sy, r.sw, r.sh, -e / 2, -n / 2, e, n);
|
|
46
|
+
} else {
|
|
47
|
+
let e = t(c, l, a.width, a.height);
|
|
48
|
+
d.drawImage(i, e.sx, e.sy, e.sw, e.sh, 0, 0, a.width, a.height);
|
|
49
|
+
}
|
|
50
|
+
d.restore(), !m && a.filter && a.filter !== "none" && s(d, a.filter);
|
|
51
|
+
let h = a.tintColor ? n(a.tintColor, a.tintIntensity ?? 0) : null;
|
|
52
|
+
return h && h.opacity > 0 && (d.save(), d.globalAlpha = h.opacity, d.fillStyle = h.color, d.fillRect(0, 0, a.width, a.height), d.restore()), u;
|
|
53
|
+
}
|
|
54
|
+
function o(e) {
|
|
55
|
+
switch (e) {
|
|
56
|
+
case "grayscale": return "grayscale(1)";
|
|
57
|
+
case "sepia": return "sepia(1)";
|
|
58
|
+
default: return "none";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function s(e, t) {
|
|
62
|
+
if (t === "none") return;
|
|
63
|
+
let { width: n, height: r } = e.canvas, i = e.getImageData(0, 0, n, r);
|
|
64
|
+
c(i.data, t), e.putImageData(i, 0, 0);
|
|
65
|
+
}
|
|
66
|
+
function c(e, t) {
|
|
67
|
+
for (let n = 0; n < e.length; n += 4) {
|
|
68
|
+
let r = e[n] ?? 0, i = e[n + 1] ?? 0, a = e[n + 2] ?? 0;
|
|
69
|
+
if (t === "grayscale") {
|
|
70
|
+
let t = .2126 * r + .7152 * i + .0722 * a;
|
|
71
|
+
e[n] = e[n + 1] = e[n + 2] = t;
|
|
72
|
+
} else t === "sepia" && (e[n] = Math.min(255, .393 * r + .769 * i + .189 * a), e[n + 1] = Math.min(255, .349 * r + .686 * i + .168 * a), e[n + 2] = Math.min(255, .272 * r + .534 * i + .131 * a));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function l(e, t = {}) {
|
|
76
|
+
let n = t.type ?? "image/jpeg", r = t.quality ?? .92;
|
|
77
|
+
return t.asBlob ? new Promise((t, i) => {
|
|
78
|
+
e.toBlob((e) => e ? t(e) : i(/* @__PURE__ */ Error("canvas.toBlob returned null")), n, r);
|
|
79
|
+
}) : Promise.resolve(e.toDataURL(n, r));
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { s as applyPixelFilter, a as captureFrame, t as coverCrop, o as cssFilter, l as exportCanvas, c as filterPixels, r as orientationAngle, n as resolveTintPaint };
|