@pixerate/editor 0.207.0 → 0.208.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.
Files changed (69) hide show
  1. package/dist/animation-editor/index.cjs +60 -59
  2. package/dist/animation-editor/index.js +6 -5
  3. package/dist/{brushstrokeRender-7LXCU7PD.js → brushstrokeRender-C3UU6GVC.js} +5 -4
  4. package/dist/{brushstrokeRender-VO4ZTWVA.cjs → brushstrokeRender-EAJNE6WP.cjs} +12 -11
  5. package/dist/canvas/index.cjs +8 -8
  6. package/dist/canvas/index.js +1 -1
  7. package/dist/{chunk-2N2QPO3H.js → chunk-2PBZBRP5.js} +9 -7
  8. package/dist/{chunk-7NW46N7I.cjs → chunk-3EHPLDFQ.cjs} +54 -52
  9. package/dist/{chunk-H367YTXI.js → chunk-42TWUPNJ.js} +13 -387
  10. package/dist/chunk-474IQG74.cjs +384 -0
  11. package/dist/{chunk-MLC7HUHO.js → chunk-BGOCAUXH.js} +1 -1
  12. package/dist/chunk-DWYQPL2A.js +2010 -0
  13. package/dist/{chunk-YXKLVD56.js → chunk-F7YA3MMC.js} +2 -2
  14. package/dist/{chunk-ZZGPYNS2.js → chunk-G4E6RUPC.js} +1 -1
  15. package/dist/chunk-HVVR5PZW.js +384 -0
  16. package/dist/{chunk-FR2Q2LVF.cjs → chunk-I7G3RSUJ.cjs} +35 -35
  17. package/dist/chunk-K6PXS6DO.cjs +102 -0
  18. package/dist/{chunk-ZIDUPSP4.js → chunk-KFIOEOCQ.js} +24 -761
  19. package/dist/{chunk-V7GWZIZK.cjs → chunk-KWNMBMKG.cjs} +23 -21
  20. package/dist/chunk-L3G23N5Y.js +763 -0
  21. package/dist/{chunk-GHCXLQ47.js → chunk-NDMXB4PR.js} +2 -2
  22. package/dist/{chunk-CWM3CUUX.cjs → chunk-OLNIPTB3.cjs} +39 -413
  23. package/dist/{chunk-EBDCRTZI.cjs → chunk-PQ3H2AAN.cjs} +92 -90
  24. package/dist/{chunk-BRKVNXDZ.cjs → chunk-QAUIZPYI.cjs} +7 -7
  25. package/dist/{chunk-UYXL6ZWQ.cjs → chunk-QE7D7TZR.cjs} +494 -1231
  26. package/dist/chunk-QYLWG22N.cjs +763 -0
  27. package/dist/{chunk-YQ5C5BVK.cjs → chunk-ROVK6AXX.cjs} +60 -60
  28. package/dist/{chunk-HGTDMKNE.cjs → chunk-UOGKSVRQ.cjs} +126 -221
  29. package/dist/{chunk-EL5PAHNP.js → chunk-USQCKRZG.js} +6 -4
  30. package/dist/{chunk-36OKQDCF.js → chunk-WJ2RBZMM.js} +5 -3
  31. package/dist/chunk-X4LUGTQX.cjs +2010 -0
  32. package/dist/{chunk-NQMP3CWF.js → chunk-YBJXCQTR.js} +15 -110
  33. package/dist/chunk-ZIF4UJJ6.js +102 -0
  34. package/dist/{chunk-WTW7QRTS.cjs → chunk-ZMHPQ6HP.cjs} +1 -1
  35. package/dist/image-editor/controller.d.cts +28 -3
  36. package/dist/image-editor/controller.d.ts +28 -3
  37. package/dist/image-editor/index.cjs +1726 -3359
  38. package/dist/image-editor/index.js +241 -1874
  39. package/dist/image-editor/selection/index.d.cts +1 -0
  40. package/dist/image-editor/selection/index.d.ts +1 -0
  41. package/dist/image-editor/selection/segment/focus.d.cts +2 -0
  42. package/dist/image-editor/selection/segment/focus.d.ts +2 -0
  43. package/dist/image-editor/selection/segment/grabcut.d.cts +4 -2
  44. package/dist/image-editor/selection/segment/grabcut.d.ts +4 -2
  45. package/dist/image-editor/selection/segment/sky.d.cts +2 -0
  46. package/dist/image-editor/selection/segment/sky.d.ts +2 -0
  47. package/dist/image-editor/selection/segment/subject.d.cts +2 -1
  48. package/dist/image-editor/selection/segment/subject.d.ts +2 -1
  49. package/dist/image-editor/selection/segment/work.d.cts +5 -0
  50. package/dist/image-editor/selection/segment/work.d.ts +5 -0
  51. package/dist/image-editor/selection/select-and-mask.d.cts +12 -2
  52. package/dist/image-editor/selection/select-and-mask.d.ts +12 -2
  53. package/dist/image-editor/selection/worker.d.cts +126 -0
  54. package/dist/image-editor/selection/worker.d.ts +126 -0
  55. package/dist/image-editor/selection-worker.cjs +14 -0
  56. package/dist/image-editor/selection-worker.d.cts +12 -0
  57. package/dist/image-editor/selection-worker.d.ts +12 -0
  58. package/dist/image-editor/selection-worker.js +14 -0
  59. package/dist/image-editor/types.d.cts +8 -0
  60. package/dist/image-editor/types.d.ts +8 -0
  61. package/dist/paint/index.cjs +6 -5
  62. package/dist/paint/index.js +5 -4
  63. package/dist/paint-editor/index.cjs +394 -390
  64. package/dist/paint-editor/index.js +18 -14
  65. package/dist/raster/index.cjs +22 -18
  66. package/dist/raster/index.js +29 -25
  67. package/dist/vector/index.cjs +986 -985
  68. package/dist/vector/index.js +6 -5
  69. package/package.json +11 -1
