Skip to content

v2.1.0

Choose a tag to compare

@github-actions github-actions released this 11 Jun 16:02

Breaking Changes

  • Replaced layout boolean options (expandCanvasToImage, fitImageToCanvas, coverImageToCanvas) with defaultLayoutMode: 'fit' | 'cover' | 'expand'.
  • Runtime layout changes should use editor.setLayoutMode(mode).
  • Invalid constructor defaultLayoutMode values fall back to 'expand'.
  • Invalid setLayoutMode(mode) calls are ignored and preserve the current layout mode.

Added

  • Add complete Mosaic mode with defaultMosaicConfig, runtime Mosaic config setters, optional DOM bindings, circular preview cursor, base-image pixel commits, and undo/redo support per successful click.
  • Add Mosaic drag painting with live in-canvas preview by caching decoded pixels during a Mosaic session, processing queued pointer points, and committing each completed stroke as one undoable history entry.
  • Add pure Mosaic pixelation and coordinate-conversion coverage, including scaled/translated/rotated image mapping.
  • Add default mask configuration for new masks.
  • Add regression coverage for dispose-aborted Fabric animations, deterministic mask UIDs, strict export data URL decoding, and frozen resolved options.

Changed

  • Rework the v2 demo workspace into a side-toolbar layout, compact icon controls, and a narrower mask list to avoid toolbar overflow.
  • Update docs demo with Mosaic controls, examples, and public API documentation.
  • Update demo page scripts and merge/isolate the legacy v1 demo page in the docs.

Fixed

  • Preserve requested WebP output for image-area exports after partial transparent edge sealing instead of silently returning PNG.
  • Avoid repeated full-image decode/replacement work for every Mosaic pointer point, and stop dropping fast Mosaic clicks while a previous point is still being processed.
  • Use the canvas or control ownerDocument for downsampling canvases, download anchors, DOM bindings, and mask-list rendering so iframe and multi-document integrations work correctly.
  • Reject near-singular Mosaic transform matrices with a practical pixel-scale threshold instead of Number.EPSILON.
  • Remove duplicate wording from the internal error module comments.
  • Make internal merge/crop snapshots fail fast when no canvas is available instead of producing an empty rollback snapshot that loadFromState() silently ignores.
  • Derive new mask maskUid values from the editor-owned maskId so identifiers are deterministic across editor instances, test runs, and page reloads.
  • Keep internal operation tokens module-local and route composite image loads through a private helper instead of carrying bypass tokens through the public loadImage() option shape.
  • Let unexpected idle-guard errors propagate while preserving documented no-op behavior for expected busy, crop, animation, and dispose guards.
  • Settle Fabric animation promises when dispose() aborts an in-flight animation, and drain the animation queue iteratively to avoid recursive promise-chain growth.
  • Freeze the top-level resolved options object and keep runtime layout mode in facade state instead of mutating resolved options.
  • Settle stale auto-scrollbars after Fit/Cover state restores so crop undo does not leave an extra scrollbar when a restored canvas axis exactly matches the visible viewport.
  • Record already-applied history snapshots with HistoryManager.push() instead of using a first-call no-op execute() latch.
  • Remove stale image-load rollback state for container overflow, reject whitespace-bearing base64 data URLs during file export, and avoid nondeterministic active-mask fallback when multiple labels are present.