@pixerate/editor 0.216.0 → 0.218.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.
@@ -2241,6 +2241,29 @@ var WetWorld = class {
2241
2241
  return slot < 0 ? -1 : this.slotBase(slot);
2242
2242
  }
2243
2243
  };
2244
+ function moveWetSnapshot(snap, from, to, dx, dy, lane = () => ({})) {
2245
+ if (!Number.isInteger(dx / WET_TILE) || !Number.isInteger(dy / WET_TILE)) throw new WetWorldError(`Wet paint moves by whole ${WET_TILE} px tiles, not (${dx}, ${dy}).`);
2246
+ const a = makeLayout(from.width, from.height);
2247
+ const b = makeLayout(to.width, to.height);
2248
+ const tx0 = dx / WET_TILE;
2249
+ const ty0 = dy / WET_TILE;
2250
+ const slots = /* @__PURE__ */ new Map();
2251
+ let bytes = 0;
2252
+ for (const [key, slot] of snap.slots) {
2253
+ const index = Math.floor(key / a.perLane);
2254
+ const t = key % a.perLane;
2255
+ const tx = t % a.tilesX + tx0;
2256
+ const ty = Math.floor(t / a.tilesX) + ty0;
2257
+ if (tx < 0 || ty < 0 || tx >= b.tilesX || ty >= b.tilesY) continue;
2258
+ slots.set(index * b.perLane + ty * b.tilesX + tx, slot);
2259
+ bytes += slot.planes.byteLength;
2260
+ }
2261
+ const lanes = snap.lanes.map((l) => {
2262
+ const moved = lane(l);
2263
+ return { ...l, base: moved.base ?? l.base, flow: moved.flow === void 0 ? l.flow : moved.flow };
2264
+ });
2265
+ return { clock: snap.clock, tilt: { ...snap.tilt }, lanes, slots, bytes };
2266
+ }
2244
2267
  function unionRect(a, b) {
2245
2268
  if (!a) return { ...b };
2246
2269
  const x = Math.min(a.x, b.x);
@@ -3179,6 +3202,7 @@ export {
3179
3202
  MAX_WET_SLOTS,
3180
3203
  WetWorldError,
3181
3204
  WetWorld,
3205
+ moveWetSnapshot,
3182
3206
  WET_FLOW_KINDS,
3183
3207
  DEFAULT_FLOW,
3184
3208
  dsincos,
@@ -2241,6 +2241,29 @@ var WetWorld = (_class = class {
2241
2241
  return slot < 0 ? -1 : this.slotBase(slot);
2242
2242
  }
2243
2243
  }, _class);
2244
+ function moveWetSnapshot(snap, from, to, dx, dy, lane = () => ({})) {
2245
+ if (!Number.isInteger(dx / WET_TILE) || !Number.isInteger(dy / WET_TILE)) throw new WetWorldError(`Wet paint moves by whole ${WET_TILE} px tiles, not (${dx}, ${dy}).`);
2246
+ const a = makeLayout(from.width, from.height);
2247
+ const b = makeLayout(to.width, to.height);
2248
+ const tx0 = dx / WET_TILE;
2249
+ const ty0 = dy / WET_TILE;
2250
+ const slots = /* @__PURE__ */ new Map();
2251
+ let bytes = 0;
2252
+ for (const [key, slot] of snap.slots) {
2253
+ const index = Math.floor(key / a.perLane);
2254
+ const t = key % a.perLane;
2255
+ const tx = t % a.tilesX + tx0;
2256
+ const ty = Math.floor(t / a.tilesX) + ty0;
2257
+ if (tx < 0 || ty < 0 || tx >= b.tilesX || ty >= b.tilesY) continue;
2258
+ slots.set(index * b.perLane + ty * b.tilesX + tx, slot);
2259
+ bytes += slot.planes.byteLength;
2260
+ }
2261
+ const lanes = snap.lanes.map((l) => {
2262
+ const moved = lane(l);
2263
+ return { ...l, base: _nullishCoalesce(moved.base, () => ( l.base)), flow: moved.flow === void 0 ? l.flow : moved.flow };
2264
+ });
2265
+ return { clock: snap.clock, tilt: { ...snap.tilt }, lanes, slots, bytes };
2266
+ }
2244
2267
  function unionRect(a, b) {
2245
2268
  if (!a) return { ...b };
2246
2269
  const x = Math.min(a.x, b.x);
@@ -3195,4 +3218,5 @@ function pointerStrokeSamples(e, toPoint) {
3195
3218
 
3196
3219
 
3197
3220
 
3198
- exports.createPigmentTools = createPigmentTools; exports.WET_TILE = WET_TILE; exports.SLOT_SIDE = SLOT_SIDE; exports.PLANE = PLANE; exports.PLANE_BYTES = PLANE_BYTES; exports.SET_PLANES = SET_PLANES; exports.P_RHO = P_RHO; exports.P_UX = P_UX; exports.P_UY = P_UY; exports.P_SW = P_SW; exports.P_P0 = P_P0; exports.P_EDGE = P_EDGE; exports.P_D0 = P_D0; exports.P_H = P_H; exports.P_FX = P_FX; exports.P_FY = P_FY; exports.SLOT_PLANES = SLOT_PLANES; exports.SLOT_BYTES = SLOT_BYTES; exports.PIGMENT_CHANNELS = PIGMENT_CHANNELS; exports.EX = EX; exports.EY = EY; exports.OPP = OPP; exports.W9 = W9; exports.DRY_EPS = DRY_EPS; exports.U_MAX = U_MAX; exports.STRIP = STRIP; exports.MAX_BATCH = MAX_BATCH; exports.FREE_INTERVAL = FREE_INTERVAL; exports.FLAG_ALIVE = FLAG_ALIVE; exports.FLAG_LEFT = FLAG_LEFT; exports.FLAG_RIGHT = FLAG_RIGHT; exports.FLAG_TOP = FLAG_TOP; exports.FLAG_BOTTOM = FLAG_BOTTOM; exports.FLAG_WET = FLAG_WET; exports.PARAM_FLOATS = PARAM_FLOATS; exports.PARAM = PARAM; exports.DEFAULT_WET_PARAMS = DEFAULT_WET_PARAMS; exports.WET_PARAM_KEYS = WET_PARAM_KEYS; exports.DEFAULT_WET_PAPER = DEFAULT_WET_PAPER; exports.FLAT = FLAT; exports.normalizeWetParams = normalizeWetParams; exports.normalizeTilt = normalizeTilt; exports.latticeViscosity = latticeViscosity; exports.PAPER_CAPACITY = PAPER_CAPACITY; exports.MAX_TILT_ACCEL = MAX_TILT_ACCEL; exports.packWetParams = packWetParams; exports.edgeBits = edgeBits; exports.PIGMENT_UNIT = PIGMENT_UNIT; exports.HIDE = HIDE; exports.BODY_SCATTER = BODY_SCATTER; exports.dexp = dexp; exports.dlog = dlog; exports.dpow = dpow; exports.SRGB_TO_LINEAR = SRGB_TO_LINEAR; exports.srgbByteToLinear = srgbByteToLinear; exports.linearToSrgb8 = linearToSrgb8; exports.pigmentOf = pigmentOf; exports.expNeg = expNeg; exports.filmReflectance = filmReflectance; exports.pigmentColor = pigmentColor; exports.filmPixel = filmPixel; exports.pixelPigment = pixelPigment; exports.shadeTile = shadeTile; exports.stepSlotTs = stepSlotTs; exports.loadWetKernel = loadWetKernel; exports.canShareMemory = canShareMemory; exports.wetSimdSupported = wetSimdSupported; exports.wetSupport = wetSupport; exports.WetWorkerPool = WetWorkerPool; exports.MAX_WET_LANES = MAX_WET_LANES; exports.MAX_WET_SLOTS = MAX_WET_SLOTS; exports.WetWorldError = WetWorldError; exports.WetWorld = WetWorld; exports.WET_FLOW_KINDS = WET_FLOW_KINDS; exports.DEFAULT_FLOW = DEFAULT_FLOW; exports.dsincos = dsincos; exports.normalizeFlow = normalizeFlow; exports.flowField = flowField; exports.WetMedium = WetMedium; exports.WGSL_STEP = WGSL_STEP; exports.WGSL_HALO = WGSL_HALO; exports.WGSL_SHADE = WGSL_SHADE; exports.findWebGpu = findWebGpu; exports.createWetGpuEngine = createWetGpuEngine; exports.wetGpuSupport = wetGpuSupport; exports.WetGpuEngine = WetGpuEngine; exports.pointerPressure = pointerPressure; exports.pointerStrokeSample = pointerStrokeSample; exports.pointerStrokeSamples = pointerStrokeSamples;
3221
+
3222
+ exports.createPigmentTools = createPigmentTools; exports.WET_TILE = WET_TILE; exports.SLOT_SIDE = SLOT_SIDE; exports.PLANE = PLANE; exports.PLANE_BYTES = PLANE_BYTES; exports.SET_PLANES = SET_PLANES; exports.P_RHO = P_RHO; exports.P_UX = P_UX; exports.P_UY = P_UY; exports.P_SW = P_SW; exports.P_P0 = P_P0; exports.P_EDGE = P_EDGE; exports.P_D0 = P_D0; exports.P_H = P_H; exports.P_FX = P_FX; exports.P_FY = P_FY; exports.SLOT_PLANES = SLOT_PLANES; exports.SLOT_BYTES = SLOT_BYTES; exports.PIGMENT_CHANNELS = PIGMENT_CHANNELS; exports.EX = EX; exports.EY = EY; exports.OPP = OPP; exports.W9 = W9; exports.DRY_EPS = DRY_EPS; exports.U_MAX = U_MAX; exports.STRIP = STRIP; exports.MAX_BATCH = MAX_BATCH; exports.FREE_INTERVAL = FREE_INTERVAL; exports.FLAG_ALIVE = FLAG_ALIVE; exports.FLAG_LEFT = FLAG_LEFT; exports.FLAG_RIGHT = FLAG_RIGHT; exports.FLAG_TOP = FLAG_TOP; exports.FLAG_BOTTOM = FLAG_BOTTOM; exports.FLAG_WET = FLAG_WET; exports.PARAM_FLOATS = PARAM_FLOATS; exports.PARAM = PARAM; exports.DEFAULT_WET_PARAMS = DEFAULT_WET_PARAMS; exports.WET_PARAM_KEYS = WET_PARAM_KEYS; exports.DEFAULT_WET_PAPER = DEFAULT_WET_PAPER; exports.FLAT = FLAT; exports.normalizeWetParams = normalizeWetParams; exports.normalizeTilt = normalizeTilt; exports.latticeViscosity = latticeViscosity; exports.PAPER_CAPACITY = PAPER_CAPACITY; exports.MAX_TILT_ACCEL = MAX_TILT_ACCEL; exports.packWetParams = packWetParams; exports.edgeBits = edgeBits; exports.PIGMENT_UNIT = PIGMENT_UNIT; exports.HIDE = HIDE; exports.BODY_SCATTER = BODY_SCATTER; exports.dexp = dexp; exports.dlog = dlog; exports.dpow = dpow; exports.SRGB_TO_LINEAR = SRGB_TO_LINEAR; exports.srgbByteToLinear = srgbByteToLinear; exports.linearToSrgb8 = linearToSrgb8; exports.pigmentOf = pigmentOf; exports.expNeg = expNeg; exports.filmReflectance = filmReflectance; exports.pigmentColor = pigmentColor; exports.filmPixel = filmPixel; exports.pixelPigment = pixelPigment; exports.shadeTile = shadeTile; exports.stepSlotTs = stepSlotTs; exports.loadWetKernel = loadWetKernel; exports.canShareMemory = canShareMemory; exports.wetSimdSupported = wetSimdSupported; exports.wetSupport = wetSupport; exports.WetWorkerPool = WetWorkerPool; exports.MAX_WET_LANES = MAX_WET_LANES; exports.MAX_WET_SLOTS = MAX_WET_SLOTS; exports.WetWorldError = WetWorldError; exports.WetWorld = WetWorld; exports.moveWetSnapshot = moveWetSnapshot; exports.WET_FLOW_KINDS = WET_FLOW_KINDS; exports.DEFAULT_FLOW = DEFAULT_FLOW; exports.dsincos = dsincos; exports.normalizeFlow = normalizeFlow; exports.flowField = flowField; exports.WetMedium = WetMedium; exports.WGSL_STEP = WGSL_STEP; exports.WGSL_HALO = WGSL_HALO; exports.WGSL_SHADE = WGSL_SHADE; exports.findWebGpu = findWebGpu; exports.createWetGpuEngine = createWetGpuEngine; exports.wetGpuSupport = wetGpuSupport; exports.WetGpuEngine = WetGpuEngine; exports.pointerPressure = pointerPressure; exports.pointerStrokeSample = pointerStrokeSample; exports.pointerStrokeSamples = pointerStrokeSamples;
@@ -1,5 +1,6 @@
1
1
  import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState, DocumentOpener } from './types.cjs';
2
2
  import { type InspectMaskEdgeOptions, type MaskEdgeReport } from './selection/inspect.cjs';
3
+ import { type CompareSelectionsOptions, type SelectionDiff } from './selection/diff.cjs';
3
4
  import { type SelectionUncertainty, type SelectionUncertaintyOptions } from './selection/uncertainty.cjs';
4
5
  import { type PathToSelectionOptions, type SelectionToPathOptions } from './selection/path.cjs';
5
6
  import { type MagneticEdgeOptions } from './selection/magnetic.cjs';
@@ -284,6 +285,22 @@ export interface CloneSource {
284
285
  /** A vector mask's path: several `components`, or one `shape` / `subpaths` (with `op`). */
285
286
  /** What `inspectMaskEdge` reads: the selection, a layer's painted mask or its vector mask. */
286
287
  export type MaskEdgeTarget = 'selection' | 'layer-mask' | 'vector-mask';
288
+ /** A selection `compareSelections` reads (see `selectionFrom`). */
289
+ export type SelectionSource = {
290
+ kind: 'selection';
291
+ } | {
292
+ kind: 'history';
293
+ steps?: number;
294
+ } | {
295
+ kind: 'channel';
296
+ channelId: string;
297
+ } | {
298
+ kind: 'layer-mask';
299
+ layerId: string;
300
+ } | {
301
+ kind: 'vector-mask';
302
+ layerId: string;
303
+ };
287
304
  /** A layer's edge colour as `getEdgeColor` describes it (percentages). */
288
305
  export interface EdgeColorInfo {
289
306
  layerId: string;
@@ -2066,6 +2083,22 @@ export declare class ImageEditorController {
2066
2083
  * selection has none.
2067
2084
  */
2068
2085
  selectionUncertainty(options?: SelectionUncertaintyOptions): SelectionUncertainty;
2086
+ /**
2087
+ * A selection to compare (`compareSelections`): the current one, the one `steps` undo steps
2088
+ * ago, a saved channel, or a layer's painted or vector mask. `null` is nothing selected.
2089
+ */
2090
+ selectionFrom(source: SelectionSource): SelectionMask | null;
2091
+ /**
2092
+ * What changed from selection `a` (default: before the last undo step) to `b` (default: the
2093
+ * current selection): added and removed area with their largest pieces, IoU and the coverage
2094
+ * change. With `show` (default true) the canvas tints added area green and removed red until the
2095
+ * selection next changes (view state, no undo step). Read-only otherwise.
2096
+ */
2097
+ compareSelections(a?: SelectionSource, b?: SelectionSource, options?: CompareSelectionsOptions & {
2098
+ show?: boolean;
2099
+ }): SelectionDiff;
2100
+ /** Hides the `compareSelections` overlay. */
2101
+ clearSelectionDiff(): void;
2069
2102
  /** A layer's painted mask over the canvas as a selection mask; null without one (or for a depth mask). */
2070
2103
  private layerMaskCoverage;
2071
2104
  /**
@@ -1,5 +1,6 @@
1
1
  import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState, DocumentOpener } from './types.js';
2
2
  import { type InspectMaskEdgeOptions, type MaskEdgeReport } from './selection/inspect.js';
3
+ import { type CompareSelectionsOptions, type SelectionDiff } from './selection/diff.js';
3
4
  import { type SelectionUncertainty, type SelectionUncertaintyOptions } from './selection/uncertainty.js';
4
5
  import { type PathToSelectionOptions, type SelectionToPathOptions } from './selection/path.js';
5
6
  import { type MagneticEdgeOptions } from './selection/magnetic.js';
@@ -284,6 +285,22 @@ export interface CloneSource {
284
285
  /** A vector mask's path: several `components`, or one `shape` / `subpaths` (with `op`). */
285
286
  /** What `inspectMaskEdge` reads: the selection, a layer's painted mask or its vector mask. */
286
287
  export type MaskEdgeTarget = 'selection' | 'layer-mask' | 'vector-mask';
288
+ /** A selection `compareSelections` reads (see `selectionFrom`). */
289
+ export type SelectionSource = {
290
+ kind: 'selection';
291
+ } | {
292
+ kind: 'history';
293
+ steps?: number;
294
+ } | {
295
+ kind: 'channel';
296
+ channelId: string;
297
+ } | {
298
+ kind: 'layer-mask';
299
+ layerId: string;
300
+ } | {
301
+ kind: 'vector-mask';
302
+ layerId: string;
303
+ };
287
304
  /** A layer's edge colour as `getEdgeColor` describes it (percentages). */
288
305
  export interface EdgeColorInfo {
289
306
  layerId: string;
@@ -2066,6 +2083,22 @@ export declare class ImageEditorController {
2066
2083
  * selection has none.
2067
2084
  */
2068
2085
  selectionUncertainty(options?: SelectionUncertaintyOptions): SelectionUncertainty;
2086
+ /**
2087
+ * A selection to compare (`compareSelections`): the current one, the one `steps` undo steps
2088
+ * ago, a saved channel, or a layer's painted or vector mask. `null` is nothing selected.
2089
+ */
2090
+ selectionFrom(source: SelectionSource): SelectionMask | null;
2091
+ /**
2092
+ * What changed from selection `a` (default: before the last undo step) to `b` (default: the
2093
+ * current selection): added and removed area with their largest pieces, IoU and the coverage
2094
+ * change. With `show` (default true) the canvas tints added area green and removed red until the
2095
+ * selection next changes (view state, no undo step). Read-only otherwise.
2096
+ */
2097
+ compareSelections(a?: SelectionSource, b?: SelectionSource, options?: CompareSelectionsOptions & {
2098
+ show?: boolean;
2099
+ }): SelectionDiff;
2100
+ /** Hides the `compareSelections` overlay. */
2101
+ clearSelectionDiff(): void;
2069
2102
  /** A layer's painted mask over the canvas as a selection mask; null without one (or for a depth mask). */
2070
2103
  private layerMaskCoverage;
2071
2104
  /**