@@ -9,32 +9,37 @@ import {
9
9
  multiplyHomographies
10
10
  } from "./chunk-OHKOFKBY.js";
11
11
  import {
12
- TILE,
13
- TiledSurface,
12
+ gaussianBlur
13
+ } from "./chunk-ZIF4UJJ6.js";
14
+ import {
14
15
  blendChannel,
15
16
  blendRgb,
16
- contentBounds,
17
17
  deepTile,
18
- emptySurface,
19
- finishTile,
20
18
  isBlendMode,
21
19
  isSeparableBlendMode,
22
20
  mixPigment8,
23
21
  mixPigmentRgb,
24
22
  readDeepRegion,
25
- readRegion,
26
23
  srgbDecode,
27
24
  srgbEncode,
28
25
  surfaceDepth,
26
+ tileSamples,
27
+ to32From8,
28
+ writeDeepRegion
29
+ } from "./chunk-42TWUPNJ.js";
30
+ import {
31
+ TILE,
32
+ TiledSurface,
33
+ contentBounds,
34
+ emptySurface,
35
+ finishTile,
36
+ readRegion,
29
37
  surfaceFromPixels,
30
38
  tileKey,
31
- tileSamples,
32
39
  tilesInRect,
33
- to32From8,
34
40
  translateSurface,
35
- writeDeepRegion,
36
41
  writeRegion
37
- } from "./chunk-H367YTXI.js";
42
+ } from "./chunk-HVVR5PZW.js";
38
43
 
39
44
  // src/raster/effects/model.ts
40
45
  var DEFAULT_GLOBAL_LIGHT = { angle: 120, altitude: 30 };
@@ -2263,104 +2268,6 @@ function decodeInPlace(d) {
2263
2268
  }
2264
2269
  }
2265
2270
 
