@fieldnotes/core 0.50.1 → 0.50.2

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
@@ -1123,6 +1123,6 @@ declare class LaserTool implements Tool {
1123
1123
  private notifyOptionsChange;
1124
1124
  }
1125
1125
 
1126
- declare const VERSION = "0.50.1";
1126
+ declare const VERSION = "0.50.2";
1127
1127
 
1128
1128
  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 ExportImageOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, IndexedDBAdapter, type IndexedDBAdapterOptions, LaserTool, type LaserToolOptions, type Layer, LayerManager, LocalStorageAdapter, MeasureTool, type MeasureToolOptions, type Measurement, MemoryAdapter, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, 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, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
package/dist/index.d.ts CHANGED
@@ -1123,6 +1123,6 @@ declare class LaserTool implements Tool {
1123
1123
  private notifyOptionsChange;
1124
1124
  }
1125
1125
 
1126
- declare const VERSION = "0.50.1";
1126
+ declare const VERSION = "0.50.2";
1127
1127
 
1128
1128
  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 ExportImageOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, IndexedDBAdapter, type IndexedDBAdapterOptions, LaserTool, type LaserToolOptions, type Layer, LayerManager, LocalStorageAdapter, MeasureTool, type MeasureToolOptions, type Measurement, MemoryAdapter, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, 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, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
