@fieldnotes/core 0.56.0 → 0.57.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.cjs +274 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +147 -35
- package/dist/index.d.ts +147 -35
- package/dist/index.js +270 -50
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -34,6 +34,7 @@ __export(index_exports, {
|
|
|
34
34
|
LaserTool: () => LaserTool,
|
|
35
35
|
LayerManager: () => LayerManager,
|
|
36
36
|
LocalStorageAdapter: () => LocalStorageAdapter,
|
|
37
|
+
MEASURE_PRESENCE_KIND: () => MEASURE_PRESENCE_KIND,
|
|
37
38
|
MeasureTool: () => MeasureTool,
|
|
38
39
|
MemoryAdapter: () => MemoryAdapter,
|
|
39
40
|
NoteTool: () => NoteTool,
|
|
@@ -42,6 +43,7 @@ __export(index_exports, {
|
|
|
42
43
|
PingInput: () => PingInput,
|
|
43
44
|
PingTool: () => PingTool,
|
|
44
45
|
RemoteLaserOverlay: () => RemoteLaserOverlay,
|
|
46
|
+
RemoteMeasureOverlay: () => RemoteMeasureOverlay,
|
|
45
47
|
RemotePingOverlay: () => RemotePingOverlay,
|
|
46
48
|
SelectTool: () => SelectTool,
|
|
47
49
|
ShapeTool: () => ShapeTool,
|
|
@@ -79,6 +81,7 @@ __export(index_exports, {
|
|
|
79
81
|
getHexCellsInSquare: () => getHexCellsInSquare,
|
|
80
82
|
getHexDistance: () => getHexDistance,
|
|
81
83
|
isLaserTrailPresence: () => isLaserTrailPresence,
|
|
84
|
+
isMeasurePresence: () => isMeasurePresence,
|
|
82
85
|
isNearBezier: () => isNearBezier,
|
|
83
86
|
isPingPresence: () => isPingPresence,
|
|
84
87
|
setFontSize: () => setFontSize,
|
|
@@ -87,6 +90,7 @@ __export(index_exports, {
|
|
|
87
90
|
snapToHexCenter: () => snapToHexCenter,
|
|
88
91
|
styleToPatch: () => styleToPatch,
|
|
89
92
|
toLaserTrailPresence: () => toLaserTrailPresence,
|
|
93
|
+
toMeasurePresence: () => toMeasurePresence,
|
|
90
94
|
toPingPresence: () => toPingPresence,
|
|
91
95
|
toggleBold: () => toggleBold,
|
|
92
96
|
toggleItalic: () => toggleItalic,
|
|
@@ -8942,10 +8946,218 @@ var RemotePingOverlay = class {
|
|
|
8942
8946
|
}
|
|
8943
8947
|
};
|
|
8944
8948
|
|
|
8949
|
+
// src/canvas/measure-render.ts
|
|
8950
|
+
function formatMeasureLabel(feet) {
|
|
8951
|
+
return `${Math.round(feet)} ft`;
|
|
8952
|
+
}
|
|
8953
|
+
function drawMeasurement(ctx, m, opts = {}) {
|
|
8954
|
+
ctx.save();
|
|
8955
|
+
if (opts.alpha !== void 0) ctx.globalAlpha = opts.alpha;
|
|
8956
|
+
ctx.strokeStyle = m.color;
|
|
8957
|
+
ctx.setLineDash([8, 4]);
|
|
8958
|
+
ctx.lineWidth = 2;
|
|
8959
|
+
ctx.beginPath();
|
|
8960
|
+
ctx.moveTo(m.start.x, m.start.y);
|
|
8961
|
+
ctx.lineTo(m.end.x, m.end.y);
|
|
8962
|
+
ctx.stroke();
|
|
8963
|
+
ctx.setLineDash([]);
|
|
8964
|
+
ctx.fillStyle = m.color;
|
|
8965
|
+
const dotRadius = 4;
|
|
8966
|
+
ctx.beginPath();
|
|
8967
|
+
ctx.arc(m.start.x, m.start.y, dotRadius, 0, Math.PI * 2);
|
|
8968
|
+
ctx.fill();
|
|
8969
|
+
ctx.beginPath();
|
|
8970
|
+
ctx.arc(m.end.x, m.end.y, dotRadius, 0, Math.PI * 2);
|
|
8971
|
+
ctx.fill();
|
|
8972
|
+
const label = formatMeasureLabel(m.feet);
|
|
8973
|
+
const midX = (m.start.x + m.end.x) / 2;
|
|
8974
|
+
const midY = (m.start.y + m.end.y) / 2;
|
|
8975
|
+
ctx.font = "14px sans-serif";
|
|
8976
|
+
const metrics = ctx.measureText(label);
|
|
8977
|
+
const padX = 6;
|
|
8978
|
+
const padY = 4;
|
|
8979
|
+
const textH = 14;
|
|
8980
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.75)";
|
|
8981
|
+
ctx.beginPath();
|
|
8982
|
+
ctx.roundRect(
|
|
8983
|
+
midX - metrics.width / 2 - padX,
|
|
8984
|
+
midY - textH / 2 - padY,
|
|
8985
|
+
metrics.width + padX * 2,
|
|
8986
|
+
textH + padY * 2,
|
|
8987
|
+
4
|
|
8988
|
+
);
|
|
8989
|
+
ctx.fill();
|
|
8990
|
+
ctx.fillStyle = "#FFFFFF";
|
|
8991
|
+
ctx.textAlign = "center";
|
|
8992
|
+
ctx.textBaseline = "middle";
|
|
8993
|
+
ctx.fillText(label, midX, midY);
|
|
8994
|
+
ctx.restore();
|
|
8995
|
+
}
|
|
8996
|
+
|
|
8997
|
+
// src/canvas/remote-measure-overlay.ts
|
|
8998
|
+
var MEASURE_PRESENCE_KIND = "measure";
|
|
8999
|
+
function isFinitePoint2(value) {
|
|
9000
|
+
if (typeof value !== "object" || value === null) return false;
|
|
9001
|
+
const point = value;
|
|
9002
|
+
return typeof point.x === "number" && Number.isFinite(point.x) && typeof point.y === "number" && Number.isFinite(point.y);
|
|
9003
|
+
}
|
|
9004
|
+
function isMeasurePresence(data) {
|
|
9005
|
+
if (typeof data !== "object" || data === null) return false;
|
|
9006
|
+
const payload = data;
|
|
9007
|
+
if (payload.kind !== MEASURE_PRESENCE_KIND) return false;
|
|
9008
|
+
if ("cleared" in payload) return payload.cleared === true;
|
|
9009
|
+
if (!isFinitePoint2(payload.start) || !isFinitePoint2(payload.end)) return false;
|
|
9010
|
+
if (typeof payload.cells !== "number" || !Number.isFinite(payload.cells)) return false;
|
|
9011
|
+
if (typeof payload.feet !== "number" || !Number.isFinite(payload.feet)) return false;
|
|
9012
|
+
if (payload.color !== void 0 && typeof payload.color !== "string") return false;
|
|
9013
|
+
return true;
|
|
9014
|
+
}
|
|
9015
|
+
function toMeasurePresence(emission) {
|
|
9016
|
+
if (emission === null) return { kind: MEASURE_PRESENCE_KIND, cleared: true };
|
|
9017
|
+
return {
|
|
9018
|
+
kind: MEASURE_PRESENCE_KIND,
|
|
9019
|
+
start: emission.start,
|
|
9020
|
+
end: emission.end,
|
|
9021
|
+
cells: emission.cells,
|
|
9022
|
+
feet: emission.feet,
|
|
9023
|
+
color: emission.color
|
|
9024
|
+
};
|
|
9025
|
+
}
|
|
9026
|
+
var DEFAULT_COLOR3 = "#FF5722";
|
|
9027
|
+
var DEFAULT_HOLD_MS = 1500;
|
|
9028
|
+
var DEFAULT_FADE_MS2 = 400;
|
|
9029
|
+
var DEFAULT_MAX_AGE_MS = 3e4;
|
|
9030
|
+
var RemoteMeasureOverlay = class {
|
|
9031
|
+
host;
|
|
9032
|
+
color;
|
|
9033
|
+
holdMs;
|
|
9034
|
+
fadeMs;
|
|
9035
|
+
maxAgeMs;
|
|
9036
|
+
measurements = /* @__PURE__ */ new Map();
|
|
9037
|
+
unregister;
|
|
9038
|
+
rafId = null;
|
|
9039
|
+
disposed = false;
|
|
9040
|
+
constructor(host, options = {}) {
|
|
9041
|
+
this.host = host;
|
|
9042
|
+
this.color = options.color ?? DEFAULT_COLOR3;
|
|
9043
|
+
this.holdMs = options.holdMs ?? DEFAULT_HOLD_MS;
|
|
9044
|
+
this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS2;
|
|
9045
|
+
this.maxAgeMs = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
9046
|
+
this.unregister = host.registerOverlay((ctx) => this.renderMeasurements(ctx));
|
|
9047
|
+
}
|
|
9048
|
+
now() {
|
|
9049
|
+
return performance.now();
|
|
9050
|
+
}
|
|
9051
|
+
/**
|
|
9052
|
+
* Applies a presence payload from `sender` (any opaque per-sender key, e.g.
|
|
9053
|
+
* the envelope `from`). Non-measure or malformed payloads are ignored and
|
|
9054
|
+
* reported as `false`, so hosts can feed every presence frame through.
|
|
9055
|
+
*/
|
|
9056
|
+
apply(sender, data) {
|
|
9057
|
+
if (this.disposed || !isMeasurePresence(data)) return false;
|
|
9058
|
+
if ("cleared" in data) {
|
|
9059
|
+
this.beginLinger(sender);
|
|
9060
|
+
return true;
|
|
9061
|
+
}
|
|
9062
|
+
const existing = this.measurements.get(sender);
|
|
9063
|
+
if (existing?.expiryTimer != null) clearTimeout(existing.expiryTimer);
|
|
9064
|
+
this.measurements.set(sender, {
|
|
9065
|
+
start: data.start,
|
|
9066
|
+
end: data.end,
|
|
9067
|
+
feet: data.feet,
|
|
9068
|
+
color: data.color ?? this.color,
|
|
9069
|
+
clearedAt: null,
|
|
9070
|
+
expiryTimer: setTimeout(() => this.beginLinger(sender), this.maxAgeMs)
|
|
9071
|
+
});
|
|
9072
|
+
this.host.requestRender();
|
|
9073
|
+
return true;
|
|
9074
|
+
}
|
|
9075
|
+
/** Removes a sender's ruler immediately (presence-leave/disconnect). */
|
|
9076
|
+
remove(sender) {
|
|
9077
|
+
const entry = this.measurements.get(sender);
|
|
9078
|
+
if (!entry) return;
|
|
9079
|
+
if (entry.expiryTimer != null) clearTimeout(entry.expiryTimer);
|
|
9080
|
+
this.measurements.delete(sender);
|
|
9081
|
+
this.host.requestRender();
|
|
9082
|
+
}
|
|
9083
|
+
/** Removes every ruler immediately. */
|
|
9084
|
+
clear() {
|
|
9085
|
+
if (this.measurements.size === 0) return;
|
|
9086
|
+
for (const entry of this.measurements.values()) {
|
|
9087
|
+
if (entry.expiryTimer != null) clearTimeout(entry.expiryTimer);
|
|
9088
|
+
}
|
|
9089
|
+
this.measurements.clear();
|
|
9090
|
+
this.host.requestRender();
|
|
9091
|
+
}
|
|
9092
|
+
/** Number of senders with a visible (active or lingering) ruler. */
|
|
9093
|
+
get activeSenderCount() {
|
|
9094
|
+
return this.measurements.size;
|
|
9095
|
+
}
|
|
9096
|
+
/** Unregisters the overlay, cancels timers, stops animating. Idempotent. */
|
|
9097
|
+
dispose() {
|
|
9098
|
+
if (this.disposed) return;
|
|
9099
|
+
this.disposed = true;
|
|
9100
|
+
if (this.rafId !== null) {
|
|
9101
|
+
cancelAnimationFrame(this.rafId);
|
|
9102
|
+
this.rafId = null;
|
|
9103
|
+
}
|
|
9104
|
+
for (const entry of this.measurements.values()) {
|
|
9105
|
+
if (entry.expiryTimer != null) clearTimeout(entry.expiryTimer);
|
|
9106
|
+
}
|
|
9107
|
+
this.measurements.clear();
|
|
9108
|
+
this.unregister?.();
|
|
9109
|
+
this.unregister = null;
|
|
9110
|
+
this.host.requestRender();
|
|
9111
|
+
}
|
|
9112
|
+
beginLinger(sender) {
|
|
9113
|
+
const entry = this.measurements.get(sender);
|
|
9114
|
+
if (!entry || entry.clearedAt !== null) return;
|
|
9115
|
+
if (entry.expiryTimer != null) {
|
|
9116
|
+
clearTimeout(entry.expiryTimer);
|
|
9117
|
+
entry.expiryTimer = null;
|
|
9118
|
+
}
|
|
9119
|
+
entry.clearedAt = this.now();
|
|
9120
|
+
this.ensureAnimating();
|
|
9121
|
+
this.host.requestRender();
|
|
9122
|
+
}
|
|
9123
|
+
ensureAnimating() {
|
|
9124
|
+
if (this.rafId === null) {
|
|
9125
|
+
this.rafId = requestAnimationFrame(() => this.tick());
|
|
9126
|
+
}
|
|
9127
|
+
}
|
|
9128
|
+
tick() {
|
|
9129
|
+
if (this.disposed) return;
|
|
9130
|
+
const now = this.now();
|
|
9131
|
+
let lingering = 0;
|
|
9132
|
+
for (const [sender, entry] of this.measurements) {
|
|
9133
|
+
if (entry.clearedAt === null) continue;
|
|
9134
|
+
if (now - entry.clearedAt >= this.holdMs + this.fadeMs) {
|
|
9135
|
+
this.measurements.delete(sender);
|
|
9136
|
+
} else {
|
|
9137
|
+
lingering += 1;
|
|
9138
|
+
}
|
|
9139
|
+
}
|
|
9140
|
+
this.host.requestRender();
|
|
9141
|
+
this.rafId = lingering > 0 ? requestAnimationFrame(() => this.tick()) : null;
|
|
9142
|
+
}
|
|
9143
|
+
renderMeasurements(ctx) {
|
|
9144
|
+
if (this.measurements.size === 0) return;
|
|
9145
|
+
const now = this.now();
|
|
9146
|
+
for (const entry of this.measurements.values()) {
|
|
9147
|
+
let alpha = 1;
|
|
9148
|
+
if (entry.clearedAt !== null) {
|
|
9149
|
+
const fadeAge = now - entry.clearedAt - this.holdMs;
|
|
9150
|
+
if (fadeAge > 0) alpha = Math.max(0, 1 - fadeAge / this.fadeMs);
|
|
9151
|
+
}
|
|
9152
|
+
drawMeasurement(ctx, entry, { alpha });
|
|
9153
|
+
}
|
|
9154
|
+
}
|
|
9155
|
+
};
|
|
9156
|
+
|
|
8945
9157
|
// src/canvas/ping-input.ts
|
|
8946
9158
|
var DEFAULT_LONG_PRESS_MS = 600;
|
|
8947
9159
|
var DEFAULT_SLOP_PX = 8;
|
|
8948
|
-
var
|
|
9160
|
+
var DEFAULT_COLOR4 = "#ff3b30";
|
|
8949
9161
|
var DEFAULT_DURATION_MS2 = 1800;
|
|
8950
9162
|
var DEFAULT_RADIUS2 = 48;
|
|
8951
9163
|
var DEFAULT_MIN_INTERVAL_MS = 300;
|
|
@@ -8978,7 +9190,7 @@ var PingInput = class {
|
|
|
8978
9190
|
this.longPressEnabled = options.longPressEnabled ?? false;
|
|
8979
9191
|
this.longPressMs = options.longPressMs ?? DEFAULT_LONG_PRESS_MS;
|
|
8980
9192
|
this.slopPx = options.slopPx ?? DEFAULT_SLOP_PX;
|
|
8981
|
-
this.color = options.color ??
|
|
9193
|
+
this.color = options.color ?? DEFAULT_COLOR4;
|
|
8982
9194
|
this.durationMs = options.durationMs ?? DEFAULT_DURATION_MS2;
|
|
8983
9195
|
this.radius = options.radius ?? DEFAULT_RADIUS2;
|
|
8984
9196
|
this.minIntervalMs = options.minIntervalMs ?? DEFAULT_MIN_INTERVAL_MS;
|
|
@@ -11268,21 +11480,37 @@ var MeasureTool = class {
|
|
|
11268
11480
|
gridType;
|
|
11269
11481
|
hexOrientation;
|
|
11270
11482
|
feetPerCell;
|
|
11483
|
+
color;
|
|
11271
11484
|
optionListeners = /* @__PURE__ */ new Set();
|
|
11485
|
+
measurementListeners = /* @__PURE__ */ new Set();
|
|
11486
|
+
emissionRafId = null;
|
|
11272
11487
|
constructor(options = {}) {
|
|
11273
11488
|
this.feetPerCell = options.feetPerCell ?? 5;
|
|
11489
|
+
this.color = options.color ?? "#FF5722";
|
|
11274
11490
|
}
|
|
11275
11491
|
getOptions() {
|
|
11276
|
-
return { feetPerCell: this.feetPerCell };
|
|
11492
|
+
return { feetPerCell: this.feetPerCell, color: this.color };
|
|
11277
11493
|
}
|
|
11278
11494
|
setOptions(options) {
|
|
11279
11495
|
if (options.feetPerCell !== void 0) this.feetPerCell = options.feetPerCell;
|
|
11496
|
+
if (options.color !== void 0) this.color = options.color;
|
|
11280
11497
|
this.notifyOptionsChange();
|
|
11281
11498
|
}
|
|
11282
11499
|
onOptionsChange(listener) {
|
|
11283
11500
|
this.optionListeners.add(listener);
|
|
11284
11501
|
return () => this.optionListeners.delete(listener);
|
|
11285
11502
|
}
|
|
11503
|
+
/**
|
|
11504
|
+
* Subscribes to raf-coalesced measurement snapshots. While a measurement is
|
|
11505
|
+
* in progress, listeners receive at most one snapshot per animation frame
|
|
11506
|
+
* carrying the latest state; `null` is delivered synchronously when the
|
|
11507
|
+
* measurement clears (pointer-up or deactivate). Emissions are ephemeral by
|
|
11508
|
+
* contract: presence only — never elements, history, or persisted state.
|
|
11509
|
+
*/
|
|
11510
|
+
onMeasurement(listener) {
|
|
11511
|
+
this.measurementListeners.add(listener);
|
|
11512
|
+
return () => this.measurementListeners.delete(listener);
|
|
11513
|
+
}
|
|
11286
11514
|
onPointerDown(state, ctx) {
|
|
11287
11515
|
this.gridSize = ctx.gridSize ?? 1;
|
|
11288
11516
|
this.gridType = ctx.gridType;
|
|
@@ -11290,22 +11518,27 @@ var MeasureTool = class {
|
|
|
11290
11518
|
const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
11291
11519
|
this.start = this.snapToGrid(world, ctx);
|
|
11292
11520
|
this.end = { ...this.start };
|
|
11521
|
+
this.scheduleEmission();
|
|
11293
11522
|
}
|
|
11294
11523
|
onPointerMove(state, ctx) {
|
|
11295
11524
|
if (!this.start) return;
|
|
11296
11525
|
const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
11297
11526
|
this.end = this.snapToGrid(world, ctx);
|
|
11298
11527
|
ctx.requestRender();
|
|
11528
|
+
this.scheduleEmission();
|
|
11299
11529
|
}
|
|
11300
11530
|
onPointerUp(_state, ctx) {
|
|
11301
11531
|
if (!this.start) return;
|
|
11302
11532
|
this.start = null;
|
|
11303
11533
|
this.end = null;
|
|
11304
11534
|
ctx.requestRender();
|
|
11535
|
+
this.emitClear();
|
|
11305
11536
|
}
|
|
11306
11537
|
onDeactivate(_ctx) {
|
|
11538
|
+
const wasActive = this.start !== null;
|
|
11307
11539
|
this.start = null;
|
|
11308
11540
|
this.end = null;
|
|
11541
|
+
if (wasActive) this.emitClear();
|
|
11309
11542
|
}
|
|
11310
11543
|
getMeasurement() {
|
|
11311
11544
|
if (!this.start || !this.end) return null;
|
|
@@ -11331,46 +11564,7 @@ var MeasureTool = class {
|
|
|
11331
11564
|
renderOverlay(ctx) {
|
|
11332
11565
|
const m = this.getMeasurement();
|
|
11333
11566
|
if (!m) return;
|
|
11334
|
-
ctx.
|
|
11335
|
-
ctx.strokeStyle = "#FF5722";
|
|
11336
|
-
ctx.setLineDash([8, 4]);
|
|
11337
|
-
ctx.lineWidth = 2;
|
|
11338
|
-
ctx.beginPath();
|
|
11339
|
-
ctx.moveTo(m.start.x, m.start.y);
|
|
11340
|
-
ctx.lineTo(m.end.x, m.end.y);
|
|
11341
|
-
ctx.stroke();
|
|
11342
|
-
ctx.setLineDash([]);
|
|
11343
|
-
ctx.fillStyle = "#FF5722";
|
|
11344
|
-
const dotRadius = 4;
|
|
11345
|
-
ctx.beginPath();
|
|
11346
|
-
ctx.arc(m.start.x, m.start.y, dotRadius, 0, Math.PI * 2);
|
|
11347
|
-
ctx.fill();
|
|
11348
|
-
ctx.beginPath();
|
|
11349
|
-
ctx.arc(m.end.x, m.end.y, dotRadius, 0, Math.PI * 2);
|
|
11350
|
-
ctx.fill();
|
|
11351
|
-
const label = `${Math.round(m.feet)} ft`;
|
|
11352
|
-
const midX = (m.start.x + m.end.x) / 2;
|
|
11353
|
-
const midY = (m.start.y + m.end.y) / 2;
|
|
11354
|
-
ctx.font = "14px sans-serif";
|
|
11355
|
-
const metrics = ctx.measureText(label);
|
|
11356
|
-
const padX = 6;
|
|
11357
|
-
const padY = 4;
|
|
11358
|
-
const textH = 14;
|
|
11359
|
-
ctx.fillStyle = "rgba(0, 0, 0, 0.75)";
|
|
11360
|
-
ctx.beginPath();
|
|
11361
|
-
ctx.roundRect(
|
|
11362
|
-
midX - metrics.width / 2 - padX,
|
|
11363
|
-
midY - textH / 2 - padY,
|
|
11364
|
-
metrics.width + padX * 2,
|
|
11365
|
-
textH + padY * 2,
|
|
11366
|
-
4
|
|
11367
|
-
);
|
|
11368
|
-
ctx.fill();
|
|
11369
|
-
ctx.fillStyle = "#FFFFFF";
|
|
11370
|
-
ctx.textAlign = "center";
|
|
11371
|
-
ctx.textBaseline = "middle";
|
|
11372
|
-
ctx.fillText(label, midX, midY);
|
|
11373
|
-
ctx.restore();
|
|
11567
|
+
drawMeasurement(ctx, { start: m.start, end: m.end, feet: m.feet, color: this.color });
|
|
11374
11568
|
}
|
|
11375
11569
|
snapToGrid(point, ctx) {
|
|
11376
11570
|
if (!ctx.gridSize) return point;
|
|
@@ -11388,6 +11582,32 @@ var MeasureTool = class {
|
|
|
11388
11582
|
notifyOptionsChange() {
|
|
11389
11583
|
for (const listener of this.optionListeners) listener();
|
|
11390
11584
|
}
|
|
11585
|
+
scheduleEmission() {
|
|
11586
|
+
if (this.measurementListeners.size === 0) return;
|
|
11587
|
+
if (this.emissionRafId !== null) return;
|
|
11588
|
+
this.emissionRafId = requestAnimationFrame(() => {
|
|
11589
|
+
this.emissionRafId = null;
|
|
11590
|
+
const m = this.getMeasurement();
|
|
11591
|
+
if (!m) return;
|
|
11592
|
+
this.emit({ ...m, color: this.color });
|
|
11593
|
+
});
|
|
11594
|
+
}
|
|
11595
|
+
emitClear() {
|
|
11596
|
+
if (this.emissionRafId !== null) {
|
|
11597
|
+
cancelAnimationFrame(this.emissionRafId);
|
|
11598
|
+
this.emissionRafId = null;
|
|
11599
|
+
}
|
|
11600
|
+
if (this.measurementListeners.size === 0) return;
|
|
11601
|
+
this.emit(null);
|
|
11602
|
+
}
|
|
11603
|
+
emit(emission) {
|
|
11604
|
+
for (const listener of this.measurementListeners) {
|
|
11605
|
+
try {
|
|
11606
|
+
listener(emission);
|
|
11607
|
+
} catch {
|
|
11608
|
+
}
|
|
11609
|
+
}
|
|
11610
|
+
}
|
|
11391
11611
|
};
|
|
11392
11612
|
|
|
11393
11613
|
// src/tools/template-tool.ts
|
|
@@ -11683,9 +11903,9 @@ var TemplateTool = class {
|
|
|
11683
11903
|
};
|
|
11684
11904
|
|
|
11685
11905
|
// src/tools/laser-tool.ts
|
|
11686
|
-
var
|
|
11906
|
+
var DEFAULT_COLOR5 = "#ff3b30";
|
|
11687
11907
|
var DEFAULT_WIDTH2 = 4;
|
|
11688
|
-
var
|
|
11908
|
+
var DEFAULT_FADE_MS3 = 1200;
|
|
11689
11909
|
var LaserTool = class {
|
|
11690
11910
|
name;
|
|
11691
11911
|
color;
|
|
@@ -11699,9 +11919,9 @@ var LaserTool = class {
|
|
|
11699
11919
|
pendingEmission = [];
|
|
11700
11920
|
constructor(options = {}) {
|
|
11701
11921
|
this.name = options.name ?? "laser";
|
|
11702
|
-
this.color = options.color ??
|
|
11922
|
+
this.color = options.color ?? DEFAULT_COLOR5;
|
|
11703
11923
|
this.width = options.width ?? DEFAULT_WIDTH2;
|
|
11704
|
-
this.fadeMs = options.fadeMs ??
|
|
11924
|
+
this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS3;
|
|
11705
11925
|
}
|
|
11706
11926
|
now() {
|
|
11707
11927
|
return performance.now();
|
|
@@ -11827,7 +12047,7 @@ var LaserTool = class {
|
|
|
11827
12047
|
};
|
|
11828
12048
|
|
|
11829
12049
|
// src/tools/ping-tool.ts
|
|
11830
|
-
var
|
|
12050
|
+
var DEFAULT_COLOR6 = "#ff3b30";
|
|
11831
12051
|
var DEFAULT_DURATION_MS3 = 1800;
|
|
11832
12052
|
var DEFAULT_RADIUS4 = 48;
|
|
11833
12053
|
var DEFAULT_MIN_INTERVAL_MS2 = 300;
|
|
@@ -11844,7 +12064,7 @@ var PingTool = class {
|
|
|
11844
12064
|
pingListeners = /* @__PURE__ */ new Set();
|
|
11845
12065
|
constructor(options = {}) {
|
|
11846
12066
|
this.name = options.name ?? "ping";
|
|
11847
|
-
this.color = options.color ??
|
|
12067
|
+
this.color = options.color ?? DEFAULT_COLOR6;
|
|
11848
12068
|
this.durationMs = options.durationMs ?? DEFAULT_DURATION_MS3;
|
|
11849
12069
|
this.radius = options.radius ?? DEFAULT_RADIUS4;
|
|
11850
12070
|
this.minIntervalMs = options.minIntervalMs ?? DEFAULT_MIN_INTERVAL_MS2;
|
|
@@ -11947,7 +12167,7 @@ var PingTool = class {
|
|
|
11947
12167
|
};
|
|
11948
12168
|
|
|
11949
12169
|
// src/index.ts
|
|
11950
|
-
var VERSION = "0.
|
|
12170
|
+
var VERSION = "0.57.0";
|
|
11951
12171
|
// Annotate the CommonJS export names for ESM import in node:
|
|
11952
12172
|
0 && (module.exports = {
|
|
11953
12173
|
ArrowTool,
|
|
@@ -11964,6 +12184,7 @@ var VERSION = "0.56.0";
|
|
|
11964
12184
|
LaserTool,
|
|
11965
12185
|
LayerManager,
|
|
11966
12186
|
LocalStorageAdapter,
|
|
12187
|
+
MEASURE_PRESENCE_KIND,
|
|
11967
12188
|
MeasureTool,
|
|
11968
12189
|
MemoryAdapter,
|
|
11969
12190
|
NoteTool,
|
|
@@ -11972,6 +12193,7 @@ var VERSION = "0.56.0";
|
|
|
11972
12193
|
PingInput,
|
|
11973
12194
|
PingTool,
|
|
11974
12195
|
RemoteLaserOverlay,
|
|
12196
|
+
RemoteMeasureOverlay,
|
|
11975
12197
|
RemotePingOverlay,
|
|
11976
12198
|
SelectTool,
|
|
11977
12199
|
ShapeTool,
|
|
@@ -12009,6 +12231,7 @@ var VERSION = "0.56.0";
|
|
|
12009
12231
|
getHexCellsInSquare,
|
|
12010
12232
|
getHexDistance,
|
|
12011
12233
|
isLaserTrailPresence,
|
|
12234
|
+
isMeasurePresence,
|
|
12012
12235
|
isNearBezier,
|
|
12013
12236
|
isPingPresence,
|
|
12014
12237
|
setFontSize,
|
|
@@ -12017,6 +12240,7 @@ var VERSION = "0.56.0";
|
|
|
12017
12240
|
snapToHexCenter,
|
|
12018
12241
|
styleToPatch,
|
|
12019
12242
|
toLaserTrailPresence,
|
|
12243
|
+
toMeasurePresence,
|
|
12020
12244
|
toPingPresence,
|
|
12021
12245
|
toggleBold,
|
|
12022
12246
|
toggleItalic,
|