2266
- // src/raster/blur.ts
2267
- function gaussianKernel(sigma) {
2268
- const r = Math.ceil(sigma * 3);
2269
- const k = new Float32Array(2 * r + 1);
2270
- let s = 0;
2271
- for (let i = -r; i <= r; i++) {
2272
- const v = Math.exp(-(i * i) / (2 * sigma * sigma));
2273
- k[i + r] = v;
2274
- s += v;
2275
- }
2276
- for (let i = 0; i < k.length; i++) k[i] /= s;
2277
- return k;
2278
- }
2279
- var DIRECT_GAUSSIAN_MAX_SIGMA = 8;
2280
- function boxRadii(sigma) {
2281
- const n = 3;
2282
- const wIdeal = Math.sqrt(12 * sigma * sigma / n + 1);
2283
- let wl = Math.floor(wIdeal);
2284
- if (wl % 2 === 0) wl--;
2285
- const wu = wl + 2;
2286
- const mIdeal = (12 * sigma * sigma - n * wl * wl - 4 * n * wl - 3 * n) / (-4 * wl - 4);
2287
- const m = Math.round(mIdeal);
2288
- const sizes = [0, 1, 2].map((i) => i < m ? wl : wu);
2289
- return sizes.map((s) => (s - 1) / 2);
2290
- }
2291
- function convolveLine(src, off, stride, len, k, edge, dst) {
2292
- const r = (k.length - 1) / 2;
2293
- for (let i = 0; i < len; i++) {
2294
- let a = 0;
2295
- const lo = i - r;
2296
- for (let j = 0; j < k.length; j++) {
2297
- let x = lo + j;
2298
- if (x < 0 || x >= len) {
2299
- if (edge === "zero") continue;
2300
- x = x < 0 ? 0 : len - 1;
2301
- }
2302
- a += src[off + x * stride] * k[j];
2303
- }
2304
- dst[i] = a;
2305
- }
2306
- }
2307
- function boxesLine(src, off, stride, len, radii, edge, a, b, dst) {
2308
- const pad = radii.reduce((s, r) => s + r, 0);
2309
- const plen = len + 2 * pad;
2310
- for (let i = 0; i < plen; i++) {
2311
- const j = i - pad;
2312
- a[i] = j < 0 ? edge === "zero" ? 0 : src[off] : j >= len ? edge === "zero" ? 0 : src[off + (len - 1) * stride] : src[off + j * stride];
2313
- }
2314
- let from = a;
2315
- let to = b;
2316
- for (const r of radii) {
2317
- let sum = 0;
2318
- for (let i = 0; i <= Math.min(r, plen - 1); i++) sum += from[i];
2319
- const k = 2 * r + 1;
2320
- for (let i = 0; i < plen; i++) {
2321
- to[i] = sum / k;
2322
- const add = i + r + 1;
2323
- const drop = i - r;
2324
- if (add < plen) sum += from[add];
2325
- if (drop >= 0) sum -= from[drop];
2326
- }
2327
- const t = from;
2328
- from = to;
2329
- to = t;
2330
- }
2331
- for (let i = 0; i < len; i++) dst[i] = from[i + pad];
2332
- }
2333
- function gaussianBlur(src, w, h, sigma, edge = "zero") {
2334
- const out = Float32Array.from(src);
2335
- if (!(sigma >= 0.1) || w <= 0 || h <= 0) return out;
2336
- const s = Math.min(sigma, 4 * Math.max(w, h));
2337
- const line = new Float32Array(Math.max(w, h));
2338
- const passes = [];
2339
- if (s <= DIRECT_GAUSSIAN_MAX_SIGMA) {
2340
- const k = gaussianKernel(s);
2341
- passes.push((buf, off, stride, len) => convolveLine(buf, off, stride, len, k, edge, line));
2342
- } else {
2343
- const radii = boxRadii(s);
2344
- const plen = Math.max(w, h) + 2 * radii.reduce((a2, r) => a2 + r, 0);
2345
- const a = new Float32Array(plen);
2346
- const b = new Float32Array(plen);
2347
- passes.push((buf, off, stride, len) => boxesLine(buf, off, stride, len, radii, edge, a, b, line));
2348
- }
2349
- for (const pass of passes) {
2350
- for (let y = 0; y < h; y++) {
2351
- pass(out, y * w, 1, w);
2352
- out.set(line.subarray(0, w), y * w);
2353
- }
2354
- }
2355
- for (const pass of passes) {
2356
- for (let x = 0; x < w; x++) {
2357
- pass(out, x, w, h);
2358
- for (let y = 0; y < h; y++) out[y * w + x] = line[y];
2359
- }
2360
- }
2361
- return out;
2362
- }
2363
-
2364
2271
  // src/raster/layers.ts