package/dist/index.js CHANGED
@@ -3593,7 +3593,7 @@ function renderSquareGrid(ctx, bounds, cellSize, strokeColor, strokeWidth, opaci
3593
3593
  ctx.save();
3594
3594
  ctx.strokeStyle = strokeColor;
3595
3595
  ctx.lineWidth = strokeWidth;
3596
- ctx.globalAlpha = opacity;
3596
+ ctx.globalAlpha *= opacity;
3597
3597
  ctx.beginPath();
3598
3598
  for (const x of verticals) {
3599
3599
  ctx.moveTo(x, bounds.minY);
@@ -3624,7 +3624,7 @@ function renderHexGrid(ctx, bounds, cellSize, orientation, strokeColor, strokeWi
3624
3624
  ctx.save();
3625
3625
  ctx.strokeStyle = strokeColor;
3626
3626
  ctx.lineWidth = strokeWidth;
3627
- ctx.globalAlpha = opacity;
3627
+ ctx.globalAlpha *= opacity;
3628
3628
  ctx.beginPath();
3629
3629
  if (orientation === "pointy") {
3630
3630
  const hexW = Math.sqrt(3) * cellSize;
@@ -5384,41 +5384,70 @@ async function exportImage(store, options = {}, layerManager) {
5384
5384
  const renderer = new ElementRenderer();
5385
5385
  renderer.setStore(store);
5386
5386
  const grids = [];
5387
- for (const el of visibleElements) {
5388
- if (el.type === "grid") {
5389
- grids.push(el);
5390
- continue;
5391
- }
5387
+ const renderElement = (target, el) => {
5392
5388
  if (el.type === "note") {
5393
5389
  const b = getElementBounds(el);
5394
- withRotation(ctx, el, b ? center(b) : el.position, () => renderNoteOnCanvas(ctx, el));
5395
- continue;
5390
+ withRotation(target, el, b ? center(b) : el.position, () => renderNoteOnCanvas(target, el));
5391
+ return;
5396
5392
  }
5397
5393
  if (el.type === "text") {
5398
5394
  const b = getElementBounds(el);
5399
- withRotation(ctx, el, b ? center(b) : el.position, () => renderTextOnCanvas(ctx, el));
5400
- continue;
5395
+ withRotation(target, el, b ? center(b) : el.position, () => renderTextOnCanvas(target, el));
5396
+ return;
5401
5397
  }
5402
5398
  if (el.type === "html") {
5403
- continue;
5399
+ return;
5404
5400
  }
5405
5401
  if (el.type === "image") {
5406
5402
  const img = imageCache.get(el.id);
5407
5403
  if (img) {
5408
5404
  const b = getElementBounds(el);
5409
5405
  withRotation(
5410
- ctx,
5406
+ target,
5411
5407
  el,
5412
5408
  b ? center(b) : el.position,
5413
- () => ctx.drawImage(img, el.position.x, el.position.y, el.size.w, el.size.h)
5409
+ () => target.drawImage(img, el.position.x, el.position.y, el.size.w, el.size.h)
5414
5410
  );
5415
5411
  }
5412
+ return;
5413
+ }
5414
+ renderer.renderCanvasElement(target, el);
5415
+ };
5416
+ const layerGroups = /* @__PURE__ */ new Map();
5417
+ for (const el of visibleElements) {
5418
+ if (el.type === "grid") {
5419
+ grids.push(el);
5420
+ continue;
5421
+ }
5422
+ const group = layerGroups.get(el.layerId) ?? [];
5423
+ group.push(el);
5424
+ layerGroups.set(el.layerId, group);
5425
+ }
5426
+ for (const [layerId, elements] of layerGroups) {
5427
+ const opacity = layerManager?.getLayer?.(layerId)?.opacity ?? 1;
5428
+ if (opacity === 1) {
5429
+ for (const el of elements) renderElement(ctx, el);
5416
5430
  continue;
5417
5431
  }
5418
- renderer.renderCanvasElement(ctx, el);
5432
+ const layerCanvas = document.createElement("canvas");
5433
+ layerCanvas.width = canvas.width;
5434
+ layerCanvas.height = canvas.height;
5435
+ const layerCtx = layerCanvas.getContext("2d");
5436
+ if (!layerCtx) continue;
5437
+ layerCtx.scale(scale, scale);
5438
+ layerCtx.translate(-bounds.x, -bounds.y);
5439
+ for (const el of elements) renderElement(layerCtx, el);
5440
+ ctx.save();
5441
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
5442
+ ctx.globalAlpha = opacity;
5443
+ ctx.drawImage(layerCanvas, 0, 0);
5444
+ ctx.restore();
5419
5445
  }
5420
5446
  for (const grid of grids) {
5447
+ ctx.save();
5448
+ ctx.globalAlpha = layerManager?.getLayer?.(grid.layerId)?.opacity ?? 1;
5421
5449
  renderGridForBounds(ctx, grid, bounds);
5450
+ ctx.restore();
5422
5451
  }
5423
5452
  return new Promise((resolve) => {
5424
5453
  canvas.toBlob((blob) => resolve(blob), "image/png");
@@ -5738,11 +5767,19 @@ async function exportSvg(store, options = {}, layerManager) {
5738
5767
  if (options.background) {
5739
5768
  body += `<rect x="${n(bounds.x)}" y="${n(bounds.y)}" width="${n(bounds.w)}" height="${n(bounds.h)}" fill="${esc(options.background)}" />`;
5740
5769
  }
5770
+ const layerBodies = /* @__PURE__ */ new Map();
5741
5771
  for (const el of visibleElements) {
5742
- body += emitElement(el, imageDataUris, rasterScale, firstGrid, store);
5772
+ const emitted = emitElement(el, imageDataUris, rasterScale, firstGrid, store);
5773
+ layerBodies.set(el.layerId, (layerBodies.get(el.layerId) ?? "") + emitted);
5774
+ }
5775
+ for (const [layerId, emitted] of layerBodies) {
5776
+ const opacity = layerManager?.getLayer?.(layerId)?.opacity ?? 1;
5777
+ body += opacity === 1 || emitted === "" ? emitted : `<g opacity="${n(opacity)}">${emitted}</g>`;
5743
5778
  }
5744
5779
  for (const grid of grids) {
5745
- body += emitGrid(grid, bounds);
5780
+ const emitted = emitGrid(grid, bounds);
5781
+ const opacity = layerManager?.getLayer?.(grid.layerId)?.opacity ?? 1;
5782
+ body += opacity === 1 ? emitted : `<g opacity="${n(opacity)}">${emitted}</g>`;
5746
5783
  }
5747
5784
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${n(bounds.w)}" height="${n(bounds.h)}" viewBox="${n(bounds.x)} ${n(bounds.y)} ${n(bounds.w)} ${n(bounds.h)}">${body}</svg>`;
5748
5785
  }
@@ -6061,6 +6098,7 @@ var DomNodeManager = class {
6061
6098
  getVersion;
6062
6099
  lastSyncedVersion = /* @__PURE__ */ new Map();
6063
6100
  lastSyncedZIndex = /* @__PURE__ */ new Map();
6101
+ lastSyncedOpacity = /* @__PURE__ */ new Map();
6064
6102
  constructor(deps) {
6065
6103
  this.domLayer = deps.domLayer;
6066
6104
  this.onEditRequest = deps.onEditRequest;
@@ -6080,6 +6118,7 @@ var DomNodeManager = class {
6080
6118
  this.htmlContent.delete(elementId);
6081
6119
  this.lastSyncedVersion.delete(elementId);
6082
6120
  this.lastSyncedZIndex.delete(elementId);
6121
+ this.lastSyncedOpacity.delete(elementId);
6083
6122
  const node = this.domNodes.get(elementId);
6084
6123
  if (!node) return;
6085
6124
  while (node.firstChild) {
@@ -6087,7 +6126,7 @@ var DomNodeManager = class {
6087
6126
  }
6088
6127
  delete node.dataset["initialized"];
6089
6128
  }
6090
- syncDomNode(element, zIndex = 0) {
6129
+ syncDomNode(element, zIndex = 0, opacity = 1) {
6091
6130
  let node = this.domNodes.get(element.id);
6092
6131
  if (!node) {
6093
6132
  node = document.createElement("div");
@@ -6102,13 +6141,15 @@ var DomNodeManager = class {
6102
6141
  const currentVersion = this.getVersion(element.id);
6103
6142
  const lastVersion = this.lastSyncedVersion.get(element.id);
6104
6143
  const lastZ = this.lastSyncedZIndex.get(element.id);
6105
- if (lastVersion === currentVersion && lastZ === zIndex) {
6144
+ const lastOpacity = this.lastSyncedOpacity.get(element.id);
6145
+ if (lastVersion === currentVersion && lastZ === zIndex && lastOpacity === opacity) {
6106
6146
  return;
6107
6147
  }
6108
6148
  }
6109
6149
  if (this.getVersion) {
6110
6150
  this.lastSyncedVersion.set(element.id, this.getVersion(element.id));
6111
6151
  this.lastSyncedZIndex.set(element.id, zIndex);
6152
+ this.lastSyncedOpacity.set(element.id, opacity);
6112
6153
  }
6113
6154
  const size = "size" in element ? element.size : null;
6114
6155
  Object.assign(node.style, {
@@ -6118,6 +6159,7 @@ var DomNodeManager = class {
6118
6159
  width: size ? `${size.w}px` : "auto",
6119
6160
  height: size ? `${size.h}px` : "auto",
6120
6161
  zIndex: String(zIndex),
6162
+ opacity: String(opacity),
6121
6163
  transform: element.rotation ? `rotate(${element.rotation}rad)` : "",
6122
6164
  transformOrigin: "50% 50%"
6123
6165
  });
@@ -6131,6 +6173,7 @@ var DomNodeManager = class {
6131
6173
  this.htmlContent.delete(id);
6132
6174
  this.lastSyncedVersion.delete(id);
6133
6175
  this.lastSyncedZIndex.delete(id);
6176
+ this.lastSyncedOpacity.delete(id);
6134
6177
  const node = this.domNodes.get(id);
6135
6178
  if (node) {
6136
6179
  node.remove();
@@ -6143,6 +6186,7 @@ var DomNodeManager = class {
6143
6186
  this.htmlContent.clear();
6144
6187
  this.lastSyncedVersion.clear();
6145
6188
  this.lastSyncedZIndex.clear();
6189
+ this.lastSyncedOpacity.clear();
6146
6190
  }
6147
6191
  reattachHtmlContent(store) {
6148
6192
  for (const el of store.getElementsByType("html")) {
@@ -6381,11 +6425,12 @@ var RenderLoop = class {
6381
6425
  }
6382
6426
  markAllLayersDirty() {
6383
6427
  this.layerCache.markAllDirty();
6428
+ this.gridCacheDirty = true;
6384
6429
  }
6385
6430
  getStats() {
6386
6431
  return this.stats.getSnapshot();
6387
6432
  }
6388
- compositeLayerCache(ctx, layerId) {
6433
+ compositeLayerCache(ctx, layerId, opacity) {
6389
6434
  const cached = this.layerCache.getCanvas(layerId);
6390
6435
  const offset = this.marginViewport.compositeOffset(
6391
6436
  this.camera.position.x,
@@ -6393,6 +6438,7 @@ var RenderLoop = class {
6393
6438
  );
6394
6439
  ctx.save();
6395
6440
  ctx.setTransform(1, 0, 0, 1, 0, 0);
6441
+ ctx.globalAlpha = opacity;
6396
6442
  ctx.drawImage(cached, offset.x, offset.y);
6397
6443
  ctx.restore();
6398
6444
  }
@@ -6472,11 +6518,12 @@ var RenderLoop = class {
6472
6518
  continue;
6473
6519
  }
6474
6520
  if (this.renderer.isDomElement(element)) {
6521
+ const layerOpacity = this.layerManager.getLayer?.(element.layerId)?.opacity ?? 1;
6475
6522
  const elBounds = getElementBounds(element);
6476
6523
  if (elBounds && !boundsIntersect(elBounds, cullingRect)) {
6477
6524
  this.domNodeManager.hideDomNode(element.id);
6478
6525
  } else {
6479
- this.domNodeManager.syncDomNode(element, domZIndex++);
6526
+ this.domNodeManager.syncDomNode(element, domZIndex++, layerOpacity);
6480
6527
  }
6481
6528
  continue;
6482
6529
  }
@@ -6493,15 +6540,16 @@ var RenderLoop = class {
6493
6540
  }
6494
6541
  for (const [layerId, elements] of this.layerGroups) {
6495
6542
  const isActiveDrawingLayer = layerId === this.activeDrawingLayerId;
6543
+ const layerOpacity = this.layerManager.getLayer?.(layerId)?.opacity ?? 1;
6496
6544
  if (!this.layerCache.isDirty(layerId)) {
6497
6545
  const compT0 = performance.now();
6498
- this.compositeLayerCache(ctx, layerId);
6546
+ this.compositeLayerCache(ctx, layerId, layerOpacity);
6499
6547
  compositeMs += performance.now() - compT0;
6500
6548
  continue;
6501
6549
  }
6502
6550
  if (isActiveDrawingLayer) {
6503
6551
  const compT0 = performance.now();
6504
- this.compositeLayerCache(ctx, layerId);
6552
+ this.compositeLayerCache(ctx, layerId, layerOpacity);
6505
6553
  compositeMs += performance.now() - compT0;
6506
6554
  continue;
6507
6555
  }
@@ -6521,7 +6569,7 @@ var RenderLoop = class {
6521
6569
  this.layerCache.markClean(layerId);
6522
6570
  layersMs += performance.now() - layerT0;
6523
6571
  const compT0 = performance.now();
6524
- this.compositeLayerCache(ctx, layerId);
6572
+ this.compositeLayerCache(ctx, layerId, layerOpacity);
6525
6573
  compositeMs += performance.now() - compT0;
6526
6574
  }
6527
6575
  }
@@ -6545,7 +6593,10 @@ var RenderLoop = class {
6545
6593
  this.marginViewport.applyRenderTransform(gc);
6546
6594
  try {
6547
6595
  for (const grid of gridElements) {
6596
+ gc.save();
6597
+ gc.globalAlpha = this.layerManager.getLayer?.(grid.layerId)?.opacity ?? 1;
6548
6598
  this.renderer.renderCanvasElement(gc, grid);
6599
+ gc.restore();
6549
6600
  }
6550
6601
  } finally {
6551
6602
  gc.restore();
@@ -6566,7 +6617,10 @@ var RenderLoop = class {
6566
6617
  ctx.restore();
6567
6618
  } else {
6568
6619
  for (const grid of gridElements) {
6620
+ ctx.save();
6621
+ ctx.globalAlpha = this.layerManager.getLayer?.(grid.layerId)?.opacity ?? 1;
6569
6622
  this.renderer.renderCanvasElement(ctx, grid);
6623
+ ctx.restore();
6570
6624
  }
6571
6625
  }
6572
6626
  gridMs = performance.now() - gridT0;
@@ -7471,6 +7525,7 @@ var Viewport = class {
7471
7525
  ];
7472
7526
  this.layerManager.on("change", () => {
7473
7527
  this.toolContext.activeLayerId = this.layerManager.activeLayerId;
7528
+ this.renderLoop.markAllLayersDirty();
7474
7529
  this.minimap?.scheduleDraw();
7475
7530
  this.requestRender();
7476
7531
  });
@@ -10534,7 +10589,7 @@ var LaserTool = class {
10534
10589
  };
10535
10590
 
10536
10591
  // src/index.ts
10537
- var VERSION = "0.50.1";
10592
+ var VERSION = "0.50.2";
10538
10593
  export {
10539
10594
  ArrowTool,
10540
10595
  AutoSave,