@fieldnotes/core 0.50.0 → 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 +92 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +92 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -367,7 +367,7 @@ function migrateElement(obj) {
|
|
|
367
367
|
if (obj["type"] === "note" && typeof obj["textColor"] !== "string") {
|
|
368
368
|
obj["textColor"] = "#000000";
|
|
369
369
|
}
|
|
370
|
-
if (obj["type"] === "note" && typeof obj["text"] === "string") {
|
|
370
|
+
if ((obj["type"] === "note" || obj["type"] === "text") && typeof obj["text"] === "string") {
|
|
371
371
|
obj["text"] = sanitizeNoteHtml(obj["text"]);
|
|
372
372
|
}
|
|
373
373
|
}
|
|
@@ -2580,6 +2580,11 @@ function transferStrokeRenderData(prev, next) {
|
|
|
2580
2580
|
}
|
|
2581
2581
|
|
|
2582
2582
|
// src/elements/element-store.ts
|
|
2583
|
+
function sanitizeRichText(element) {
|
|
2584
|
+
if (element.type !== "note" && element.type !== "text") return element;
|
|
2585
|
+
const text = sanitizeNoteHtml(element.text);
|
|
2586
|
+
return text === element.text ? element : { ...element, text };
|
|
2587
|
+
}
|
|
2583
2588
|
var ElementStore = class {
|
|
2584
2589
|
elements = /* @__PURE__ */ new Map();
|
|
2585
2590
|
bus = new EventBus();
|
|
@@ -2624,6 +2629,7 @@ var ElementStore = class {
|
|
|
2624
2629
|
return angle === 0 ? bounds : rotatedAABB(bounds, angle);
|
|
2625
2630
|
}
|
|
2626
2631
|
add(element, meta) {
|
|
2632
|
+
element = sanitizeRichText(element);
|
|
2627
2633
|
this.sortedCache = null;
|
|
2628
2634
|
this._versions.set(element.id, 0);
|
|
2629
2635
|
this.elements.set(element.id, element);
|
|
@@ -2650,7 +2656,7 @@ var ElementStore = class {
|
|
|
2650
2656
|
const arrow = updated;
|
|
2651
2657
|
arrow.cachedControlPoint = getArrowControlPoint(arrow.from, arrow.to, arrow.bend);
|
|
2652
2658
|
}
|
|
2653
|
-
if (updated.type === "note" && "text" in partial) {
|
|
2659
|
+
if ((updated.type === "note" || updated.type === "text") && "text" in partial) {
|
|
2654
2660
|
updated.text = sanitizeNoteHtml(updated.text);
|
|
2655
2661
|
}
|
|
2656
2662
|
this.elements.set(id, updated);
|
|
@@ -2680,11 +2686,12 @@ var ElementStore = class {
|
|
|
2680
2686
|
return this.getAll().map((el) => ({ ...el }));
|
|
2681
2687
|
}
|
|
2682
2688
|
loadSnapshot(elements, meta) {
|
|
2689
|
+
const sanitizedElements = elements.map(sanitizeRichText);
|
|
2683
2690
|
this.sortedCache = null;
|
|
2684
2691
|
this._versions.clear();
|
|
2685
2692
|
this.elements.clear();
|
|
2686
2693
|
this.spatialIndex.clear();
|
|
2687
|
-
for (const el of
|
|
2694
|
+
for (const el of sanitizedElements) {
|
|
2688
2695
|
this.elements.set(el.id, el);
|
|
2689
2696
|
this._versions.set(el.id, 0);
|
|
2690
2697
|
const bounds = this.indexBounds(el);
|
|
@@ -2697,7 +2704,7 @@ var ElementStore = class {
|
|
|
2697
2704
|
}
|
|
2698
2705
|
}
|
|
2699
2706
|
this.bus.emit("clear", null, meta);
|
|
2700
|
-
for (const el of
|
|
2707
|
+
for (const el of sanitizedElements) {
|
|
2701
2708
|
this.bus.emit("add", el, meta);
|
|
2702
2709
|
}
|
|
2703
2710
|
}
|
|
@@ -3673,7 +3680,7 @@ function renderSquareGrid(ctx, bounds, cellSize, strokeColor, strokeWidth, opaci
|
|
|
3673
3680
|
ctx.save();
|
|
3674
3681
|
ctx.strokeStyle = strokeColor;
|
|
3675
3682
|
ctx.lineWidth = strokeWidth;
|
|
3676
|
-
ctx.globalAlpha
|
|
3683
|
+
ctx.globalAlpha *= opacity;
|
|
3677
3684
|
ctx.beginPath();
|
|
3678
3685
|
for (const x of verticals) {
|
|
3679
3686
|
ctx.moveTo(x, bounds.minY);
|
|
@@ -3704,7 +3711,7 @@ function renderHexGrid(ctx, bounds, cellSize, orientation, strokeColor, strokeWi
|
|
|
3704
3711
|
ctx.save();
|
|
3705
3712
|
ctx.strokeStyle = strokeColor;
|
|
3706
3713
|
ctx.lineWidth = strokeWidth;
|
|
3707
|
-
ctx.globalAlpha
|
|
3714
|
+
ctx.globalAlpha *= opacity;
|
|
3708
3715
|
ctx.beginPath();
|
|
3709
3716
|
if (orientation === "pointy") {
|
|
3710
3717
|
const hexW = Math.sqrt(3) * cellSize;
|
|
@@ -4112,7 +4119,7 @@ function createText(input) {
|
|
|
4112
4119
|
locked: input.locked ?? false,
|
|
4113
4120
|
layerId: input.layerId ?? "",
|
|
4114
4121
|
size: input.size ?? { w: 200, h: 28 },
|
|
4115
|
-
text: input.text ?? "",
|
|
4122
|
+
text: sanitizeNoteHtml(input.text ?? ""),
|
|
4116
4123
|
fontSize: input.fontSize ?? 16,
|
|
4117
4124
|
color: input.color ?? "#1a1a1a",
|
|
4118
4125
|
textAlign: input.textAlign ?? "left"
|
|
@@ -5464,41 +5471,70 @@ async function exportImage(store, options = {}, layerManager) {
|
|
|
5464
5471
|
const renderer = new ElementRenderer();
|
|
5465
5472
|
renderer.setStore(store);
|
|
5466
5473
|
const grids = [];
|
|
5467
|
-
|
|
5468
|
-
if (el.type === "grid") {
|
|
5469
|
-
grids.push(el);
|
|
5470
|
-
continue;
|
|
5471
|
-
}
|
|
5474
|
+
const renderElement = (target, el) => {
|
|
5472
5475
|
if (el.type === "note") {
|
|
5473
5476
|
const b = getElementBounds(el);
|
|
5474
|
-
withRotation(
|
|
5475
|
-
|
|
5477
|
+
withRotation(target, el, b ? center(b) : el.position, () => renderNoteOnCanvas(target, el));
|
|
5478
|
+
return;
|
|
5476
5479
|
}
|
|
5477
5480
|
if (el.type === "text") {
|
|
5478
5481
|
const b = getElementBounds(el);
|
|
5479
|
-
withRotation(
|
|
5480
|
-
|
|
5482
|
+
withRotation(target, el, b ? center(b) : el.position, () => renderTextOnCanvas(target, el));
|
|
5483
|
+
return;
|
|
5481
5484
|
}
|
|
5482
5485
|
if (el.type === "html") {
|
|
5483
|
-
|
|
5486
|
+
return;
|
|
5484
5487
|
}
|
|
5485
5488
|
if (el.type === "image") {
|
|
5486
5489
|
const img = imageCache.get(el.id);
|
|
5487
5490
|
if (img) {
|
|
5488
5491
|
const b = getElementBounds(el);
|
|
5489
5492
|
withRotation(
|
|
5490
|
-
|
|
5493
|
+
target,
|
|
5491
5494
|
el,
|
|
5492
5495
|
b ? center(b) : el.position,
|
|
5493
|
-
() =>
|
|
5496
|
+
() => target.drawImage(img, el.position.x, el.position.y, el.size.w, el.size.h)
|
|
5494
5497
|
);
|
|
5495
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);
|
|
5496
5517
|
continue;
|
|
5497
5518
|
}
|
|
5498
|
-
|
|
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();
|
|
5499
5532
|
}
|
|
5500
5533
|
for (const grid of grids) {
|
|
5534
|
+
ctx.save();
|
|
5535
|
+
ctx.globalAlpha = layerManager?.getLayer?.(grid.layerId)?.opacity ?? 1;
|
|
5501
5536
|
renderGridForBounds(ctx, grid, bounds);
|
|
5537
|
+
ctx.restore();
|
|
5502
5538
|
}
|
|
5503
5539
|
return new Promise((resolve) => {
|
|
5504
5540
|
canvas.toBlob((blob) => resolve(blob), "image/png");
|
|
@@ -5818,11 +5854,19 @@ async function exportSvg(store, options = {}, layerManager) {
|
|
|
5818
5854
|
if (options.background) {
|
|
5819
5855
|
body += `<rect x="${n(bounds.x)}" y="${n(bounds.y)}" width="${n(bounds.w)}" height="${n(bounds.h)}" fill="${esc(options.background)}" />`;
|
|
5820
5856
|
}
|
|
5857
|
+
const layerBodies = /* @__PURE__ */ new Map();
|
|
5821
5858
|
for (const el of visibleElements) {
|
|
5822
|
-
|
|
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>`;
|
|
5823
5865
|
}
|
|
5824
5866
|
for (const grid of grids) {
|
|
5825
|
-
|
|
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>`;
|
|
5826
5870
|
}
|
|
5827
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>`;
|
|
5828
5872
|
}
|
|
@@ -6141,6 +6185,7 @@ var DomNodeManager = class {
|
|
|
6141
6185
|
getVersion;
|
|
6142
6186
|
lastSyncedVersion = /* @__PURE__ */ new Map();
|
|
6143
6187
|
lastSyncedZIndex = /* @__PURE__ */ new Map();
|
|
6188
|
+
lastSyncedOpacity = /* @__PURE__ */ new Map();
|
|
6144
6189
|
constructor(deps) {
|
|
6145
6190
|
this.domLayer = deps.domLayer;
|
|
6146
6191
|
this.onEditRequest = deps.onEditRequest;
|
|
@@ -6160,6 +6205,7 @@ var DomNodeManager = class {
|
|
|
6160
6205
|
this.htmlContent.delete(elementId);
|
|
6161
6206
|
this.lastSyncedVersion.delete(elementId);
|
|
6162
6207
|
this.lastSyncedZIndex.delete(elementId);
|
|
6208
|
+
this.lastSyncedOpacity.delete(elementId);
|
|
6163
6209
|
const node = this.domNodes.get(elementId);
|
|
6164
6210
|
if (!node) return;
|
|
6165
6211
|
while (node.firstChild) {
|
|
@@ -6167,7 +6213,7 @@ var DomNodeManager = class {
|
|
|
6167
6213
|
}
|
|
6168
6214
|
delete node.dataset["initialized"];
|
|
6169
6215
|
}
|
|
6170
|
-
syncDomNode(element, zIndex = 0) {
|
|
6216
|
+
syncDomNode(element, zIndex = 0, opacity = 1) {
|
|
6171
6217
|
let node = this.domNodes.get(element.id);
|
|
6172
6218
|
if (!node) {
|
|
6173
6219
|
node = document.createElement("div");
|
|
@@ -6182,13 +6228,15 @@ var DomNodeManager = class {
|
|
|
6182
6228
|
const currentVersion = this.getVersion(element.id);
|
|
6183
6229
|
const lastVersion = this.lastSyncedVersion.get(element.id);
|
|
6184
6230
|
const lastZ = this.lastSyncedZIndex.get(element.id);
|
|
6185
|
-
|
|
6231
|
+
const lastOpacity = this.lastSyncedOpacity.get(element.id);
|
|
6232
|
+
if (lastVersion === currentVersion && lastZ === zIndex && lastOpacity === opacity) {
|
|
6186
6233
|
return;
|
|
6187
6234
|
}
|
|
6188
6235
|
}
|
|
6189
6236
|
if (this.getVersion) {
|
|
6190
6237
|
this.lastSyncedVersion.set(element.id, this.getVersion(element.id));
|
|
6191
6238
|
this.lastSyncedZIndex.set(element.id, zIndex);
|
|
6239
|
+
this.lastSyncedOpacity.set(element.id, opacity);
|
|
6192
6240
|
}
|
|
6193
6241
|
const size = "size" in element ? element.size : null;
|
|
6194
6242
|
Object.assign(node.style, {
|
|
@@ -6198,6 +6246,7 @@ var DomNodeManager = class {
|
|
|
6198
6246
|
width: size ? `${size.w}px` : "auto",
|
|
6199
6247
|
height: size ? `${size.h}px` : "auto",
|
|
6200
6248
|
zIndex: String(zIndex),
|
|
6249
|
+
opacity: String(opacity),
|
|
6201
6250
|
transform: element.rotation ? `rotate(${element.rotation}rad)` : "",
|
|
6202
6251
|
transformOrigin: "50% 50%"
|
|
6203
6252
|
});
|
|
@@ -6211,6 +6260,7 @@ var DomNodeManager = class {
|
|
|
6211
6260
|
this.htmlContent.delete(id);
|
|
6212
6261
|
this.lastSyncedVersion.delete(id);
|
|
6213
6262
|
this.lastSyncedZIndex.delete(id);
|
|
6263
|
+
this.lastSyncedOpacity.delete(id);
|
|
6214
6264
|
const node = this.domNodes.get(id);
|
|
6215
6265
|
if (node) {
|
|
6216
6266
|
node.remove();
|
|
@@ -6223,6 +6273,7 @@ var DomNodeManager = class {
|
|
|
6223
6273
|
this.htmlContent.clear();
|
|
6224
6274
|
this.lastSyncedVersion.clear();
|
|
6225
6275
|
this.lastSyncedZIndex.clear();
|
|
6276
|
+
this.lastSyncedOpacity.clear();
|
|
6226
6277
|
}
|
|
6227
6278
|
reattachHtmlContent(store) {
|
|
6228
6279
|
for (const el of store.getElementsByType("html")) {
|
|
@@ -6461,11 +6512,12 @@ var RenderLoop = class {
|
|
|
6461
6512
|
}
|
|
6462
6513
|
markAllLayersDirty() {
|
|
6463
6514
|
this.layerCache.markAllDirty();
|
|
6515
|
+
this.gridCacheDirty = true;
|
|
6464
6516
|
}
|
|
6465
6517
|
getStats() {
|
|
6466
6518
|
return this.stats.getSnapshot();
|
|
6467
6519
|
}
|
|
6468
|
-
compositeLayerCache(ctx, layerId) {
|
|
6520
|
+
compositeLayerCache(ctx, layerId, opacity) {
|
|
6469
6521
|
const cached = this.layerCache.getCanvas(layerId);
|
|
6470
6522
|
const offset = this.marginViewport.compositeOffset(
|
|
6471
6523
|
this.camera.position.x,
|
|
@@ -6473,6 +6525,7 @@ var RenderLoop = class {
|
|
|
6473
6525
|
);
|
|
6474
6526
|
ctx.save();
|
|
6475
6527
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
6528
|
+
ctx.globalAlpha = opacity;
|
|
6476
6529
|
ctx.drawImage(cached, offset.x, offset.y);
|
|
6477
6530
|
ctx.restore();
|
|
6478
6531
|
}
|
|
@@ -6552,11 +6605,12 @@ var RenderLoop = class {
|
|
|
6552
6605
|
continue;
|
|
6553
6606
|
}
|
|
6554
6607
|
if (this.renderer.isDomElement(element)) {
|
|
6608
|
+
const layerOpacity = this.layerManager.getLayer?.(element.layerId)?.opacity ?? 1;
|
|
6555
6609
|
const elBounds = getElementBounds(element);
|
|
6556
6610
|
if (elBounds && !boundsIntersect(elBounds, cullingRect)) {
|
|
6557
6611
|
this.domNodeManager.hideDomNode(element.id);
|
|
6558
6612
|
} else {
|
|
6559
|
-
this.domNodeManager.syncDomNode(element, domZIndex
|
|
6613
|
+
this.domNodeManager.syncDomNode(element, domZIndex++, layerOpacity);
|
|
6560
6614
|
}
|
|
6561
6615
|
continue;
|
|
6562
6616
|
}
|
|
@@ -6573,15 +6627,16 @@ var RenderLoop = class {
|
|
|
6573
6627
|
}
|
|
6574
6628
|
for (const [layerId, elements] of this.layerGroups) {
|
|
6575
6629
|
const isActiveDrawingLayer = layerId === this.activeDrawingLayerId;
|
|
6630
|
+
const layerOpacity = this.layerManager.getLayer?.(layerId)?.opacity ?? 1;
|
|
6576
6631
|
if (!this.layerCache.isDirty(layerId)) {
|
|
6577
6632
|
const compT0 = performance.now();
|
|
6578
|
-
this.compositeLayerCache(ctx, layerId);
|
|
6633
|
+
this.compositeLayerCache(ctx, layerId, layerOpacity);
|
|
6579
6634
|
compositeMs += performance.now() - compT0;
|
|
6580
6635
|
continue;
|
|
6581
6636
|
}
|
|
6582
6637
|
if (isActiveDrawingLayer) {
|
|
6583
6638
|
const compT0 = performance.now();
|
|
6584
|
-
this.compositeLayerCache(ctx, layerId);
|
|
6639
|
+
this.compositeLayerCache(ctx, layerId, layerOpacity);
|
|
6585
6640
|
compositeMs += performance.now() - compT0;
|
|
6586
6641
|
continue;
|
|
6587
6642
|
}
|
|
@@ -6601,7 +6656,7 @@ var RenderLoop = class {
|
|
|
6601
6656
|
this.layerCache.markClean(layerId);
|
|
6602
6657
|
layersMs += performance.now() - layerT0;
|
|
6603
6658
|
const compT0 = performance.now();
|
|
6604
|
-
this.compositeLayerCache(ctx, layerId);
|
|
6659
|
+
this.compositeLayerCache(ctx, layerId, layerOpacity);
|
|
6605
6660
|
compositeMs += performance.now() - compT0;
|
|
6606
6661
|
}
|
|
6607
6662
|
}
|
|
@@ -6625,7 +6680,10 @@ var RenderLoop = class {
|
|
|
6625
6680
|
this.marginViewport.applyRenderTransform(gc);
|
|
6626
6681
|
try {
|
|
6627
6682
|
for (const grid of gridElements) {
|
|
6683
|
+
gc.save();
|
|
6684
|
+
gc.globalAlpha = this.layerManager.getLayer?.(grid.layerId)?.opacity ?? 1;
|
|
6628
6685
|
this.renderer.renderCanvasElement(gc, grid);
|
|
6686
|
+
gc.restore();
|
|
6629
6687
|
}
|
|
6630
6688
|
} finally {
|
|
6631
6689
|
gc.restore();
|
|
@@ -6646,7 +6704,10 @@ var RenderLoop = class {
|
|
|
6646
6704
|
ctx.restore();
|
|
6647
6705
|
} else {
|
|
6648
6706
|
for (const grid of gridElements) {
|
|
6707
|
+
ctx.save();
|
|
6708
|
+
ctx.globalAlpha = this.layerManager.getLayer?.(grid.layerId)?.opacity ?? 1;
|
|
6649
6709
|
this.renderer.renderCanvasElement(ctx, grid);
|
|
6710
|
+
ctx.restore();
|
|
6650
6711
|
}
|
|
6651
6712
|
}
|
|
6652
6713
|
gridMs = performance.now() - gridT0;
|
|
@@ -7551,6 +7612,7 @@ var Viewport = class {
|
|
|
7551
7612
|
];
|
|
7552
7613
|
this.layerManager.on("change", () => {
|
|
7553
7614
|
this.toolContext.activeLayerId = this.layerManager.activeLayerId;
|
|
7615
|
+
this.renderLoop.markAllLayersDirty();
|
|
7554
7616
|
this.minimap?.scheduleDraw();
|
|
7555
7617
|
this.requestRender();
|
|
7556
7618
|
});
|
|
@@ -10614,7 +10676,7 @@ var LaserTool = class {
|
|
|
10614
10676
|
};
|
|
10615
10677
|
|
|
10616
10678
|
// src/index.ts
|
|
10617
|
-
var VERSION = "0.50.
|
|
10679
|
+
var VERSION = "0.50.2";
|
|
10618
10680
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10619
10681
|
0 && (module.exports = {
|
|
10620
10682
|
ArrowTool,
|