@bensitu/image-editor 1.5.2 → 2.1.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/README.md +460 -509
- package/dist/cjs/index.cjs +6892 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/esm/animation/animation-queue.js +74 -0
- package/dist/esm/animation/animation-queue.js.map +1 -0
- package/dist/esm/core/callback-reporter.js +23 -0
- package/dist/esm/core/callback-reporter.js.map +1 -0
- package/dist/esm/core/default-options.js +529 -0
- package/dist/esm/core/default-options.js.map +1 -0
- package/dist/esm/core/errors.js +156 -0
- package/dist/esm/core/errors.js.map +1 -0
- package/dist/esm/core/operation-guard.js +157 -0
- package/dist/esm/core/operation-guard.js.map +1 -0
- package/dist/esm/core/public-types.js +4 -0
- package/dist/esm/core/public-types.js.map +1 -0
- package/dist/esm/core/state-serializer.js +252 -0
- package/dist/esm/core/state-serializer.js.map +1 -0
- package/dist/esm/crop/crop-controller.js +405 -0
- package/dist/esm/crop/crop-controller.js.map +1 -0
- package/dist/esm/export/export-format.js +53 -0
- package/dist/esm/export/export-format.js.map +1 -0
- package/dist/esm/export/export-service.js +607 -0
- package/dist/esm/export/export-service.js.map +1 -0
- package/dist/esm/fabric/fabric-adapter.js +37 -0
- package/dist/esm/fabric/fabric-adapter.js.map +1 -0
- package/dist/esm/fabric/fabric-animation.js +89 -0
- package/dist/esm/fabric/fabric-animation.js.map +1 -0
- package/dist/esm/history/command.js +2 -0
- package/dist/esm/history/command.js.map +1 -0
- package/dist/esm/history/history-manager.js +103 -0
- package/dist/esm/history/history-manager.js.map +1 -0
- package/dist/esm/image/image-loader.js +238 -0
- package/dist/esm/image/image-loader.js.map +1 -0
- package/dist/esm/image/image-resampler.js +60 -0
- package/dist/esm/image/image-resampler.js.map +1 -0
- package/dist/esm/image/layout-manager.js +206 -0
- package/dist/esm/image/layout-manager.js.map +1 -0
- package/dist/esm/image/transform-controller.js +132 -0
- package/dist/esm/image/transform-controller.js.map +1 -0
- package/dist/esm/image-editor.js +2076 -0
- package/dist/esm/image-editor.js.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/mask/mask-factory.js +356 -0
- package/dist/esm/mask/mask-factory.js.map +1 -0
- package/dist/esm/mask/mask-label-manager.js +120 -0
- package/dist/esm/mask/mask-label-manager.js.map +1 -0
- package/dist/esm/mask/mask-list.js +53 -0
- package/dist/esm/mask/mask-list.js.map +1 -0
- package/dist/esm/mask/mask-style.js +182 -0
- package/dist/esm/mask/mask-style.js.map +1 -0
- package/dist/esm/mosaic/mosaic-controller.js +670 -0
- package/dist/esm/mosaic/mosaic-controller.js.map +1 -0
- package/dist/esm/mosaic/mosaic-geometry.js +81 -0
- package/dist/esm/mosaic/mosaic-geometry.js.map +1 -0
- package/dist/esm/mosaic/mosaic-pixelate.js +71 -0
- package/dist/esm/mosaic/mosaic-pixelate.js.map +1 -0
- package/dist/esm/ui/dom-bindings.js +67 -0
- package/dist/esm/ui/dom-bindings.js.map +1 -0
- package/dist/esm/ui/ui-state.js +25 -0
- package/dist/esm/ui/ui-state.js.map +1 -0
- package/dist/esm/ui/visibility-state.js +11 -0
- package/dist/esm/ui/visibility-state.js.map +1 -0
- package/dist/esm/utils/canvas-region.js +100 -0
- package/dist/esm/utils/canvas-region.js.map +1 -0
- package/dist/esm/utils/dom.js +6 -0
- package/dist/esm/utils/dom.js.map +1 -0
- package/dist/esm/utils/file.js +53 -0
- package/dist/esm/utils/file.js.map +1 -0
- package/dist/esm/utils/number.js +24 -0
- package/dist/esm/utils/number.js.map +1 -0
- package/dist/esm/utils/timeout.js +17 -0
- package/dist/esm/utils/timeout.js.map +1 -0
- package/dist/types/animation/animation-queue.d.ts +111 -0
- package/dist/types/animation/animation-queue.d.ts.map +1 -0
- package/dist/types/core/callback-reporter.d.ts +125 -0
- package/dist/types/core/callback-reporter.d.ts.map +1 -0
- package/dist/types/core/default-options.d.ts +84 -0
- package/dist/types/core/default-options.d.ts.map +1 -0
- package/dist/types/core/errors.d.ts +142 -0
- package/dist/types/core/errors.d.ts.map +1 -0
- package/dist/types/core/operation-guard.d.ts +194 -0
- package/dist/types/core/operation-guard.d.ts.map +1 -0
- package/dist/types/core/public-types.d.ts +788 -0
- package/dist/types/core/public-types.d.ts.map +1 -0
- package/dist/types/core/state-serializer.d.ts +303 -0
- package/dist/types/core/state-serializer.d.ts.map +1 -0
- package/dist/types/crop/crop-controller.d.ts +407 -0
- package/dist/types/crop/crop-controller.d.ts.map +1 -0
- package/dist/types/export/export-format.d.ts +136 -0
- package/dist/types/export/export-format.d.ts.map +1 -0
- package/dist/types/export/export-service.d.ts +333 -0
- package/dist/types/export/export-service.d.ts.map +1 -0
- package/dist/types/fabric/fabric-adapter.d.ts +74 -0
- package/dist/types/fabric/fabric-adapter.d.ts.map +1 -0
- package/dist/types/fabric/fabric-animation.d.ts +141 -0
- package/dist/types/fabric/fabric-animation.d.ts.map +1 -0
- package/dist/types/history/command.d.ts +16 -0
- package/dist/types/history/command.d.ts.map +1 -0
- package/dist/types/history/history-manager.d.ts +129 -0
- package/dist/types/history/history-manager.d.ts.map +1 -0
- package/dist/types/image/image-loader.d.ts +263 -0
- package/dist/types/image/image-loader.d.ts.map +1 -0
- package/dist/types/image/image-resampler.d.ts +139 -0
- package/dist/types/image/image-resampler.d.ts.map +1 -0
- package/dist/types/image/layout-manager.d.ts +211 -0
- package/dist/types/image/layout-manager.d.ts.map +1 -0
- package/dist/types/image/transform-controller.d.ts +286 -0
- package/dist/types/image/transform-controller.d.ts.map +1 -0
- package/dist/types/image-editor.d.ts +661 -0
- package/dist/types/image-editor.d.ts.map +1 -0
- package/dist/types/index.d.cts +31 -0
- package/dist/types/index.d.cts.map +1 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/mask/mask-factory.d.ts +212 -0
- package/dist/types/mask/mask-factory.d.ts.map +1 -0
- package/dist/types/mask/mask-label-manager.d.ts +171 -0
- package/dist/types/mask/mask-label-manager.d.ts.map +1 -0
- package/dist/types/mask/mask-list.d.ts +144 -0
- package/dist/types/mask/mask-list.d.ts.map +1 -0
- package/dist/types/mask/mask-style.d.ts +338 -0
- package/dist/types/mask/mask-style.d.ts.map +1 -0
- package/dist/types/mosaic/mosaic-controller.d.ts +82 -0
- package/dist/types/mosaic/mosaic-controller.d.ts.map +1 -0
- package/dist/types/mosaic/mosaic-geometry.d.ts +29 -0
- package/dist/types/mosaic/mosaic-geometry.d.ts.map +1 -0
- package/dist/types/mosaic/mosaic-pixelate.d.ts +23 -0
- package/dist/types/mosaic/mosaic-pixelate.d.ts.map +1 -0
- package/dist/types/ui/dom-bindings.d.ts +105 -0
- package/dist/types/ui/dom-bindings.d.ts.map +1 -0
- package/dist/types/ui/ui-state.d.ts +112 -0
- package/dist/types/ui/ui-state.d.ts.map +1 -0
- package/dist/types/ui/visibility-state.d.ts +77 -0
- package/dist/types/ui/visibility-state.d.ts.map +1 -0
- package/dist/types/utils/canvas-region.d.ts +177 -0
- package/dist/types/utils/canvas-region.d.ts.map +1 -0
- package/dist/types/utils/dom.d.ts +26 -0
- package/dist/types/utils/dom.d.ts.map +1 -0
- package/dist/types/utils/file.d.ts +80 -0
- package/dist/types/utils/file.d.ts.map +1 -0
- package/dist/types/utils/number.d.ts +131 -0
- package/dist/types/utils/number.d.ts.map +1 -0
- package/dist/types/utils/timeout.d.ts +84 -0
- package/dist/types/utils/timeout.d.ts.map +1 -0
- package/dist/umd/image-editor.umd.js +2 -0
- package/dist/umd/image-editor.umd.js.map +1 -0
- package/package.json +72 -66
- package/dist/image-editor.cjs +0 -4407
- package/dist/image-editor.cjs.map +0 -7
- package/dist/image-editor.esm.js +0 -4376
- package/dist/image-editor.esm.js.map +0 -7
- package/dist/image-editor.esm.min.js +0 -9
- package/dist/image-editor.esm.min.js.map +0 -7
- package/dist/image-editor.esm.min.mjs +0 -9
- package/dist/image-editor.esm.min.mjs.map +0 -7
- package/dist/image-editor.esm.mjs +0 -4376
- package/dist/image-editor.esm.mjs.map +0 -7
- package/dist/image-editor.js +0 -4373
- package/dist/image-editor.js.map +0 -7
- package/dist/image-editor.min.js +0 -9
- package/dist/image-editor.min.js.map +0 -7
- package/image-editor.d.ts +0 -271
- package/src/browser.js +0 -11
- package/src/esm.js +0 -9
- package/src/image-editor.js +0 -5013
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disabled-state, aria-state, and toolbar-state helpers used by
|
|
3
|
+
* {@link ImageEditor}'s `init` and operation handlers. These
|
|
4
|
+
* helpers share the same `idMap`-driven element-resolution
|
|
5
|
+
* vocabulary as `dom-bindings.ts` so the orchestrator can speak
|
|
6
|
+
* one language when wiring or refreshing UI state.
|
|
7
|
+
*
|
|
8
|
+
* ## Owned contracts
|
|
9
|
+
*
|
|
10
|
+
* - Bound DOM controls live in the orchestrator's
|
|
11
|
+
* bindings registry and are addressed by logical {@link ElementKey}.
|
|
12
|
+
* These helpers consume the same key vocabulary so toolbar-state updates
|
|
13
|
+
* stay aligned with what `dom-bindings.ts` originally bound.
|
|
14
|
+
* - Toolbar-state mutation must remain a no-op when
|
|
15
|
+
* the editor is disposed or when a logical key is unmapped. Each helper
|
|
16
|
+
* short-circuits on a missing element ID or missing DOM node so
|
|
17
|
+
* post-`dispose` `updateUi`-style calls cannot throw or surprise the
|
|
18
|
+
* host page.
|
|
19
|
+
*
|
|
20
|
+
* ## Why this lives in its own module
|
|
21
|
+
*
|
|
22
|
+
* Splitting low-level DOM state out keeps `image-editor.ts` focused on
|
|
23
|
+
* toolbar policy while helpers here own native DOM writes such as setting
|
|
24
|
+
* `disabled` by logical key.
|
|
25
|
+
*
|
|
26
|
+
* Like `dom-bindings.ts` and `visibility-state.ts`, this module is imported
|
|
27
|
+
* by `image-editor.ts` only and is intentionally NOT re-exported from
|
|
28
|
+
* `src/index.ts`.
|
|
29
|
+
*
|
|
30
|
+
* @module
|
|
31
|
+
*/
|
|
32
|
+
import type { ElementIdMap } from '../core/public-types.js';
|
|
33
|
+
/**
|
|
34
|
+
* Logical element-name keys understood by the editor's `idMap`. Matches the
|
|
35
|
+
* `ElementKey` alias exported from `dom-bindings.ts` so the orchestrator's
|
|
36
|
+
* registry and the toolbar-state helpers can be driven from the same
|
|
37
|
+
* lookup function without crossing the public-types boundary.
|
|
38
|
+
*/
|
|
39
|
+
export type ElementKey = keyof Required<ElementIdMap>;
|
|
40
|
+
/**
|
|
41
|
+
* Callback used by every helper in this module to translate a logical
|
|
42
|
+
* {@link ElementKey} to the resolved DOM element ID supplied by the host
|
|
43
|
+
* page through `idMap`. Returning a falsy value (`null`, `undefined`, or
|
|
44
|
+
* empty string) means the host omitted that key — helpers MUST treat that
|
|
45
|
+
* as a no-op rather than a bug.
|
|
46
|
+
*/
|
|
47
|
+
export type ElementIdResolver = (key: ElementKey) => string | null | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Set the native `disabled` IDL property on a button-like control resolved
|
|
50
|
+
* from `key`. Used by the orchestrator's `updateUi` policy: each toolbar
|
|
51
|
+
* button maps to one logical key, and the policy decides whether the
|
|
52
|
+
* button is currently usable.
|
|
53
|
+
*
|
|
54
|
+
* Behaviour:
|
|
55
|
+
*
|
|
56
|
+
* - If `resolveElementId(key)` returns a falsy value, the helper returns
|
|
57
|
+
* without touching the DOM (the integrator chose not to wire that
|
|
58
|
+
* control).
|
|
59
|
+
* - If `document.getElementById(id)` returns `null`, the helper returns
|
|
60
|
+
* without throwing. A missing node is a partial-DOM scenario, not a
|
|
61
|
+
* fatal error.
|
|
62
|
+
* - Otherwise the resolved element's `disabled` property is set to the
|
|
63
|
+
* requested boolean. Using the IDL property (not `setAttribute`)
|
|
64
|
+
* keeps the keyboard/click behaviour the
|
|
65
|
+
* browser provides "for free" on real `<button>` elements.
|
|
66
|
+
*
|
|
67
|
+
* The element is typed as `HTMLButtonElement` because every key in the
|
|
68
|
+
* documented toolbar set (`zoomInButton`, `applyCropButton`, …) resolves to a
|
|
69
|
+
* `<button>`. A non-button host element will still receive the `disabled`
|
|
70
|
+
* assignment via the IDL slot but will not visually reflect it; that is
|
|
71
|
+
* the integrator's responsibility per the public `idMap` contract.
|
|
72
|
+
*
|
|
73
|
+
* @param resolveElementId - Resolver from logical key to DOM element ID.
|
|
74
|
+
* @param key - Logical toolbar element key.
|
|
75
|
+
* @param disabled - Target `disabled` value.
|
|
76
|
+
*/
|
|
77
|
+
export declare function setDisabled(resolveElementId: ElementIdResolver, key: ElementKey, disabled: boolean): void;
|
|
78
|
+
/**
|
|
79
|
+
* Set the `aria-disabled` attribute on the element resolved from `key`.
|
|
80
|
+
* Useful for non-button toolbar controls (links, custom widgets) that do
|
|
81
|
+
* not honour the native `disabled` IDL property but still need to expose
|
|
82
|
+
* disabled state to assistive technology.
|
|
83
|
+
*
|
|
84
|
+
* Behaviour mirrors {@link setDisabled}: missing key or missing element
|
|
85
|
+
* results in a silent no-op. The attribute value is
|
|
86
|
+
* always the canonical string `'true'` or `'false'` as required by the
|
|
87
|
+
* ARIA spec — never the empty string and never removed entirely, so a
|
|
88
|
+
* subsequent toggle is a single `setAttribute` away.
|
|
89
|
+
*
|
|
90
|
+
* @param resolveElementId - Resolver from logical key to DOM element ID.
|
|
91
|
+
* @param key - Logical toolbar element key.
|
|
92
|
+
* @param disabled - Target `aria-disabled` value.
|
|
93
|
+
*/
|
|
94
|
+
export declare function setAriaDisabled(resolveElementId: ElementIdResolver, key: ElementKey, disabled: boolean): void;
|
|
95
|
+
/**
|
|
96
|
+
* Toggle a CSS class on the element resolved from `key`. Used for toolbar
|
|
97
|
+
* state that does not correspond to `disabled` / `aria-disabled` — for
|
|
98
|
+
* example, marking the active mask in the mask list or flipping a button
|
|
99
|
+
* into a "pressed" visual style during crop mode.
|
|
100
|
+
*
|
|
101
|
+
* The helper delegates to `Element.classList.toggle(className, force)`, so
|
|
102
|
+
* the caller's `enabled` flag deterministically adds or removes the class
|
|
103
|
+
* regardless of its current presence. Missing key or missing element is a
|
|
104
|
+
* silent no-op.
|
|
105
|
+
*
|
|
106
|
+
* @param resolveElementId - Resolver from logical key to DOM element ID.
|
|
107
|
+
* @param key - Logical toolbar element key.
|
|
108
|
+
* @param className - CSS class name to toggle.
|
|
109
|
+
* @param enabled - `true` to add the class, `false` to remove it.
|
|
110
|
+
*/
|
|
111
|
+
export declare function setClass(resolveElementId: ElementIdResolver, key: ElementKey, className: string, enabled: boolean): void;
|
|
112
|
+
//# sourceMappingURL=ui-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-state.d.ts","sourceRoot":"","sources":["../../../src/ui/ui-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,WAAW,CACvB,gBAAgB,EAAE,iBAAiB,EACnC,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,OAAO,GAClB,IAAI,CAKN;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC3B,gBAAgB,EAAE,iBAAiB,EACnC,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,OAAO,GAClB,IAAI,CAKN;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CACpB,gBAAgB,EAAE,iBAAiB,EACnC,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,GACjB,IAAI,CAKN"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Placeholder/canvas-container visibility helper. Owns the
|
|
3
|
+
* standard-DOM-state transition that the orchestrator's
|
|
4
|
+
* private `_setPlaceholderVisible` method delegates to.
|
|
5
|
+
*
|
|
6
|
+
* ## Owned contracts
|
|
7
|
+
*
|
|
8
|
+
* - `setPlaceholderVisible(..., true)` SHALL set the
|
|
9
|
+
* placeholder's `hidden` to `false` and `aria-hidden` to `'false'`, and
|
|
10
|
+
* SHALL set the canvas container's `hidden` to `true` and `aria-hidden`
|
|
11
|
+
* to `'true'`.
|
|
12
|
+
* - `setPlaceholderVisible(..., false)` SHALL set the
|
|
13
|
+
* placeholder's `hidden` to `true` and `aria-hidden` to `'true'`, and
|
|
14
|
+
* SHALL set the canvas container's `hidden` to `false` and `aria-hidden`
|
|
15
|
+
* to `'false'`.
|
|
16
|
+
* - This module SHALL NOT add or remove the
|
|
17
|
+
* Bootstrap `d-none` class on either element. The host page is free to
|
|
18
|
+
* style `[hidden]` however it likes; the editor stays out of utility-class
|
|
19
|
+
* territory so it works with or without Bootstrap.
|
|
20
|
+
* - When `containerElement` is `null`, the
|
|
21
|
+
* placeholder's `hidden` and `aria-hidden` SHALL still be updated
|
|
22
|
+
* correctly. A missing container is a partial-DOM scenario, not a fatal
|
|
23
|
+
* error.
|
|
24
|
+
*
|
|
25
|
+
* ## Why this lives in its own module
|
|
26
|
+
*
|
|
27
|
+
* The helper uses standard DOM state instead of Bootstrap utility classes so
|
|
28
|
+
* the editor works with or without a host stylesheet. Keeping the transition
|
|
29
|
+
* here makes the orchestrator's private method a one-line delegate and keeps
|
|
30
|
+
* the behavior unit-testable in isolation. This module is imported by
|
|
31
|
+
* `image-editor.ts` only and is intentionally not re-exported from
|
|
32
|
+
* `src/index.ts`.
|
|
33
|
+
*
|
|
34
|
+
* @module
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* Toggle placeholder/canvas-container visibility using only standard DOM
|
|
38
|
+
* state. The function is total: it never throws on null inputs and never
|
|
39
|
+
* touches utility classes.
|
|
40
|
+
*
|
|
41
|
+
* Visibility semantics:
|
|
42
|
+
*
|
|
43
|
+
* - `show === true` means **show the placeholder** (and therefore hide the
|
|
44
|
+
* canvas container). The placeholder is the "no image yet" affordance, so
|
|
45
|
+
* showing it implies the live canvas is not the right thing to render.
|
|
46
|
+
* - `show === false` means **hide the placeholder** (and therefore show the
|
|
47
|
+
* canvas container). This is the post-`loadImage` steady state.
|
|
48
|
+
*
|
|
49
|
+
* In both branches the function:
|
|
50
|
+
*
|
|
51
|
+
* 1. Sets the DOM `hidden` property. Using the
|
|
52
|
+
* property — not the attribute — keeps the IDL flag and the reflected
|
|
53
|
+
* attribute in sync without an extra `setAttribute` call.
|
|
54
|
+
* 2. Sets `aria-hidden` to the matching string so assistive technology
|
|
55
|
+
* tracks the visual state.
|
|
56
|
+
* 3. Leaves every other class and inline style untouched. In particular,
|
|
57
|
+
* Bootstrap's `d-none` is never added or removed,
|
|
58
|
+
* which lets the editor coexist with host pages that use `d-none` for
|
|
59
|
+
* their own purposes.
|
|
60
|
+
*
|
|
61
|
+
* When `containerElement` is `null` (partial DOM, or a host page that does
|
|
62
|
+
* not wrap the canvas in a dedicated container), the placeholder side of
|
|
63
|
+
* the transition still runs to completion. When
|
|
64
|
+
* `placeholderElement` is `null` the function is a no-op for that side; the
|
|
65
|
+
* orchestrator's `updatePlaceholderStatus` already early-returns in that
|
|
66
|
+
* case, but defending here keeps the helper safe to call from any future
|
|
67
|
+
* code path.
|
|
68
|
+
*
|
|
69
|
+
* @param placeholderElement - The placeholder DOM element shown when no image is loaded, or `null`
|
|
70
|
+
* when the host page omitted the placeholder slot from the `idMap`.
|
|
71
|
+
* @param containerElement - The canvas container DOM element wrapping the live `<canvas>`, or
|
|
72
|
+
* `null` when no container is available.
|
|
73
|
+
* @param show - `true` to make the placeholder visible (and hide the canvas container);
|
|
74
|
+
* `false` to hide the placeholder (and show the canvas container).
|
|
75
|
+
*/
|
|
76
|
+
export declare function setPlaceholderVisible(placeholderElement: HTMLElement | null, containerElement: HTMLElement | null, show: boolean): void;
|
|
77
|
+
//# sourceMappingURL=visibility-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visibility-state.d.ts","sourceRoot":"","sources":["../../../src/ui/visibility-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,qBAAqB,CACjC,kBAAkB,EAAE,WAAW,GAAG,IAAI,EACtC,gBAAgB,EAAE,WAAW,GAAG,IAAI,EACpC,IAAI,EAAE,OAAO,GACd,IAAI,CAgBN"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers that turn floating-point Fabric.js bounding
|
|
3
|
+
* rectangles into integer pixel regions and provide the
|
|
4
|
+
* bounding-box math that mask preservation across crop and
|
|
5
|
+
* export paths share.
|
|
6
|
+
*
|
|
7
|
+
* ## Owned contracts
|
|
8
|
+
*
|
|
9
|
+
* - Export regions SHALL include partially covered trailing pixels so
|
|
10
|
+
* sub-pixel image bounds do not lose the right or bottom edge.
|
|
11
|
+
* - Crop regions SHALL exclude trailing partial pixels so crop does not
|
|
12
|
+
* grow by a transparent row or column.
|
|
13
|
+
* - When `applyCrop` runs with
|
|
14
|
+
* `preserveMasksAfterCrop === true` and the image has been rotated,
|
|
15
|
+
* each mask's new `left` and `top` SHALL be expressed in the cropped
|
|
16
|
+
* image's coordinate frame using the rotation angle.
|
|
17
|
+
* - Across a crop apply, each mask's `angle`,
|
|
18
|
+
* `scaleX`, and `scaleY` SHALL be preserved so the visible shape does
|
|
19
|
+
* not change size or orientation.
|
|
20
|
+
*
|
|
21
|
+
* ## Why a dedicated module
|
|
22
|
+
*
|
|
23
|
+
* Region math is shared by export, crop, expand-to-image sizing, and crop
|
|
24
|
+
* rectangle initialization. Centralizing it prevents one call site from
|
|
25
|
+
* drifting from the others (for example, applying `Math.floor` instead of
|
|
26
|
+
* `Math.round`, or forgetting the `width >= 1` floor).
|
|
27
|
+
*
|
|
28
|
+
* ## Design notes
|
|
29
|
+
*
|
|
30
|
+
* - Region floors are total: any non-finite input collapses to a
|
|
31
|
+
* `1×1` region anchored at `(0, 0)` rather than throwing. The export
|
|
32
|
+
* and crop pipelines already validate the presence of an
|
|
33
|
+
* `originalImage` upstream, so a defensive fallback here keeps the
|
|
34
|
+
* `<canvas>.drawImage` call from being passed `NaN` if Fabric ever
|
|
35
|
+
* reports a degenerate bounding rect.
|
|
36
|
+
* - `getObjectBBox` calls `setCoords` before reading the bounding
|
|
37
|
+
* rect because Fabric.js v7's `getBoundingRect` returns the cached
|
|
38
|
+
* absolute rect; without the refresh a freshly-mutated mask returns
|
|
39
|
+
* stale coordinates. Callers that have already refreshed coords pay
|
|
40
|
+
* only a single redundant call, which is cheaper than double-tracking
|
|
41
|
+
* "is this object's cache fresh?" at every site.
|
|
42
|
+
* - `clampRegionToCanvas` exists for the crop pipeline, where the crop
|
|
43
|
+
* rectangle's bounding rect can briefly exceed the canvas after a
|
|
44
|
+
* user drag near the edge; clamping before the `drawImage` keeps the
|
|
45
|
+
* blit inside the source canvas.
|
|
46
|
+
*
|
|
47
|
+
* ## Non-goals
|
|
48
|
+
*
|
|
49
|
+
* - This module does not perform any coordinate transformation between
|
|
50
|
+
* pre-crop and post-crop frames; the rotation math for the
|
|
51
|
+
* rotated-mask coordinate frame lives in `crop/crop-controller.ts`,
|
|
52
|
+
* which uses
|
|
53
|
+
* `getObjectBBox` here only as one input to that calculation.
|
|
54
|
+
* - This module does not mutate the Fabric object passed to
|
|
55
|
+
* `getObjectBBox` beyond the `setCoords` refresh required by
|
|
56
|
+
* Fabric.js v7's API.
|
|
57
|
+
*
|
|
58
|
+
* @module
|
|
59
|
+
*/
|
|
60
|
+
import type * as FabricNS from 'fabric';
|
|
61
|
+
/**
|
|
62
|
+
* A canvas region whose `left` / `top` / `width` / `height` are all
|
|
63
|
+
* integer pixels suitable for `CanvasRenderingContext2D.drawImage` and
|
|
64
|
+
* Fabric.js `toDataURL({ left, top, width, height})`.
|
|
65
|
+
*
|
|
66
|
+
* Produced by {@link floorRegion} and {@link clampRegionToCanvas}; the
|
|
67
|
+
* `width` and `height` fields are guaranteed to be at least `1` so
|
|
68
|
+
* region exports never collapse to a zero-pixel image.
|
|
69
|
+
*/
|
|
70
|
+
export interface IntegerRegion {
|
|
71
|
+
left: number;
|
|
72
|
+
top: number;
|
|
73
|
+
width: number;
|
|
74
|
+
height: number;
|
|
75
|
+
}
|
|
76
|
+
export interface RegionRoundingOptions {
|
|
77
|
+
/**
|
|
78
|
+
* When true, `right` / `bottom` are ceiled to include partially covered
|
|
79
|
+
* trailing pixels. When false, they are floored to exclude them.
|
|
80
|
+
* @default true
|
|
81
|
+
*/
|
|
82
|
+
includePartialPixels?: boolean;
|
|
83
|
+
}
|
|
84
|
+
export interface PartialExportEdges {
|
|
85
|
+
left: boolean;
|
|
86
|
+
top: boolean;
|
|
87
|
+
right: boolean;
|
|
88
|
+
bottom: boolean;
|
|
89
|
+
}
|
|
90
|
+
export declare function hasMeaningfulCanvasRegion(rect: {
|
|
91
|
+
left: number;
|
|
92
|
+
top: number;
|
|
93
|
+
width: number;
|
|
94
|
+
height: number;
|
|
95
|
+
}, canvasWidth?: number, canvasHeight?: number): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Convert a floating-point rectangle into an {@link IntegerRegion}.
|
|
98
|
+
*
|
|
99
|
+
* - `left` / `top` are floored and clamped to `>= 0` so the region
|
|
100
|
+
* never starts before the source canvas's top-left corner.
|
|
101
|
+
* - `right` / `bottom` are ceiled by default to include partially covered
|
|
102
|
+
* trailing pixels, or floored when `includePartialPixels` is false.
|
|
103
|
+
* - `width` / `height` are derived from those integer edges and clamped
|
|
104
|
+
* to `>= 1` so no sub-pixel dimensions reach Fabric's region export.
|
|
105
|
+
* - Non-finite inputs collapse to a `1×1` region at `(0, 0)` rather than
|
|
106
|
+
* propagating `NaN` into the canvas pipeline.
|
|
107
|
+
*
|
|
108
|
+
* region floor before mask remapping).
|
|
109
|
+
*
|
|
110
|
+
* @param rect - The floating-point bounding rect to discretize.
|
|
111
|
+
* @returns An {@link IntegerRegion} safe to pass to `drawImage`.
|
|
112
|
+
*/
|
|
113
|
+
export declare function getClampedCanvasRegion(rect: {
|
|
114
|
+
left: number;
|
|
115
|
+
top: number;
|
|
116
|
+
width: number;
|
|
117
|
+
height: number;
|
|
118
|
+
}, canvasWidth?: number, canvasHeight?: number, options?: RegionRoundingOptions): IntegerRegion;
|
|
119
|
+
export declare function floorRegion(rect: {
|
|
120
|
+
left: number;
|
|
121
|
+
top: number;
|
|
122
|
+
width: number;
|
|
123
|
+
height: number;
|
|
124
|
+
}): IntegerRegion;
|
|
125
|
+
export declare function hasFractionalCanvasEdge(value: number): boolean;
|
|
126
|
+
export declare function getPartialExportEdges(bounds: {
|
|
127
|
+
left: number;
|
|
128
|
+
top: number;
|
|
129
|
+
width: number;
|
|
130
|
+
height: number;
|
|
131
|
+
} | null, angle?: number): PartialExportEdges | null;
|
|
132
|
+
/**
|
|
133
|
+
* Read a Fabric.js object's absolute bounding rectangle in canvas-pixel
|
|
134
|
+
* coordinates.
|
|
135
|
+
*
|
|
136
|
+
* `setCoords` is called first because Fabric.js v7's
|
|
137
|
+
* `getBoundingRect` returns the cached absolute rect — the per-frame
|
|
138
|
+
* cache the canvas already maintains. Without the refresh a freshly
|
|
139
|
+
* mutated mask returns stale coordinates, which can make rotated masks
|
|
140
|
+
* drift after crop.
|
|
141
|
+
*
|
|
142
|
+
* The returned rect uses floating-point coordinates; callers that need
|
|
143
|
+
* integer pixel regions should pipe the result through
|
|
144
|
+
* {@link floorRegion}.
|
|
145
|
+
*
|
|
146
|
+
* @param object - The Fabric.js object to measure.
|
|
147
|
+
* @returns The absolute bounding rect in canvas pixels.
|
|
148
|
+
*/
|
|
149
|
+
export declare function getObjectBBox(object: FabricNS.FabricObject): {
|
|
150
|
+
left: number;
|
|
151
|
+
top: number;
|
|
152
|
+
width: number;
|
|
153
|
+
height: number;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Clamp an {@link IntegerRegion} so it fits entirely inside a canvas of
|
|
157
|
+
* `canvasWidth × canvasHeight` pixels.
|
|
158
|
+
*
|
|
159
|
+
* - `left` is clamped to `[0, canvasWidth - 1]`.
|
|
160
|
+
* - `top` is clamped to `[0, canvasHeight - 1]`.
|
|
161
|
+
* - `width` is clamped so `left + width <= canvasWidth`.
|
|
162
|
+
* - `height` is clamped so `top + height <= canvasHeight`.
|
|
163
|
+
*
|
|
164
|
+
* The function preserves the `width >= 1` / `height >= 1` invariant
|
|
165
|
+
* established by {@link floorRegion}, which keeps callers from having
|
|
166
|
+
* to special-case zero-sized regions when the supplied rect lands
|
|
167
|
+
* entirely outside the canvas.
|
|
168
|
+
*
|
|
169
|
+
* canvas before the mask coordinate remap).
|
|
170
|
+
*
|
|
171
|
+
* @param region - The integer region to clamp.
|
|
172
|
+
* @param canvasWidth - The source canvas's pixel width.
|
|
173
|
+
* @param canvasHeight - The source canvas's pixel height.
|
|
174
|
+
* @returns A clamped {@link IntegerRegion}.
|
|
175
|
+
*/
|
|
176
|
+
export declare function clampRegionToCanvas(region: IntegerRegion, canvasWidth: number, canvasHeight: number): IntegerRegion;
|
|
177
|
+
//# sourceMappingURL=canvas-region.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-region.d.ts","sourceRoot":"","sources":["../../../src/utils/canvas-region.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AAEH,OAAO,KAAK,KAAK,QAAQ,MAAM,QAAQ,CAAC;AAExC;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IAClC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,yBAAyB,CACrC,IAAI,EAAE;IACF,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,EACD,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,GACtB,OAAO,CAkCT;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAClC,IAAI,EAAE;IACF,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,EACD,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,GAAE,qBAA0B,GACpC,aAAa,CA4Bf;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,GAAG,aAAa,CAEhB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAI9D;AAED,wBAAgB,qBAAqB,CACjC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,EAC3E,KAAK,SAAI,GACV,kBAAkB,GAAG,IAAI,CAc3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,CASA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACrB,aAAa,CASf"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM micro-helpers used by sizing and visibility flows.
|
|
3
|
+
*
|
|
4
|
+
* Kept intentionally small: the editor depends on a single synchronous
|
|
5
|
+
* reflow primitive after canvas dimension changes, and exposing it as a
|
|
6
|
+
* named utility lets layout, visibility, and crop flows share the same
|
|
7
|
+
* documented contract.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Force a synchronous layout reflow on `element`.
|
|
11
|
+
*
|
|
12
|
+
* Reading an offset/scroll/clientWidth-like property forces the browser
|
|
13
|
+
* to flush queued style and layout work on the spot, before any further
|
|
14
|
+
* script runs. The editor relies on this after `Canvas.setDimensions`
|
|
15
|
+
* so a container with `overflow: auto` shows or hides scrollbars before
|
|
16
|
+
* the next paint, instead of waiting for the next frame.
|
|
17
|
+
*
|
|
18
|
+
* The read is cast to `void` and isolated in this helper so optimizers
|
|
19
|
+
* cannot eliminate it as a dead access. The function is a no-op when
|
|
20
|
+
* `element` is `null` or `undefined`, which keeps callers free of guards in
|
|
21
|
+
* environments where the container element may not yet be attached.
|
|
22
|
+
*
|
|
23
|
+
* @param element - The element whose layout should be flushed. `null` is ignored.
|
|
24
|
+
*/
|
|
25
|
+
export declare function forceReflow(element: HTMLElement | null | undefined): void;
|
|
26
|
+
//# sourceMappingURL=dom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../../src/utils/dom.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAMzE"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-input helpers used by the editor's file-input flow.
|
|
3
|
+
*
|
|
4
|
+
* These helpers cover three concerns:
|
|
5
|
+
*
|
|
6
|
+
* - Determining whether a `File` selected through the upload control is a
|
|
7
|
+
* supported image, including the extension fallback when `file.type` is
|
|
8
|
+
* empty (some operating systems and browsers report an empty MIME type
|
|
9
|
+
* for known extensions).
|
|
10
|
+
* - Reading the file as a base64 data URL so the result can be routed
|
|
11
|
+
* through the existing transactional `loadImage` pipeline (and therefore
|
|
12
|
+
* inherit its rollback behavior on decode/Fabric/timeout failure).
|
|
13
|
+
* - Resetting the file input value after every attempt so selecting the
|
|
14
|
+
* same file again triggers a fresh `change` event.
|
|
15
|
+
*
|
|
16
|
+
* The helpers do not call `loadImage` themselves; the orchestrator wires
|
|
17
|
+
* them into the file-input change handler. That keeps the public
|
|
18
|
+
* `loadImage` API unchanged beyond `LoadImageOptions`.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Supported image extensions and the MIME type each one resolves to.
|
|
22
|
+
*
|
|
23
|
+
* Supported file extensions: `png`, `jpg`/`jpeg`, `webp`, `gif`, `bmp`.
|
|
24
|
+
* GIF and BMP are accepted as static raster input for canvas editing. GIF
|
|
25
|
+
* animation and GIF/BMP source-format preservation are not retained; exports
|
|
26
|
+
* are emitted through the editor's JPEG, PNG, or WebP export options.
|
|
27
|
+
*
|
|
28
|
+
* Keys are lowercase extensions without the leading `.`.
|
|
29
|
+
*/
|
|
30
|
+
export declare const SUPPORTED_IMAGE_EXTENSIONS: Record<string, string>;
|
|
31
|
+
export declare const SUPPORTED_IMAGE_MIME_TYPES: Set<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Determine whether a `File` is a supported image and return its resolved
|
|
34
|
+
* MIME type, or `null` when it should be rejected.
|
|
35
|
+
*
|
|
36
|
+
* Resolution order:
|
|
37
|
+
*
|
|
38
|
+
* 1. If `file.type` is one of the supported image MIME types, return it
|
|
39
|
+
* verbatim.
|
|
40
|
+
* 2. If `file.type` is empty, infer the MIME type from the file
|
|
41
|
+
* extension via {@link SUPPORTED_IMAGE_EXTENSIONS}. This covers the
|
|
42
|
+
* case where a browser or OS reports `''` for files with a known
|
|
43
|
+
* extension.
|
|
44
|
+
* 3. Otherwise, return `null` so the caller can skip the load without
|
|
45
|
+
* mutating editor state.
|
|
46
|
+
*
|
|
47
|
+
* @param file - File selected via the upload control.
|
|
48
|
+
* @returns The resolved MIME type, or `null` when the file is not a
|
|
49
|
+
* supported image.
|
|
50
|
+
*/
|
|
51
|
+
export declare function inferImageMimeType(file: File): string | null;
|
|
52
|
+
/**
|
|
53
|
+
* Read a `File` as a base64 data URL using `FileReader`.
|
|
54
|
+
*
|
|
55
|
+
* The returned data URL is suitable for the transactional `loadImage`
|
|
56
|
+
* pipeline: on failure the editor's existing
|
|
57
|
+
* rollback bundle restores placeholder visibility, scroll, overflow,
|
|
58
|
+
* `originalImage`, `lastSnapshot`, and the canvas JSON snapshot.
|
|
59
|
+
*
|
|
60
|
+
* @param file - File to read.
|
|
61
|
+
* @returns A promise that resolves to the data URL string, or rejects when
|
|
62
|
+
* the underlying `FileReader` errors out or returns a non-string
|
|
63
|
+
* result.
|
|
64
|
+
*/
|
|
65
|
+
export declare function readFileAsDataUrl(file: File): Promise<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Reset a file input element's value so selecting the same file again
|
|
68
|
+
* triggers a fresh `change` event.
|
|
69
|
+
*
|
|
70
|
+
* Some browsers reject programmatic assignment to `input.value` on
|
|
71
|
+
* security grounds; the assignment is wrapped in a `try`/`catch` so the
|
|
72
|
+
* caller never has to special-case those environments. A `null` input is
|
|
73
|
+
* a no-op so callers can pass the result of `document.getElementById`
|
|
74
|
+
* without an extra null check.
|
|
75
|
+
*
|
|
76
|
+
* @param input - File input element, or `null` when the element is not
|
|
77
|
+
* present in the DOM.
|
|
78
|
+
*/
|
|
79
|
+
export declare function resetFileInput(input: HTMLInputElement | null): void;
|
|
80
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/utils/file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAO7D,CAAC;AAEF,eAAO,MAAM,0BAA0B,aAAqD,CAAC;AAE7F;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAO5D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAmB7D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAOnE"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers used by `mask/mask-factory.ts` to turn the
|
|
3
|
+
* flexible `MaskNumericProp` and `PolygonPoint` inputs of
|
|
4
|
+
* {@link MaskConfig} into concrete numbers and `{ x, y }`
|
|
5
|
+
* points before a Fabric.js shape is constructed.
|
|
6
|
+
*
|
|
7
|
+
* ## Owned contracts
|
|
8
|
+
*
|
|
9
|
+
* - `MaskConfig` percentage values supplied for
|
|
10
|
+
* `left`, `width`, `rx`, or `radius` SHALL resolve against the canvas
|
|
11
|
+
* pixel **width** (axis `'x'`).
|
|
12
|
+
* - `MaskConfig` percentage values supplied for
|
|
13
|
+
* `top`, `height`, or `ry` SHALL resolve against the canvas pixel
|
|
14
|
+
* **height** (axis `'y'`).
|
|
15
|
+
* - A `MaskNumericProp` provided as a function
|
|
16
|
+
* SHALL be invoked with `(canvas, ResolvedOptions)` and the returned
|
|
17
|
+
* number used directly.
|
|
18
|
+
* - Polygon point items SHALL be accepted in
|
|
19
|
+
* either `{ x, y }` object form or `[x, y]` tuple form and coerced to
|
|
20
|
+
* numeric `{ x, y }` internally.
|
|
21
|
+
*
|
|
22
|
+
* ## Why a dedicated module
|
|
23
|
+
*
|
|
24
|
+
* `resolveNumeric` is axis-aware so horizontal values resolve against
|
|
25
|
+
* canvas width and vertical values resolve against canvas height.
|
|
26
|
+
* `coercePoint` lives next to it because both helpers are pure functions
|
|
27
|
+
* consumed by the same mask-factory pipeline.
|
|
28
|
+
*
|
|
29
|
+
* ## Design notes
|
|
30
|
+
*
|
|
31
|
+
* - `resolveNumeric` is total: any input that is not a number, a finite
|
|
32
|
+
* percentage string, or a function falls through to `fallback` rather
|
|
33
|
+
* than throwing.
|
|
34
|
+
* - Percentages are floored (`Math.floor`) to keep rendered placement
|
|
35
|
+
* deterministic across canvas resizes.
|
|
36
|
+
* - The helper does NOT clamp the result against canvas bounds; callers
|
|
37
|
+
* are responsible for any subsequent clamping (the mask factory may
|
|
38
|
+
* expand the canvas to accommodate larger placements in expand layout mode).
|
|
39
|
+
*
|
|
40
|
+
* ## Non-goals
|
|
41
|
+
*
|
|
42
|
+
* - This module does not validate that the supplied `axis` matches the
|
|
43
|
+
* field being resolved. Routing each `MaskConfig` field to the correct
|
|
44
|
+
* axis is the mask factory's responsibility.
|
|
45
|
+
* - This module does not coerce or round the output of factory functions
|
|
46
|
+
* (`(canvas, options) => number`); their return value is used verbatim
|
|
47
|
+
* so consumers retain full control over sub-pixel placement.
|
|
48
|
+
*
|
|
49
|
+
* @module
|
|
50
|
+
*/
|
|
51
|
+
import type * as FabricNS from 'fabric';
|
|
52
|
+
import type { MaskNumericProp, PolygonPoint, ResolvedOptions } from '../core/public-types.js';
|
|
53
|
+
/**
|
|
54
|
+
* Axis selector used by {@link resolveNumeric} to decide which canvas
|
|
55
|
+
* dimension a percentage value resolves against.
|
|
56
|
+
*
|
|
57
|
+
* - `'x'` → `canvas.getWidth`
|
|
58
|
+
* - `'y'` → `canvas.getHeight`
|
|
59
|
+
*/
|
|
60
|
+
export type Axis = 'x' | 'y';
|
|
61
|
+
/**
|
|
62
|
+
* Resolve a {@link MaskNumericProp} into a concrete pixel number.
|
|
63
|
+
*
|
|
64
|
+
* Resolution rules (in order):
|
|
65
|
+
* 1. If `val` is a `number`, return it unchanged.
|
|
66
|
+
* 2. If `val` is a function, invoke it as `val(canvas, options)` and
|
|
67
|
+
* return the result.
|
|
68
|
+
* 3. If `val` is a string ending in `'%'`, parse the leading number,
|
|
69
|
+
* multiply by `canvas.getWidth` (axis `'x'`) or
|
|
70
|
+
* `canvas.getHeight` (axis `'y'`), floor the product, and return
|
|
71
|
+
* it. Strings that do not parse to a
|
|
72
|
+
* finite number fall through to `fallback`.
|
|
73
|
+
* 4. Anything else (including `undefined`, `null`, non-percent strings,
|
|
74
|
+
* booleans, etc.) returns `fallback`.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* // 50% of an 800px-wide canvas:
|
|
79
|
+
* resolveNumeric('50%', 'x', 0, canvas, options); // → 400
|
|
80
|
+
*
|
|
81
|
+
* // Function form receives the live canvas and ResolvedOptions:
|
|
82
|
+
* resolveNumeric(
|
|
83
|
+
* (canvas) => canvas.getWidth() - 20,
|
|
84
|
+
* 'x',
|
|
85
|
+
* 0,
|
|
86
|
+
* canvas,
|
|
87
|
+
* options,
|
|
88
|
+
* ); // → canvas.getWidth() - 20
|
|
89
|
+
*
|
|
90
|
+
* // Unrecognized input falls back:
|
|
91
|
+
* resolveNumeric(undefined, 'x', 10, canvas, options); // → 10
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @param val - The flexible mask numeric property to resolve.
|
|
95
|
+
* @param axis - Which canvas dimension a percentage resolves against.
|
|
96
|
+
* @param fallback - Value returned when `val` cannot be resolved.
|
|
97
|
+
* @param canvas - Live Fabric.js canvas; only `getWidth`/`getHeight`
|
|
98
|
+
* are read here, but the entire canvas is forwarded to
|
|
99
|
+
* factory functions.
|
|
100
|
+
* @param options - Fully-resolved editor options forwarded to factory
|
|
101
|
+
* functions.
|
|
102
|
+
*
|
|
103
|
+
* @returns The resolved pixel number, or `fallback` when no rule applies.
|
|
104
|
+
*/
|
|
105
|
+
export declare function resolveNumeric(val: MaskNumericProp | undefined, axis: Axis, fallback: number, canvas: FabricNS.Canvas, options: ResolvedOptions): number;
|
|
106
|
+
/**
|
|
107
|
+
* Coerce a {@link PolygonPoint} into the canonical `{ x, y }` numeric
|
|
108
|
+
* shape used by Fabric.js polygon construction.
|
|
109
|
+
*
|
|
110
|
+
* Both input forms are accepted so callers may write polygon points in
|
|
111
|
+
* whichever style is most ergonomic at the call site:
|
|
112
|
+
*
|
|
113
|
+
* ```ts
|
|
114
|
+
* coercePoint({ x: 10, y: 20 }); // → { x: 10, y: 20 }
|
|
115
|
+
* coercePoint([10, 20]); // → { x: 10, y: 20 }
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* Values are coerced via `Number(...)` so string-encoded coordinates
|
|
119
|
+
* (e.g. coming straight from a JSON payload) round-trip correctly. Any
|
|
120
|
+
* value that fails to coerce becomes `NaN`, matching the rest of the
|
|
121
|
+
* mask pipeline's tolerant input handling — callers that need stricter
|
|
122
|
+
* validation should perform it before constructing the polygon.
|
|
123
|
+
*
|
|
124
|
+
* @param pt - A polygon vertex in object or tuple form.
|
|
125
|
+
* @returns An `{ x, y }` numeric point.
|
|
126
|
+
*/
|
|
127
|
+
export declare function coercePoint(pt: PolygonPoint): {
|
|
128
|
+
x: number;
|
|
129
|
+
y: number;
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=number.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"number.d.ts","sourceRoot":"","sources":["../../../src/utils/number.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,KAAK,KAAK,QAAQ,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE9F;;;;;;GAMG;AACH,MAAM,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,cAAc,CAC1B,GAAG,EAAE,eAAe,GAAG,SAAS,EAChC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,QAAQ,CAAC,MAAM,EACvB,OAAO,EAAE,eAAe,GACzB,MAAM,CAgBR;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,YAAY,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAKtE"}
|