@fieldnotes/core 0.58.0 → 0.59.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/dist/index.d.cts CHANGED
@@ -469,6 +469,32 @@ interface ExportImageOptions extends ExportResourceOptions, HtmlExportOptions {
469
469
  padding?: number;
470
470
  background?: string;
471
471
  filter?: (element: CanvasElement) => boolean;
472
+ /**
473
+ * Optional world-space crop. When set it replaces the computed content
474
+ * bounds; `padding` still applies around it. Elements outside the region
475
+ * clip naturally. A region export with no intersecting elements still
476
+ * produces a background-filled image.
477
+ */
478
+ region?: {
479
+ x: number;
480
+ y: number;
481
+ w: number;
482
+ h: number;
483
+ };
484
+ /**
485
+ * Output encoding. Defaults to 'png'. JPEG output is opaque — a transparent
486
+ * `background` renders as black; keep the default `#ffffff` (or any opaque color)
487
+ * for JPEG exports.
488
+ */
489
+ format?: 'png' | 'jpeg';
490
+ /** Encoder quality in (0, 1]. Only meaningful for 'jpeg'. */
491
+ quality?: number;
492
+ /**
493
+ * 'exact' (default) throws when scale × bounds exceeds maxDimension/maxPixels.
494
+ * 'fit' reduces the effective scale to the largest value that satisfies both
495
+ * caps (never above the requested scale).
496
+ */
497
+ scaleMode?: 'exact' | 'fit';
472
498
  }
473
499
  type ExportAssetErrorReason = 'load' | 'timeout' | 'encode';