2365
2272
  var childrenOf = (l) => l.type === "group" ? l.children ?? null : null;
2366
2273
  function flattenLayers(layers) {
@@ -4293,8 +4200,6 @@ export {
4293
4200
  renderLayerEffects,
4294
4201
  DeepCompositor,
4295
4202
  workingToSamples,
4296
- DIRECT_GAUSSIAN_MAX_SIGMA,
4297
- gaussianBlur,
4298
4203
  flattenLayers,
4299
4204
  findLayer,
4300
4205
  mapLayer,
@@ -0,0 +1,102 @@
1
+ // src/raster/blur.ts
2
+ function gaussianKernel(sigma) {
3
+ const r = Math.ceil(sigma * 3);
4
+ const k = new Float32Array(2 * r + 1);
5
+ let s = 0;
6
+ for (let i = -r; i <= r; i++) {
7
+ const v = Math.exp(-(i * i) / (2 * sigma * sigma));
8
+ k[i + r] = v;
9
+ s += v;
10
+ }
11
+ for (let i = 0; i < k.length; i++) k[i] /= s;
12
+ return k;
13
+ }
14
+ var DIRECT_GAUSSIAN_MAX_SIGMA = 8;
15
+ function boxRadii(sigma) {
16
+ const n = 3;
17
+ const wIdeal = Math.sqrt(12 * sigma * sigma / n + 1);
18
+ let wl = Math.floor(wIdeal);
19
+ if (wl % 2 === 0) wl--;
20
+ const wu = wl + 2;
21
+ const mIdeal = (12 * sigma * sigma - n * wl * wl - 4 * n * wl - 3 * n) / (-4 * wl - 4);
22
+ const m = Math.round(mIdeal);
23
+ const sizes = [0, 1, 2].map((i) => i < m ? wl : wu);
24
+ return sizes.map((s) => (s - 1) / 2);
25
+ }
26
+ function convolveLine(src, off, stride, len, k, edge, dst) {
27
+ const r = (k.length - 1) / 2;
28
+ for (let i = 0; i < len; i++) {
29
+ let a = 0;
30
+ const lo = i - r;
31
+ for (let j = 0; j < k.length; j++) {
32
+ let x = lo + j;
33
+ if (x < 0 || x >= len) {
34
+ if (edge === "zero") continue;
35
+ x = x < 0 ? 0 : len - 1;
36
+ }
37
+ a += src[off + x * stride] * k[j];
38
+ }
39
+ dst[i] = a;
40
+ }
41
+ }
42
+ function boxesLine(src, off, stride, len, radii, edge, a, b, dst) {
43
+ const pad = radii.reduce((s, r) => s + r, 0);
44
+ const plen = len + 2 * pad;
45
+ for (let i = 0; i < plen; i++) {
46
+ const j = i - pad;
47
+ a[i] = j < 0 ? edge === "zero" ? 0 : src[off] : j >= len ? edge === "zero" ? 0 : src[off + (len - 1) * stride] : src[off + j * stride];
48
+ }
49
+ let from = a;
50
+ let to = b;
51
+ for (const r of radii) {
52
+ let sum = 0;
53
+ for (let i = 0; i <= Math.min(r, plen - 1); i++) sum += from[i];
54
+ const k = 2 * r + 1;
55
+ for (let i = 0; i < plen; i++) {
56
+ to[i] = sum / k;
57
+ const add = i + r + 1;
58
+ const drop = i - r;
59
+ if (add < plen) sum += from[add];
60
+ if (drop >= 0) sum -= from[drop];
61
+ }
62
+ const t = from;
63
+ from = to;
64
+ to = t;
65
+ }
66
+ for (let i = 0; i < len; i++) dst[i] = from[i + pad];
67
+ }
68
+ function gaussianBlur(src, w, h, sigma, edge = "zero") {
69
+ const out = Float32Array.from(src);
70
+ if (!(sigma >= 0.1) || w <= 0 || h <= 0) return out;
71
+ const s = Math.min(sigma, 4 * Math.max(w, h));
72
+ const line = new Float32Array(Math.max(w, h));
73
+ const passes = [];
74
+ if (s <= DIRECT_GAUSSIAN_MAX_SIGMA) {
75
+ const k = gaussianKernel(s);
76
+ passes.push((buf, off, stride, len) => convolveLine(buf, off, stride, len, k, edge, line));
77
+ } else {
78
+ const radii = boxRadii(s);
79
+ const plen = Math.max(w, h) + 2 * radii.reduce((a2, r) => a2 + r, 0);
80
+ const a = new Float32Array(plen);
81
+ const b = new Float32Array(plen);
82
+ passes.push((buf, off, stride, len) => boxesLine(buf, off, stride, len, radii, edge, a, b, line));
83
+ }
84
+ for (const pass of passes) {
85
+ for (let y = 0; y < h; y++) {
86
+ pass(out, y * w, 1, w);
87
+ out.set(line.subarray(0, w), y * w);
88
+ }
89
+ }
90
+ for (const pass of passes) {
91
+ for (let x = 0; x < w; x++) {
92
+ pass(out, x, w, h);
93
+ for (let y = 0; y < h; y++) out[y * w + x] = line[y];
94
+ }
95
+ }
96
+ return out;
97
+ }
98
+
99
+ export {
100
+ DIRECT_GAUSSIAN_MAX_SIGMA,
101
+ gaussianBlur
102
+ };
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
74
74
  var round3 = (v) => Math.round(v * 1e3) / 1e3;
75
75
  var loading = null;
76
76
  function loadCanvasBrushstrokeRenderer() {
77
- loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-VO4ZTWVA.cjs"))).catch((error) => {
77
+ loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-EAJNE6WP.cjs"))).catch((error) => {
78
78
  loading = null;
79
79
  throw error;
80
80
  });
@@ -1,9 +1,11 @@
1
1
  import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState } from './types.cjs';
