@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.cjs CHANGED
@@ -3680,7 +3680,7 @@ function renderSquareGrid(ctx, bounds, cellSize, strokeColor, strokeWidth, opaci
3680
3680
  ctx.save();
3681
3681
  ctx.strokeStyle = strokeColor;
3682
3682
  ctx.lineWidth = strokeWidth;
3683
- ctx.globalAlpha = opacity;
3683
+ ctx.globalAlpha *= opacity;
3684
3684
  ctx.beginPath();
3685
3685
  for (const x of verticals) {
3686
3686
  ctx.moveTo(x, bounds.minY);
@@ -3711,7 +3711,7 @@ function renderHexGrid(ctx, bounds, cellSize, orientation, strokeColor, strokeWi
3711
3711
  ctx.save();
3712
3712
  ctx.strokeStyle = strokeColor;
3713
3713
  ctx.lineWidth = strokeWidth;
3714
- ctx.globalAlpha = opacity;
3714
+ ctx.globalAlpha *= opacity;
3715
3715
  ctx.beginPath();
3716
3716
  if (orientation === "pointy") {
3717
3717
  const hexW = Math.sqrt(3) * cellSize;
@@ -5471,41 +5471,70 @@ async function exportImage(store, options = {}, layerManager) {
5471
5471
  const renderer = new ElementRenderer();
5472
5472
  renderer.setStore(store);
5473
5473
  const grids = [];
5474
- for (const el of visibleElements) {
5475
- if (el.type === "grid") {
5476
- grids.push(el);
5477
- continue;
5478
- }
5474
+ const renderElement = (target, el) => {
5479
5475
  if (el.type === "note") {
5480
5476
  const b = getElementBounds(el);
5481
- withRotation(ctx, el, b ? center(b) : el.position, () => renderNoteOnCanvas(ctx, el));
5482
- continue;
5477
+ withRotation(target, el, b ? center(b) : el.position, () => renderNoteOnCanvas(target, el));
5478
+ return;
5483
5479
  }
5484
5480
  if (el.type === "text") {
5485
5481
  const b = getElementBounds(el);
5486
- withRotation(ctx, el, b ? center(b) : el.position, () => renderTextOnCanvas(ctx, el));
5487
- continue;
5482
+ withRotation(target, el, b ? center(b) : el.position, () => renderTextOnCanvas(target, el));
5483
+ return;
5488
5484
  }
5489
5485
  if (el.type === "html") {
5490
- continue;
5486
+ return;
5491
5487
  }
5492
5488
  if (el.type === "image") {
5493
5489
  const img = imageCache.get(el.id);
5494
5490
  if (img) {
5495
5491
  const b = getElementBounds(el);
5496
5492
  withRotation(
5497
- ctx,
5493
+ target,
5498
5494
  el,
5499
5495
  b ? center(b) : el.position,
5500
- () => ctx.drawImage(img, el.position.x, el.position.y, el.size.w, el.size.h)
5496
+ () => target.drawImage(img, el.position.x, el.position.y, el.size.w, el.size.h)
5501
5497
  );
5502
5498
  }
5499
+ return;
5500
+ }
5501
+ renderer.renderCanvasElement(target, el);
5502
+ };
5503
+ const layerGroups = /* @__PURE__ */ new Map();
5504
+ for (const el of visibleElements) {
5505
+ if (el.type === "grid") {
5506
+ grids.push(el);
5507
+ continue;
5508
+ }
5509
+ const group = layerGroups.get(el.layerId) ?? [];
5510
+ group.push(el);
5511
+ layerGroups.set(el.layerId, group);
5512
+ }
5513
+ for (const [layerId, elements] of layerGroups) {
5514
+ const opacity = layerManager?.getLayer?.(layerId)?.opacity ?? 1;
5515
+ if (opacity === 1) {
5516
+ for (const el of elements) renderElement(ctx, el);
5503
5517
  continue;
5504
5518
  }
5505
- renderer.renderCanvasElement(ctx, el);
5519
+ const layerCanvas = document.createElement("canvas");
5520
+ layerCanvas.width = canvas.width;
5521
+ layerCanvas.height = canvas.height;
5522
+ const layerCtx = layerCanvas.getContext("2d");
5523
+ if (!layerCtx) continue;
5524
+ layerCtx.scale(scale, scale);
5525
+ layerCtx.translate(-bounds.x, -bounds.y);
5526
+ for (const el of elements) renderElement(layerCtx, el);
5527
+ ctx.save();
5528
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
5529
+ ctx.globalAlpha = opacity;
5530
+ ctx.drawImage(layerCanvas, 0, 0);
5531
+ ctx.restore();
5506
5532
  }
5507
5533
  for (const grid of grids) {
5534
+ ctx.save();
5535
+ ctx.globalAlpha = layerManager?.getLayer?.(grid.layerId)?.opacity ?? 1;
5508
5536
  renderGridForBounds(ctx, grid, bounds);
5537
+ ctx.restore();
5509
5538
  }
5510
5539
  return new Promise((resolve) => {
5511
5540
  canvas.toBlob((blob) => resolve(blob), "image/png");
@@ -5825,11 +5854,19 @@ async function exportSvg(store, options = {}, layerManager) {
5825
5854
  if (options.background) {
5826
5855
  body += `<rect x="${n(bounds.x)}" y="${n(bounds.y)}" width="${n(bounds.w)}" height="${n(bounds.h)}" fill="${esc(options.background)}" />`;
5827
5856
  }
5857
+ const layerBodies = /* @__PURE__ */ new Map();
5828
5858
  for (const el of visibleElements) {
5829
- body += emitElement(el, imageDataUris, rasterScale, firstGrid, store);
5859
+ const emitted = emitElement(el, imageDataUris, rasterScale, firstGrid, store);
5860
+ layerBodies.set(el.layerId, (layerBodies.get(el.layerId) ?? "") + emitted);
5861
+ }
5862
+ for (const [layerId, emitted] of layerBodies) {
5863
+ const opacity = layerManager?.getLayer?.(layerId)?.opacity ?? 1;
5864
+ body += opacity === 1 || emitted === "" ? emitted : `<g opacity="${n(opacity)}">${emitted}</g>`;
5830
5865
  }
5831
5866
  for (const grid of grids) {
5832
- body += emitGrid(grid, bounds);
5867
+ const emitted = emitGrid(grid, bounds);
5868
+ const opacity = layerManager?.getLayer?.(grid.layerId)?.opacity ?? 1;
5869
+ body += opacity === 1 ? emitted : `<g opacity="${n(opacity)}">${emitted}</g>`;
5833
5870
  }
5834
5871
  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>`;
5835
5872
  }
@@ -6148,6 +6185,7 @@ var DomNodeManager = class {
6148
6185
  getVersion;
6149
6186
  lastSyncedVersion = /* @__PURE__ */ new Map();
6150
6187
  lastSyncedZIndex = /* @__PURE__ */ new Map();
6188
+ lastSyncedOpacity = /* @__PURE__ */ new Map();
6151
6189
  constructor(deps) {
6152
6190
  this.domLayer = deps.domLayer;
6153
6191
  this.onEditRequest = deps.onEditRequest;
@@ -6167,6 +6205,7 @@ var DomNodeManager = class {
6167
6205
  this.htmlContent.delete(elementId);
6168
6206
  this.lastSyncedVersion.delete(elementId);
6169
6207
  this.lastSyncedZIndex.delete(elementId);
6208
+ this.lastSyncedOpacity.delete(elementId);
6170
6209
  const node = this.domNodes.get(elementId);
6171
6210
  if (!node) return;
6172
6211
  while (node.firstChild) {
@@ -6174,7 +6213,7 @@ var DomNodeManager = class {
6174
6213
  }
6175
6214
  delete node.dataset["initialized"];
6176
6215
  }
6177
- syncDomNode(element, zIndex = 0) {
6216
+ syncDomNode(element, zIndex = 0, opacity = 1) {
6178
6217
  let node = this.domNodes.get(element.id);
6179
6218
  if (!node) {
6180
6219
  node = document.createElement("div");
@@ -6189,13 +6228,15 @@ var DomNodeManager = class {
6189
6228
  const currentVersion = this.getVersion(element.id);
6190
6229
  const lastVersion = this.lastSyncedVersion.get(element.id);
6191
6230
  const lastZ = this.lastSyncedZIndex.get(element.id);
6192
- if (lastVersion === currentVersion && lastZ === zIndex) {
6231
+ const lastOpacity = this.lastSyncedOpacity.get(element.id);
6232
+ if (lastVersion === currentVersion && lastZ === zIndex && lastOpacity === opacity) {
6193
6233
  return;
6194
6234
  }
6195
6235
  }
6196
6236
  if (this.getVersion) {
6197
6237
  this.lastSyncedVersion.set(element.id, this.getVersion(element.id));
6198
6238
  this.lastSyncedZIndex.set(element.id, zIndex);
6239
+ this.lastSyncedOpacity.set(element.id, opacity);
6199
6240
  }
6200
6241
  const size = "size" in element ? element.size : null;
6201
6242
  Object.assign(node.style, {
@@ -6205,6 +6246,7 @@ var DomNodeManager = class {
6205
6246
  width: size ? `${size.w}px` : "auto",
6206
6247
  height: size ? `${size.h}px` : "auto",
6207
6248
  zIndex: String(zIndex),
6249
+ opacity: String(opacity),
6208
6250
  transform: element.rotation ? `rotate(${element.rotation}rad)` : "",
6209
6251
  transformOrigin: "50% 50%"
6210
6252
  });
@@ -6218,6 +6260,7 @@ var DomNodeManager = class {
6218
6260
  this.htmlContent.delete(id);
6219
6261
  this.lastSyncedVersion.delete(id);
6220
6262
  this.lastSyncedZIndex.delete(id);
6263
+ this.lastSyncedOpacity.delete(id);
6221
6264
  const node = this.domNodes.get(id);
6222
6265
  if (node) {
6223
6266
  node.remove();
@@ -6230,6 +6273,7 @@ var DomNodeManager = class {
6230
6273
  this.htmlContent.clear();
6231
6274
  this.lastSyncedVersion.clear();
6232
6275
  this.lastSyncedZIndex.clear();
6276
+ this.lastSyncedOpacity.clear();
6233
6277
  }
6234
6278
  reattachHtmlContent(store) {
6235
6279
  for (const el of store.getElementsByType("html")) {
@@ -6468,11 +6512,12 @@ var RenderLoop = class {
6468
6512
  }
6469
6513
  markAllLayersDirty() {
6470
6514
  this.layerCache.markAllDirty();
6515
+ this.gridCacheDirty = true;
6471
6516
  }
6472
6517
  getStats() {
6473
6518
  return this.stats.getSnapshot();
6474
6519
  }
6475
- compositeLayerCache(ctx, layerId) {
6520
+ compositeLayerCache(ctx, layerId, opacity) {
6476
6521
  const cached = this.layerCache.getCanvas(layerId);
6477
6522
  const offset = this.marginViewport.compositeOffset(
6478
6523
  this.camera.position.x,
@@ -6480,6 +6525,7 @@ var RenderLoop = class {
6480
6525
  );
6481
6526
  ctx.save();
6482
6527
  ctx.setTransform(1, 0, 0, 1, 0, 0);
6528
+ ctx.globalAlpha = opacity;
6483
6529
  ctx.drawImage(cached, offset.x, offset.y);
6484
6530
  ctx.restore();
6485
6531
  }
@@ -6559,11 +6605,12 @@ var RenderLoop = class {
6559
6605
  continue;
6560
6606
  }
6561
6607
  if (this.renderer.isDomElement(element)) {
6608
+ const layerOpacity = this.layerManager.getLayer?.(element.layerId)?.opacity ?? 1;
6562
6609
  const elBounds = getElementBounds(element);
6563
6610
  if (elBounds && !boundsIntersect(elBounds, cullingRect)) {
6564
6611
  this.domNodeManager.hideDomNode(element.id);
6565
6612
  } else {
6566
- this.domNodeManager.syncDomNode(element, domZIndex++);
6613
+ this.domNodeManager.syncDomNode(element, domZIndex++, layerOpacity);
6567
6614
  }
6568
6615
  continue;
6569
6616
  }
@@ -6580,15 +6627,16 @@ var RenderLoop = class {
6580
6627
  }
6581
6628
  for (const [layerId, elements] of this.layerGroups) {
6582
6629
  const isActiveDrawingLayer = layerId === this.activeDrawingLayerId;
6630
+ const layerOpacity = this.layerManager.getLayer?.(layerId)?.opacity ?? 1;
6583
6631
  if (!this.layerCache.isDirty(layerId)) {
6584
6632
  const compT0 = performance.now();
6585
- this.compositeLayerCache(ctx, layerId);
6633
+ this.compositeLayerCache(ctx, layerId, layerOpacity);
6586
6634
  compositeMs += performance.now() - compT0;
6587
6635
  continue;
6588
6636
  }
6589
6637
  if (isActiveDrawingLayer) {
6590
6638
  const compT0 = performance.now();
6591
- this.compositeLayerCache(ctx, layerId);
6639
+ this.compositeLayerCache(ctx, layerId, layerOpacity);
6592
6640
  compositeMs += performance.now() - compT0;
6593
6641
  continue;
6594
6642
  }
@@ -6608,7 +6656,7 @@ var RenderLoop = class {
6608
6656
  this.layerCache.markClean(layerId);
6609
6657
  layersMs += performance.now() - layerT0;
6610
6658
  const compT0 = performance.now();
6611
- this.compositeLayerCache(ctx, layerId);
6659
+ this.compositeLayerCache(ctx, layerId, layerOpacity);
6612
6660
  compositeMs += performance.now() - compT0;
6613
6661
  }
6614
6662
  }
@@ -6632,7 +6680,10 @@ var RenderLoop = class {
6632
6680
  this.marginViewport.applyRenderTransform(gc);
6633
6681
  try {
6634
6682
  for (const grid of gridElements) {
6683
+ gc.save();
6684
+ gc.globalAlpha = this.layerManager.getLayer?.(grid.layerId)?.opacity ?? 1;
6635
6685
  this.renderer.renderCanvasElement(gc, grid);
6686
+ gc.restore();
6636
6687
  }
6637
6688
  } finally {
6638
6689
  gc.restore();
@@ -6653,7 +6704,10 @@ var RenderLoop = class {
6653
6704
  ctx.restore();
6654
6705
  } else {
6655
6706
  for (const grid of gridElements) {
6707
+ ctx.save();
6708
+ ctx.globalAlpha = this.layerManager.getLayer?.(grid.layerId)?.opacity ?? 1;
6656
6709
  this.renderer.renderCanvasElement(ctx, grid);
6710
+ ctx.restore();
6657
6711
  }
6658
6712
  }
6659
6713
  gridMs = performance.now() - gridT0;
@@ -7558,6 +7612,7 @@ var Viewport = class {
7558
7612
  ];
7559
7613
  this.layerManager.on("change", () => {
7560
7614
  this.toolContext.activeLayerId = this.layerManager.activeLayerId;
7615
+ this.renderLoop.markAllLayersDirty();
7561
7616
  this.minimap?.scheduleDraw();
7562
7617
  this.requestRender();
7563
7618
  });
@@ -10621,7 +10676,7 @@ var LaserTool = class {
10621
10676
  };
10622
10677
 
10623
10678
  // src/index.ts
10624
- var VERSION = "0.50.1";
10679
+ var VERSION = "0.50.2";
10625
10680
  // Annotate the CommonJS export names for ESM import in node:
10626
10681
  0 && (module.exports = {
10627
10682
  ArrowTool,