474
500
  interface ExportAssetError {
@@ -1729,6 +1755,6 @@ declare class TemplateTool implements Tool {
1729
1755
  private notifyOptionsChange;
1730
1756
  }
1731
1757
 
1732
- declare const VERSION = "0.58.0";
1758
+ declare const VERSION = "0.59.0";
1733
1759
 
1734
1760
  export { type ActiveFormats, type AlignEdge, type ArrowElement, type ArrowStrokeStyle, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, type DistributeAxis, type ElementChangeMeta, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportAssetError, type ExportAssetErrorReason, type ExportImageOptions, type ExportResourceOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type HtmlExportError, type HtmlExportErrorReason, type HtmlExportOptions, type HtmlExportRenderer, type ImageElement, ImageTool, type ImageToolOptions, IndexedDBAdapter, type IndexedDBAdapterOptions, LASER_TRAIL_PRESENCE_KIND, LaserTool, type LaserToolOptions, type LaserTrailEmission, type LaserTrailPresence, type Layer, LayerManager, LocalStorageAdapter, MEASURE_PRESENCE_KIND, type MeasureEmission, type MeasurePresence, MeasureTool, type MeasureToolOptions, type Measurement, MemoryAdapter, MinimapController, type MinimapControllerOptions, type NoteElement, NoteTool, type NoteToolOptions, type OverlayRenderer, PING_PRESENCE_KIND, PencilTool, type PencilToolOptions, type PingEmission, PingInput, type PingInputHost, type PingInputOptions, type PingPresence, PingTool, type PingToolOptions, type Point, type PointerState, RemoteLaserOverlay, type RemoteLaserOverlayHost, type RemoteLaserOverlayOptions, RemoteMeasureOverlay, type RemoteMeasureOverlayHost, type RemoteMeasureOverlayOptions, RemotePingOverlay, type RemotePingOverlayHost, type RemotePingOverlayOptions, type RenderStatsSnapshot, type RotateDirection, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StorageAdapter, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateRenderStyle, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, exportSvg, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInRectangle, getHexCellsInSquare, getHexDistance, isLaserTrailPresence, isMeasurePresence, isNearBezier, isPingPresence, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toLaserTrailPresence, toMeasurePresence, toPingPresence, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
package/dist/index.d.ts CHANGED
@@ -469,6 +469,32 @@ interface ExportImageOptions extends ExportResourceOptions, HtmlExportOptions {
469
469
  padding?: number;
470
470
  background?: string;
471
471
  filter?: (element: CanvasElement) => boolean;
472
+ /**
473
+ * Optional world-space crop. When set it replaces the computed content
474
+ * bounds; `padding` still applies around it. Elements outside the region
475
+ * clip naturally. A region export with no intersecting elements still
476
+ * produces a background-filled image.
477
+ */
478
+ region?: {
479
+ x: number;
480
+ y: number;
481
+ w: number;
482
+ h: number;
483
+ };
484
+ /**
485
+ * Output encoding. Defaults to 'png'. JPEG output is opaque — a transparent
486
+ * `background` renders as black; keep the default `#ffffff` (or any opaque color)
487
+ * for JPEG exports.
488
+ */
489
+ format?: 'png' | 'jpeg';
490
+ /** Encoder quality in (0, 1]. Only meaningful for 'jpeg'. */
491
+ quality?: number;
492
+ /**
493
+ * 'exact' (default) throws when scale × bounds exceeds maxDimension/maxPixels.
494
+ * 'fit' reduces the effective scale to the largest value that satisfies both
495
+ * caps (never above the requested scale).
496
+ */
497
+ scaleMode?: 'exact' | 'fit';
472
498
  }
473
499
  type ExportAssetErrorReason = 'load' | 'timeout' | 'encode';
474
500
  interface ExportAssetError {
@@ -1729,6 +1755,6 @@ declare class TemplateTool implements Tool {
1729
1755
  private notifyOptionsChange;
1730
1756
  }
1731
1757
 
1732
- declare const VERSION = "0.58.0";
1758
+ declare const VERSION = "0.59.0";
1733
1759
 
1734
1760
  export { type ActiveFormats, type AlignEdge, type ArrowElement, type ArrowStrokeStyle, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, type DistributeAxis, type ElementChangeMeta, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportAssetError, type ExportAssetErrorReason, type ExportImageOptions, type ExportResourceOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type HtmlExportError, type HtmlExportErrorReason, type HtmlExportOptions, type HtmlExportRenderer, type ImageElement, ImageTool, type ImageToolOptions, IndexedDBAdapter, type IndexedDBAdapterOptions, LASER_TRAIL_PRESENCE_KIND, LaserTool, type LaserToolOptions, type LaserTrailEmission, type LaserTrailPresence, type Layer, LayerManager, LocalStorageAdapter, MEASURE_PRESENCE_KIND, type MeasureEmission, type MeasurePresence, MeasureTool, type MeasureToolOptions, type Measurement, MemoryAdapter, MinimapController, type MinimapControllerOptions, type NoteElement, NoteTool, type NoteToolOptions, type OverlayRenderer, PING_PRESENCE_KIND, PencilTool, type PencilToolOptions, type PingEmission, PingInput, type PingInputHost, type PingInputOptions, type PingPresence, PingTool, type PingToolOptions, type Point, type PointerState, RemoteLaserOverlay, type RemoteLaserOverlayHost, type RemoteLaserOverlayOptions, RemoteMeasureOverlay, type RemoteMeasureOverlayHost, type RemoteMeasureOverlayOptions, RemotePingOverlay, type RemotePingOverlayHost, type RemotePingOverlayOptions, type RenderStatsSnapshot, type RotateDirection, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StorageAdapter, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateRenderStyle, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, exportSvg, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInRectangle, getHexCellsInSquare, getHexDistance, isLaserTrailPresence, isMeasurePresence, isNearBezier, isPingPresence, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toLaserTrailPresence, toMeasurePresence, toPingPresence, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
package/dist/index.js CHANGED
@@ -5753,6 +5753,19 @@ function computeBounds(elements, padding) {
5753
5753
  h: maxY - minY + padding * 2
5754
5754
  };
5755
5755
  }
5756
+ function resolveExportBounds(region, elements, padding) {
5757
+ if (!region) return computeBounds(elements, padding);
5758
+ const finite = Number.isFinite(region.x) && Number.isFinite(region.y) && Number.isFinite(region.w) && Number.isFinite(region.h);
5759
+ if (!finite || region.w <= 0 || region.h <= 0) {
5760
+ throw new RangeError("region must have finite coordinates and positive w/h");
5761
+ }
5762
+ return {
5763
+ x: region.x - padding,
5764
+ y: region.y - padding,
5765
+ w: region.w + padding * 2,
5766
+ h: region.h + padding * 2
5767
+ };
5768
+ }
5756
5769
  function renderGridForBounds(ctx, grid, bounds) {
5757
5770
  const visibleBounds = {
5758
5771
  minX: bounds.x,
@@ -5795,6 +5808,29 @@ function nonNegativeOption(value, fallback, name) {
5795
5808
  }
5796
5809
  return resolved;
5797
5810
  }
5811
+ function fitExportScale(bounds, requestedScale, options) {
5812
+ const maxDimension = positiveOption(options.maxDimension, DEFAULT_MAX_DIMENSION, "maxDimension");
5813
+ const maxPixels = positiveOption(options.maxPixels, DEFAULT_MAX_PIXELS, "maxPixels");
5814
+ const fits = (scale) => {
5815
+ const w = Math.ceil(bounds.w * scale);
5816
+ const h = Math.ceil(bounds.h * scale);
5817
+ return w <= maxDimension && h <= maxDimension && w * h <= maxPixels;
5818
+ };
5819
+ if (fits(requestedScale)) return requestedScale;
5820
+ const analytical = Math.min(
5821
+ maxDimension / Math.max(bounds.w, bounds.h),
5822
+ Math.sqrt(maxPixels) / Math.sqrt(bounds.w) / Math.sqrt(bounds.h)
5823
+ );
5824
+ let hi = Math.min(requestedScale, analytical);
5825
+ if (fits(hi)) return hi;
5826
+ let lo = 0;
5827
+ for (let i = 0; i < 40; i++) {
5828
+ const mid = (lo + hi) / 2;
5829
+ if (fits(mid)) lo = mid;
5830
+ else hi = mid;
5831
+ }
5832
+ return lo;
5833
+ }
5798
5834
  function assertExportSize(width, height, options) {
5799
5835
  const maxDimension = positiveOption(options.maxDimension, DEFAULT_MAX_DIMENSION, "maxDimension");
5800
5836
  const maxPixels = positiveOption(options.maxPixels, DEFAULT_MAX_PIXELS, "maxPixels");
@@ -5869,10 +5905,23 @@ function loadImages(elements, options = {}) {
5869
5905
  });
5870
5906
  }
5871
5907
  async function exportImage(store, options = {}, layerManager) {
5872
- const scale = positiveOption(options.scale, 2, "scale");
5908
+ const requestedScale = positiveOption(options.scale, 2, "scale");
5909
+ const scaleMode = options.scaleMode ?? "exact";
5910
+ if (scaleMode !== "exact" && scaleMode !== "fit") {
5911
+ throw new RangeError(`scaleMode must be 'exact' or 'fit'`);
5912
+ }
5873
5913
  const padding = nonNegativeOption(options.padding, 0, "padding");
5874
5914
  validateExportResourceOptions(options);
5875
5915
  validateHtmlExportOptions(options);
5916
+ const format = options.format ?? "png";
5917
+ if (format !== "png" && format !== "jpeg") {
5918
+ throw new RangeError(`format must be 'png' or 'jpeg'`);
5919
+ }
5920
+ if (options.quality !== void 0) {
5921
+ if (!Number.isFinite(options.quality) || options.quality <= 0 || options.quality > 1) {
5922
+ throw new RangeError("quality must be a finite number in (0, 1]");
5923
+ }
5924
+ }
5876
5925
  const background = options.background ?? "#ffffff";
5877
5926
  const filter = options.filter;
5878
5927
  const allElements = store.getAll();
@@ -5880,8 +5929,9 @@ async function exportImage(store, options = {}, layerManager) {
5880
5929
  if (filter) {
5881
5930
  visibleElements = visibleElements.filter(filter);
5882
5931
  }
5883
- const bounds = computeBounds(visibleElements, padding);
5932
+ const bounds = resolveExportBounds(options.region, visibleElements, padding);
5884
5933
  if (!bounds) return null;
5934
+ const scale = scaleMode === "fit" ? fitExportScale(bounds, requestedScale, options) : requestedScale;
5885
5935
  const width = Math.ceil(bounds.w * scale);
5886
5936
  const height = Math.ceil(bounds.h * scale);
5887
5937
  assertExportSize(width, height, options);
@@ -5983,8 +6033,9 @@ async function exportImage(store, options = {}, layerManager) {
5983
6033
  renderGridForBounds(ctx, grid, bounds);
5984
6034
  ctx.restore();
5985
6035
  }
6036
+ const mimeType = format === "jpeg" ? "image/jpeg" : "image/png";
5986
6037
  return new Promise((resolve) => {
5987
- canvas.toBlob((blob) => resolve(blob), "image/png");
6038
+ canvas.toBlob((blob) => resolve(blob), mimeType, options.quality);
5988
6039
  });
5989
6040
  }
5990
6041
 
@@ -12264,7 +12315,7 @@ var PingTool = class {
12264
12315
  };
12265
12316
 
12266
12317
  // src/index.ts
12267
- var VERSION = "0.58.0";
12318
+ var VERSION = "0.59.0";
12268
12319
  export {
12269
12320
  ArrowTool,
12270
12321
  AutoSave,