2
2
  import { type PathToSelectionOptions, type SelectionToPathOptions } from './selection/path.cjs';
3
3
  import { type MagneticEdgeOptions } from './selection/magnetic.cjs';
4
- import { type ObjectTarget } from './selection/segment/grabcut.cjs';
5
- import { type FocusAreaOptions } from './selection/segment/focus.cjs';
6
- import { type SkyOptions } from './selection/segment/sky.cjs';
4
+ import type { ObjectTarget } from './selection/segment/grabcut.cjs';
5
+ import { type SelectionJob, type SelectionJobResult, type SelectionWorkerFactory } from './selection/worker.cjs';
6
+ import type { SelectionProgress } from './selection/segment/work.cjs';
7
+ import type { FocusAreaOptions } from './selection/segment/focus.cjs';
8
+ import type { SkyOptions } from './selection/segment/sky.cjs';
7
9
  import { RenderOptions } from './renderer.cjs';
8
10
  import { type BlendMode } from './blend.cjs';
9
11
  import type { ImageHistogram } from './histogram.cjs';
@@ -146,6 +148,8 @@ export interface SampleOptions {
146
148
  }
147
149
  /** Options of {@link ImageEditorController.quickSelect}. */
148
150
  export interface QuickSelectCommandOptions {
151
+ signal?: AbortSignal;
152
+ onProgress?: SelectionProgress;
149
153
  /** Brush diameter in natural pixels (default 30). */
150
154
  size?: number;
151
155
  /** How the strokes combine with the selection (default `replace`: the first replaces, the rest add). */
@@ -157,6 +161,7 @@ export interface QuickSelectCommandOptions {
157
161
  }
158
162
  /** Options of {@link ImageEditorController.selectFocusArea}. */
159
163
  export interface FocusAreaCommandOptions extends FocusAreaOptions {
164
+ signal?: AbortSignal;
160
165
  /** How the area combines with the selection (default `replace`). */
161
166
  mode?: SelectionMode;
162
167
  /** Sample every layer (default true) or only the active pixel layer. */
@@ -186,6 +191,7 @@ export interface SkyCommandOptions extends SkyOptions {
186
191
  }
187
192
  /** Options of {@link ImageEditorController.selectObject}. */
188
193
  export interface SelectObjectCommandOptions {
194
+ onProgress?: SelectionProgress;
189
195
  /**
190
196
  * With a segmentation provider set, ask it for the object in the box or under the point (default
191
197
  * true), falling back to GrabCut when nothing it returns fits; false always uses GrabCut.
@@ -684,6 +690,7 @@ export declare class ImageEditorController {
684
690
  private compositor;
685
691
  /** The segmentation provider behind `selectSubject` (see `setSegmentationProvider`). */
686
692
  private segmentation;
693
+ private selectionWorker;
687
694
  /** The effects provider slot (see `setEffectsProvider`). */
688
695
  readonly effects: EffectsSlot;
689
696
  /** Renders provider effects: effect smart filter results and effect layers. */
@@ -714,6 +721,22 @@ export declare class ImageEditorController {
714
721
  private refreshEffectSurfaces;
715
722
  /** The registered segmentation provider, or `null` (then `selectSubject` finds the most salient subject without a model). */
716
723
  get segmentationProvider(): SegmentationProvider | null;
724
+ /**
725
+ * Runs the long selections in a Web Worker made by `factory` (or with `null`, on the page again).
726
+ * A worker that is cancelled or fails is replaced by a fresh one on the next job.
727
+ */
728
+ setSelectionWorker(factory: SelectionWorkerFactory | null): void;
729
+ /** Whether the long selections run in a worker. */
730
+ get hasSelectionWorker(): boolean;
731
+ /**
732
+ * Runs a long selection job on `pixels`: in the worker when there is one, else here (which
733
+ * blocks the page until it is done). `signal` cancels it (rejecting with an `AbortError`);
734
+ * `onProgress` hears its stages. The document is not changed.
735
+ */
736
+ runSelectionJob(job: SelectionJob, pixels: PixelBuffer, options?: {
737
+ signal?: AbortSignal;
738
+ onProgress?: SelectionProgress;
739
+ }): Promise<SelectionJobResult>;
717
740
  /** Registers (or with `null` removes) the segmentation provider. Not an edit: no undo step. */
718
741
  setSegmentationProvider(provider: SegmentationProvider | null): void;
719
742
  /** The registered effects provider, or `null`. */
@@ -1723,6 +1746,8 @@ export declare class ImageEditorController {
1723
1746
  beforeApply?: (outlines: ImagePoint[][]) => void | Promise<void>;
1724
1747
  /** Without a model: smoother, less blocky edges (Auto-Enhance). */
1725
1748
  enhanceEdge?: boolean;
1749
+ /** Without a model: hears the stages of finding the subject. */
1750
+ onProgress?: SelectionProgress;
1726
1751
  }): Promise<{
1727
1752
  segments: {
1728
1753
  label: string;
@@ -1,9 +1,11 @@
1
1
  import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState } from './types.js';
2
2
  import { type PathToSelectionOptions, type SelectionToPathOptions } from './selection/path.js';
3
3
  import { type MagneticEdgeOptions } from './selection/magnetic.js';
4
- import { type ObjectTarget } from './selection/segment/grabcut.js';
5
- import { type FocusAreaOptions } from './selection/segment/focus.js';
6
- import { type SkyOptions } from './selection/segment/sky.js';
4
+ import type { ObjectTarget } from './selection/segment/grabcut.js';
5
+ import { type SelectionJob, type SelectionJobResult, type SelectionWorkerFactory } from './selection/worker.js';
6
+ import type { SelectionProgress } from './selection/segment/work.js';
7
+ import type { FocusAreaOptions } from './selection/segment/focus.js';
8
+ import type { SkyOptions } from './selection/segment/sky.js';
7
9
  import { RenderOptions } from './renderer.js';
8
10
  import { type BlendMode } from './blend.js';
9
11
  import type { ImageHistogram } from './histogram.js';
@@ -146,6 +148,8 @@ export interface SampleOptions {
146
148
  }
147
149
  /** Options of {@link ImageEditorController.quickSelect}. */
148
150
  export interface QuickSelectCommandOptions {
151
+ signal?: AbortSignal;
152
+ onProgress?: SelectionProgress;
149
153
  /** Brush diameter in natural pixels (default 30). */
150
154
  size?: number;
151
155
  /** How the strokes combine with the selection (default `replace`: the first replaces, the rest add). */
@@ -157,6 +161,7 @@ export interface QuickSelectCommandOptions {
157
161
  }
158
162
  /** Options of {@link ImageEditorController.selectFocusArea}. */
159
163
  export interface FocusAreaCommandOptions extends FocusAreaOptions {
164
+ signal?: AbortSignal;
160
165
  /** How the area combines with the selection (default `replace`). */
161
166
  mode?: SelectionMode;
162
167
  /** Sample every layer (default true) or only the active pixel layer. */
@@ -186,6 +191,7 @@ export interface SkyCommandOptions extends SkyOptions {
186
191
  }
187
192
  /** Options of {@link ImageEditorController.selectObject}. */
188
193
  export interface SelectObjectCommandOptions {
194
+ onProgress?: SelectionProgress;
189
195
  /**
190
196
  * With a segmentation provider set, ask it for the object in the box or under the point (default
191
197
  * true), falling back to GrabCut when nothing it returns fits; false always uses GrabCut.
@@ -684,6 +690,7 @@ export declare class ImageEditorController {
684
690
  private compositor;
685
691
  /** The segmentation provider behind `selectSubject` (see `setSegmentationProvider`). */
686
692
  private segmentation;
693
+ private selectionWorker;
687
694
  /** The effects provider slot (see `setEffectsProvider`). */
688
695
  readonly effects: EffectsSlot;
689
696
  /** Renders provider effects: effect smart filter results and effect layers. */
@@ -714,6 +721,22 @@ export declare class ImageEditorController {
714
721
  private refreshEffectSurfaces;
715
722
  /** The registered segmentation provider, or `null` (then `selectSubject` finds the most salient subject without a model). */
716
723
  get segmentationProvider(): SegmentationProvider | null;
724
+ /**
725
+ * Runs the long selections in a Web Worker made by `factory` (or with `null`, on the page again).
726
+ * A worker that is cancelled or fails is replaced by a fresh one on the next job.
727
+ */
728
+ setSelectionWorker(factory: SelectionWorkerFactory | null): void;
729
+ /** Whether the long selections run in a worker. */
730
+ get hasSelectionWorker(): boolean;
731
+ /**
732
+ * Runs a long selection job on `pixels`: in the worker when there is one, else here (which
733
+ * blocks the page until it is done). `signal` cancels it (rejecting with an `AbortError`);
734
+ * `onProgress` hears its stages. The document is not changed.
735
+ */
736
+ runSelectionJob(job: SelectionJob, pixels: PixelBuffer, options?: {
737
+ signal?: AbortSignal;
738
+ onProgress?: SelectionProgress;
739
+ }): Promise<SelectionJobResult>;
717
740
  /** Registers (or with `null` removes) the segmentation provider. Not an edit: no undo step. */
718
741
  setSegmentationProvider(provider: SegmentationProvider | null): void;
719
742
  /** The registered effects provider, or `null`. */
@@ -1723,6 +1746,8 @@ export declare class ImageEditorController {
1723
1746
  beforeApply?: (outlines: ImagePoint[][]) => void | Promise<void>;
1724
1747
  /** Without a model: smoother, less blocky edges (Auto-Enhance). */
1725
1748
  enhanceEdge?: boolean;
1749
+ /** Without a model: hears the stages of finding the subject. */
1750
+ onProgress?: SelectionProgress;
1726
1751
  }): Promise<{
1727
1752
  segments: {
1728
1753
  label: string;