@fieldnotes/core 0.60.0 → 0.61.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 +390 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +209 -2
- package/dist/index.d.ts +209 -2
- package/dist/index.js +381 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8484,6 +8484,17 @@ var Viewport = class _Viewport {
|
|
|
8484
8484
|
getVisibleRect() {
|
|
8485
8485
|
return this.camera.getVisibleRect(this.canvasEl.clientWidth, this.canvasEl.clientHeight);
|
|
8486
8486
|
}
|
|
8487
|
+
/**
|
|
8488
|
+
* Size in CSS pixels of the canvas that `getVisibleRect()` measures.
|
|
8489
|
+
* Exposed because `canvasEl` is private: consumers can only reach the
|
|
8490
|
+
* wrapper (via `domLayer.parentElement`), so without this accessor the
|
|
8491
|
+
* canonical size behind `getVisibleRect()` is unreachable and callers
|
|
8492
|
+
* resort to `getVisibleRect().w * camera.zoom`. Capture and restore must
|
|
8493
|
+
* measure the same element or saved views do not round-trip.
|
|
8494
|
+
*/
|
|
8495
|
+
getCanvasSize() {
|
|
8496
|
+
return { w: this.canvasEl.clientWidth, h: this.canvasEl.clientHeight };
|
|
8497
|
+
}
|
|
8487
8498
|
/** Centers the camera on a world point without changing zoom. */
|
|
8488
8499
|
centerCameraAt(world) {
|
|
8489
8500
|
const z = this.camera.zoom;
|
|
@@ -9632,6 +9643,361 @@ var PingInput = class {
|
|
|
9632
9643
|
}
|
|
9633
9644
|
};
|
|
9634
9645
|
|
|
9646
|
+
// src/canvas/camera-view.ts
|
|
9647
|
+
function assertValidView(view) {
|
|
9648
|
+
const { x, y, w, h } = view;
|
|
9649
|
+
if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(w) || !Number.isFinite(h)) {
|
|
9650
|
+
throw new Error("[fieldnotes] CameraView requires finite x, y, w, and h");
|
|
9651
|
+
}
|
|
9652
|
+
if (w <= 0 || h <= 0) {
|
|
9653
|
+
throw new Error("[fieldnotes] CameraView requires positive w and h");
|
|
9654
|
+
}
|
|
9655
|
+
}
|
|
9656
|
+
function assertCanvasDims(canvasW, canvasH) {
|
|
9657
|
+
if (!Number.isFinite(canvasW) || !Number.isFinite(canvasH)) {
|
|
9658
|
+
throw new Error("[fieldnotes] canvas dimensions must be finite");
|
|
9659
|
+
}
|
|
9660
|
+
if (canvasW < 0 || canvasH < 0) {
|
|
9661
|
+
throw new Error("[fieldnotes] canvas dimensions must not be negative");
|
|
9662
|
+
}
|
|
9663
|
+
}
|
|
9664
|
+
function canvasDimsUsable(canvasW, canvasH) {
|
|
9665
|
+
return Number.isFinite(canvasW) && Number.isFinite(canvasH) && canvasW >= 0 && canvasH >= 0;
|
|
9666
|
+
}
|
|
9667
|
+
function captureCameraView(viewport) {
|
|
9668
|
+
const rect = viewport.getVisibleRect();
|
|
9669
|
+
return { x: rect.x, y: rect.y, w: rect.w, h: rect.h };
|
|
9670
|
+
}
|
|
9671
|
+
function fitZoomForView(view, canvasW, canvasH) {
|
|
9672
|
+
assertValidView(view);
|
|
9673
|
+
assertCanvasDims(canvasW, canvasH);
|
|
9674
|
+
if (canvasW === 0 || canvasH === 0) {
|
|
9675
|
+
throw new Error("[fieldnotes] fitZoomForView requires a non-zero canvas size");
|
|
9676
|
+
}
|
|
9677
|
+
return Math.min(canvasW / view.w, canvasH / view.h);
|
|
9678
|
+
}
|
|
9679
|
+
function cameraOriginForView(view, zoom, canvasW, canvasH) {
|
|
9680
|
+
return {
|
|
9681
|
+
x: canvasW / 2 - (view.x + view.w / 2) * zoom,
|
|
9682
|
+
y: canvasH / 2 - (view.y + view.h / 2) * zoom
|
|
9683
|
+
};
|
|
9684
|
+
}
|
|
9685
|
+
function applyCameraView(camera, view, canvasW, canvasH) {
|
|
9686
|
+
assertValidView(view);
|
|
9687
|
+
assertCanvasDims(canvasW, canvasH);
|
|
9688
|
+
if (canvasW === 0 || canvasH === 0) return;
|
|
9689
|
+
camera.setZoom(fitZoomForView(view, canvasW, canvasH));
|
|
9690
|
+
const origin = cameraOriginForView(view, camera.zoom, canvasW, canvasH);
|
|
9691
|
+
camera.moveTo(origin.x, origin.y);
|
|
9692
|
+
}
|
|
9693
|
+
|
|
9694
|
+
// src/canvas/camera-animator.ts
|
|
9695
|
+
var DEFAULT_DURATION_MS3 = 400;
|
|
9696
|
+
var FRAMED_EPSILON = 1e-6;
|
|
9697
|
+
var easeOutCubic2 = (t) => 1 - Math.pow(1 - t, 3);
|
|
9698
|
+
function lerp(a, b, k) {
|
|
9699
|
+
return a + (b - a) * k;
|
|
9700
|
+
}
|
|
9701
|
+
function lerpView(from, to, k) {
|
|
9702
|
+
return {
|
|
9703
|
+
x: lerp(from.x, to.x, k),
|
|
9704
|
+
y: lerp(from.y, to.y, k),
|
|
9705
|
+
w: lerp(from.w, to.w, k),
|
|
9706
|
+
h: lerp(from.h, to.h, k)
|
|
9707
|
+
};
|
|
9708
|
+
}
|
|
9709
|
+
function viewsClose(a, b) {
|
|
9710
|
+
return Math.abs(a.x - b.x) < FRAMED_EPSILON && Math.abs(a.y - b.y) < FRAMED_EPSILON && Math.abs(a.w - b.w) < FRAMED_EPSILON && Math.abs(a.h - b.h) < FRAMED_EPSILON;
|
|
9711
|
+
}
|
|
9712
|
+
var CameraAnimator = class {
|
|
9713
|
+
camera;
|
|
9714
|
+
getCanvasSize;
|
|
9715
|
+
frames;
|
|
9716
|
+
now;
|
|
9717
|
+
durationMs;
|
|
9718
|
+
easing;
|
|
9719
|
+
rafId = null;
|
|
9720
|
+
from = null;
|
|
9721
|
+
to = null;
|
|
9722
|
+
startedAt = 0;
|
|
9723
|
+
endListeners = /* @__PURE__ */ new Set();
|
|
9724
|
+
/**
|
|
9725
|
+
* Monotonic operation counter. `animateTo`/`jumpTo` claim a generation
|
|
9726
|
+
* before emitting 'superseded'; if an onEnd listener starts a newer
|
|
9727
|
+
* operation during that emit, the outer call sees a bumped counter and
|
|
9728
|
+
* bails instead of overwriting the nested animation's state. Without this,
|
|
9729
|
+
* the nested animation would run to completion having never reported an end
|
|
9730
|
+
* reason, breaking the exactly-one guarantee the spec makes.
|
|
9731
|
+
*/
|
|
9732
|
+
generation = 0;
|
|
9733
|
+
lastWrite = null;
|
|
9734
|
+
disposed = false;
|
|
9735
|
+
detachListeners = null;
|
|
9736
|
+
constructor(element, camera, options) {
|
|
9737
|
+
if (options.frames !== void 0) {
|
|
9738
|
+
const { requestFrame, cancelFrame } = options.frames;
|
|
9739
|
+
if (typeof requestFrame !== "function" || typeof cancelFrame !== "function") {
|
|
9740
|
+
throw new Error(
|
|
9741
|
+
"[fieldnotes] CameraAnimator: `frames` must supply both requestFrame and cancelFrame"
|
|
9742
|
+
);
|
|
9743
|
+
}
|
|
9744
|
+
}
|
|
9745
|
+
this.camera = camera;
|
|
9746
|
+
this.getCanvasSize = options.getCanvasSize;
|
|
9747
|
+
this.frames = options.frames ?? {
|
|
9748
|
+
requestFrame: (cb) => requestAnimationFrame(cb),
|
|
9749
|
+
cancelFrame: (id) => cancelAnimationFrame(id)
|
|
9750
|
+
};
|
|
9751
|
+
this.now = options.now ?? (() => performance.now());
|
|
9752
|
+
this.durationMs = options.durationMs ?? DEFAULT_DURATION_MS3;
|
|
9753
|
+
this.easing = options.easing ?? easeOutCubic2;
|
|
9754
|
+
if (options.interactive ?? true) {
|
|
9755
|
+
const onUserInput = () => {
|
|
9756
|
+
this.end("cancelled");
|
|
9757
|
+
};
|
|
9758
|
+
const types = ["pointerdown", "wheel", "keydown"];
|
|
9759
|
+
for (const type of types) {
|
|
9760
|
+
element.addEventListener(type, onUserInput, { passive: true });
|
|
9761
|
+
}
|
|
9762
|
+
this.detachListeners = () => {
|
|
9763
|
+
for (const type of types) {
|
|
9764
|
+
element.removeEventListener(type, onUserInput);
|
|
9765
|
+
}
|
|
9766
|
+
};
|
|
9767
|
+
}
|
|
9768
|
+
}
|
|
9769
|
+
get animating() {
|
|
9770
|
+
return this.to !== null;
|
|
9771
|
+
}
|
|
9772
|
+
onEnd(listener) {
|
|
9773
|
+
this.endListeners.add(listener);
|
|
9774
|
+
return () => this.endListeners.delete(listener);
|
|
9775
|
+
}
|
|
9776
|
+
animateTo(view) {
|
|
9777
|
+
const size = this.validateAndMeasure(view);
|
|
9778
|
+
if (size === null) return;
|
|
9779
|
+
const current = this.camera.getVisibleRect(size.w, size.h);
|
|
9780
|
+
const generation = ++this.generation;
|
|
9781
|
+
this.end("superseded");
|
|
9782
|
+
if (this.generation !== generation) return;
|
|
9783
|
+
if (viewsClose(current, view)) {
|
|
9784
|
+
applyCameraView(this.camera, view, size.w, size.h);
|
|
9785
|
+
this.emit("complete");
|
|
9786
|
+
return;
|
|
9787
|
+
}
|
|
9788
|
+
this.from = current;
|
|
9789
|
+
this.to = view;
|
|
9790
|
+
this.startedAt = this.now();
|
|
9791
|
+
this.lastWrite = null;
|
|
9792
|
+
this.rafId = this.frames.requestFrame(this.step);
|
|
9793
|
+
}
|
|
9794
|
+
jumpTo(view) {
|
|
9795
|
+
const size = this.validateAndMeasure(view);
|
|
9796
|
+
if (size === null) return;
|
|
9797
|
+
const generation = ++this.generation;
|
|
9798
|
+
this.end("superseded");
|
|
9799
|
+
if (this.generation !== generation) return;
|
|
9800
|
+
applyCameraView(this.camera, view, size.w, size.h);
|
|
9801
|
+
this.lastWrite = null;
|
|
9802
|
+
}
|
|
9803
|
+
cancel() {
|
|
9804
|
+
if (this.disposed) return;
|
|
9805
|
+
this.end("cancelled");
|
|
9806
|
+
}
|
|
9807
|
+
/**
|
|
9808
|
+
* Terminal. Order is load-bearing: the flag is set BEFORE any listener runs,
|
|
9809
|
+
* because an onEnd listener can call animateTo during the disposal callback.
|
|
9810
|
+
* With the flag set last, that call would start a real animation which the
|
|
9811
|
+
* listener clear then silently discards — a second animation with no end
|
|
9812
|
+
* reason, breaking the exactly-one guarantee.
|
|
9813
|
+
*/
|
|
9814
|
+
dispose() {
|
|
9815
|
+
if (this.disposed) return;
|
|
9816
|
+
this.disposed = true;
|
|
9817
|
+
this.generation++;
|
|
9818
|
+
const wasAnimating = this.to !== null;
|
|
9819
|
+
this.clearFrame();
|
|
9820
|
+
this.from = null;
|
|
9821
|
+
this.to = null;
|
|
9822
|
+
this.lastWrite = null;
|
|
9823
|
+
if (wasAnimating) this.emit("cancelled");
|
|
9824
|
+
this.endListeners.clear();
|
|
9825
|
+
this.detachListeners?.();
|
|
9826
|
+
this.detachListeners = null;
|
|
9827
|
+
}
|
|
9828
|
+
/**
|
|
9829
|
+
* Steps 1-3 of the public-call contract. Returns null when the caller must
|
|
9830
|
+
* stop, having already handled termination.
|
|
9831
|
+
*
|
|
9832
|
+
* The disposed check precedes validation deliberately: ordering it after
|
|
9833
|
+
* would make `disposed.animateTo(invalidView)` both required to throw and
|
|
9834
|
+
* required to stay silent. Disposal wins — a terminal animator is inert for
|
|
9835
|
+
* every input, and post-disposal calls are exactly the racy teardown paths
|
|
9836
|
+
* where a throw is least useful.
|
|
9837
|
+
*/
|
|
9838
|
+
validateAndMeasure(view) {
|
|
9839
|
+
if (this.disposed) return null;
|
|
9840
|
+
assertValidView(view);
|
|
9841
|
+
const size = this.getCanvasSize();
|
|
9842
|
+
assertCanvasDims(size.w, size.h);
|
|
9843
|
+
if (size.w === 0 || size.h === 0) {
|
|
9844
|
+
this.end("cancelled");
|
|
9845
|
+
return null;
|
|
9846
|
+
}
|
|
9847
|
+
return size;
|
|
9848
|
+
}
|
|
9849
|
+
step = () => {
|
|
9850
|
+
if (this.disposed || this.to === null || this.from === null) return;
|
|
9851
|
+
if (this.foreignWrite()) {
|
|
9852
|
+
this.end("cancelled");
|
|
9853
|
+
return;
|
|
9854
|
+
}
|
|
9855
|
+
const size = this.getCanvasSize();
|
|
9856
|
+
if (!canvasDimsUsable(size.w, size.h)) {
|
|
9857
|
+
this.end("cancelled");
|
|
9858
|
+
return;
|
|
9859
|
+
}
|
|
9860
|
+
if (size.w === 0 || size.h === 0) {
|
|
9861
|
+
this.end("cancelled");
|
|
9862
|
+
return;
|
|
9863
|
+
}
|
|
9864
|
+
const elapsed = this.now() - this.startedAt;
|
|
9865
|
+
const t = this.durationMs <= 0 ? 1 : Math.min(1, elapsed / this.durationMs);
|
|
9866
|
+
const view = lerpView(this.from, this.to, this.easing(t));
|
|
9867
|
+
applyCameraView(this.camera, view, size.w, size.h);
|
|
9868
|
+
this.recordWrite();
|
|
9869
|
+
if (t >= 1) {
|
|
9870
|
+
this.end("complete");
|
|
9871
|
+
return;
|
|
9872
|
+
}
|
|
9873
|
+
this.rafId = this.frames.requestFrame(this.step);
|
|
9874
|
+
};
|
|
9875
|
+
recordWrite() {
|
|
9876
|
+
this.lastWrite = {
|
|
9877
|
+
x: this.camera.position.x,
|
|
9878
|
+
y: this.camera.position.y,
|
|
9879
|
+
zoom: this.camera.zoom
|
|
9880
|
+
};
|
|
9881
|
+
}
|
|
9882
|
+
foreignWrite() {
|
|
9883
|
+
if (this.lastWrite === null) return false;
|
|
9884
|
+
const eps = 1e-6;
|
|
9885
|
+
return Math.abs(this.camera.position.x - this.lastWrite.x) > eps || Math.abs(this.camera.position.y - this.lastWrite.y) > eps || Math.abs(this.camera.zoom - this.lastWrite.zoom) > eps;
|
|
9886
|
+
}
|
|
9887
|
+
/** Terminates an in-flight animation with `reason`. No-op when idle. */
|
|
9888
|
+
end(reason) {
|
|
9889
|
+
if (this.disposed || this.to === null) return;
|
|
9890
|
+
this.clearFrame();
|
|
9891
|
+
this.from = null;
|
|
9892
|
+
this.to = null;
|
|
9893
|
+
this.lastWrite = null;
|
|
9894
|
+
this.emit(reason);
|
|
9895
|
+
}
|
|
9896
|
+
clearFrame() {
|
|
9897
|
+
if (this.rafId !== null) {
|
|
9898
|
+
this.frames.cancelFrame(this.rafId);
|
|
9899
|
+
this.rafId = null;
|
|
9900
|
+
}
|
|
9901
|
+
}
|
|
9902
|
+
emit(reason) {
|
|
9903
|
+
for (const listener of [...this.endListeners]) {
|
|
9904
|
+
try {
|
|
9905
|
+
listener(reason);
|
|
9906
|
+
} catch {
|
|
9907
|
+
}
|
|
9908
|
+
}
|
|
9909
|
+
}
|
|
9910
|
+
};
|
|
9911
|
+
|
|
9912
|
+
// src/canvas/focus-presence.ts
|
|
9913
|
+
var FOCUS_PRESENCE_KIND = "focus";
|
|
9914
|
+
var AUDIENCES = ["all", "players", "display"];
|
|
9915
|
+
function isPositiveFinite(value) {
|
|
9916
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
9917
|
+
}
|
|
9918
|
+
function isFiniteNumber2(value) {
|
|
9919
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
9920
|
+
}
|
|
9921
|
+
function isFocusPresence(data) {
|
|
9922
|
+
if (typeof data !== "object" || data === null) return false;
|
|
9923
|
+
const payload = data;
|
|
9924
|
+
if (payload.kind !== FOCUS_PRESENCE_KIND) return false;
|
|
9925
|
+
if (!isFiniteNumber2(payload.x) || !isFiniteNumber2(payload.y)) return false;
|
|
9926
|
+
if (!isPositiveFinite(payload.w) || !isPositiveFinite(payload.h)) return false;
|
|
9927
|
+
if (typeof payload.audience !== "string" || !AUDIENCES.some((a) => a === payload.audience)) {
|
|
9928
|
+
return false;
|
|
9929
|
+
}
|
|
9930
|
+
if (payload.color !== void 0 && typeof payload.color !== "string") return false;
|
|
9931
|
+
return true;
|
|
9932
|
+
}
|
|
9933
|
+
function toFocusPresence(view, audience, color) {
|
|
9934
|
+
return {
|
|
9935
|
+
kind: FOCUS_PRESENCE_KIND,
|
|
9936
|
+
x: view.x,
|
|
9937
|
+
y: view.y,
|
|
9938
|
+
w: view.w,
|
|
9939
|
+
h: view.h,
|
|
9940
|
+
audience,
|
|
9941
|
+
...color === void 0 ? {} : { color }
|
|
9942
|
+
};
|
|
9943
|
+
}
|
|
9944
|
+
|
|
9945
|
+
// src/canvas/remote-focus-receiver.ts
|
|
9946
|
+
function audienceIncludes(audience, role) {
|
|
9947
|
+
if (role === "dm") return false;
|
|
9948
|
+
if (audience === "all") return true;
|
|
9949
|
+
if (audience === "players") return role === "player";
|
|
9950
|
+
return role === "display";
|
|
9951
|
+
}
|
|
9952
|
+
var RemoteFocusReceiver = class {
|
|
9953
|
+
role;
|
|
9954
|
+
animator;
|
|
9955
|
+
animate;
|
|
9956
|
+
pulseColor;
|
|
9957
|
+
overlay;
|
|
9958
|
+
disposed = false;
|
|
9959
|
+
constructor(host, options) {
|
|
9960
|
+
this.role = options.role;
|
|
9961
|
+
this.animator = options.animator;
|
|
9962
|
+
this.animate = options.animate ?? true;
|
|
9963
|
+
this.pulseColor = options.pulseColor;
|
|
9964
|
+
this.overlay = options.pulse ?? true ? new RemotePingOverlay(host, {
|
|
9965
|
+
...options.pulseColor === void 0 ? {} : { color: options.pulseColor },
|
|
9966
|
+
...options.pulseDurationMs === void 0 ? {} : { durationMs: options.pulseDurationMs },
|
|
9967
|
+
...options.pulseRadius === void 0 ? {} : { radius: options.pulseRadius },
|
|
9968
|
+
maxPingsPerSender: 1
|
|
9969
|
+
}) : null;
|
|
9970
|
+
}
|
|
9971
|
+
/**
|
|
9972
|
+
* Applies a presence payload from `sender`. Returns `false` for payloads
|
|
9973
|
+
* that are not focus frames, or are addressed to a different role, so hosts
|
|
9974
|
+
* can feed every presence frame through without disturbing other handlers.
|
|
9975
|
+
*/
|
|
9976
|
+
apply(from, data) {
|
|
9977
|
+
if (this.disposed || !isFocusPresence(data)) return false;
|
|
9978
|
+
if (!audienceIncludes(data.audience, this.role)) return false;
|
|
9979
|
+
const view = { x: data.x, y: data.y, w: data.w, h: data.h };
|
|
9980
|
+
if (this.animate) {
|
|
9981
|
+
this.animator.animateTo(view);
|
|
9982
|
+
} else {
|
|
9983
|
+
this.animator.jumpTo(view);
|
|
9984
|
+
}
|
|
9985
|
+
this.overlay?.apply(from, {
|
|
9986
|
+
kind: "ping",
|
|
9987
|
+
x: view.x + view.w / 2,
|
|
9988
|
+
y: view.y + view.h / 2,
|
|
9989
|
+
color: data.color ?? this.pulseColor
|
|
9990
|
+
});
|
|
9991
|
+
return true;
|
|
9992
|
+
}
|
|
9993
|
+
/** Idempotent. Does NOT dispose the animator — the host owns that. */
|
|
9994
|
+
dispose() {
|
|
9995
|
+
if (this.disposed) return;
|
|
9996
|
+
this.disposed = true;
|
|
9997
|
+
this.overlay?.dispose();
|
|
9998
|
+
}
|
|
9999
|
+
};
|
|
10000
|
+
|
|
9635
10001
|
// src/tools/hand-tool.ts
|
|
9636
10002
|
var HandTool = class {
|
|
9637
10003
|
name = "hand";
|
|
@@ -9820,7 +10186,7 @@ function hitTestStroke(stroke, point, radius) {
|
|
|
9820
10186
|
}
|
|
9821
10187
|
|
|
9822
10188
|
// src/elements/stroke-erase.ts
|
|
9823
|
-
function
|
|
10189
|
+
function lerp2(a, b, t) {
|
|
9824
10190
|
return {
|
|
9825
10191
|
x: a.x + (b.x - a.x) * t,
|
|
9826
10192
|
y: a.y + (b.y - a.y) * t,
|
|
@@ -9879,13 +10245,13 @@ function erasePoints(points, eraser, radius) {
|
|
|
9879
10245
|
erased = true;
|
|
9880
10246
|
if (tLo > 0) {
|
|
9881
10247
|
if (current.length === 0) current.push(a);
|
|
9882
|
-
current.push(
|
|
10248
|
+
current.push(lerp2(a, b, tLo));
|
|
9883
10249
|
flush();
|
|
9884
10250
|
} else {
|
|
9885
10251
|
flush();
|
|
9886
10252
|
}
|
|
9887
10253
|
if (tHi < 1) {
|
|
9888
|
-
current = [
|
|
10254
|
+
current = [lerp2(a, b, tHi), b];
|
|
9889
10255
|
}
|
|
9890
10256
|
}
|
|
9891
10257
|
flush();
|
|
@@ -12341,7 +12707,7 @@ var LaserTool = class {
|
|
|
12341
12707
|
|
|
12342
12708
|
// src/tools/ping-tool.ts
|
|
12343
12709
|
var DEFAULT_COLOR6 = "#ff3b30";
|
|
12344
|
-
var
|
|
12710
|
+
var DEFAULT_DURATION_MS4 = 1800;
|
|
12345
12711
|
var DEFAULT_RADIUS4 = 48;
|
|
12346
12712
|
var DEFAULT_MIN_INTERVAL_MS2 = 300;
|
|
12347
12713
|
var PingTool = class {
|
|
@@ -12358,7 +12724,7 @@ var PingTool = class {
|
|
|
12358
12724
|
constructor(options = {}) {
|
|
12359
12725
|
this.name = options.name ?? "ping";
|
|
12360
12726
|
this.color = options.color ?? DEFAULT_COLOR6;
|
|
12361
|
-
this.durationMs = options.durationMs ??
|
|
12727
|
+
this.durationMs = options.durationMs ?? DEFAULT_DURATION_MS4;
|
|
12362
12728
|
this.radius = options.radius ?? DEFAULT_RADIUS4;
|
|
12363
12729
|
this.minIntervalMs = options.minIntervalMs ?? DEFAULT_MIN_INTERVAL_MS2;
|
|
12364
12730
|
}
|
|
@@ -12460,14 +12826,16 @@ var PingTool = class {
|
|
|
12460
12826
|
};
|
|
12461
12827
|
|
|
12462
12828
|
// src/index.ts
|
|
12463
|
-
var VERSION = "0.
|
|
12829
|
+
var VERSION = "0.61.0";
|
|
12464
12830
|
export {
|
|
12465
12831
|
ArrowTool,
|
|
12466
12832
|
AutoSave,
|
|
12467
12833
|
Camera,
|
|
12834
|
+
CameraAnimator,
|
|
12468
12835
|
DEFAULT_NOTE_FONT_SIZE,
|
|
12469
12836
|
ElementStore,
|
|
12470
12837
|
EraserTool,
|
|
12838
|
+
FOCUS_PRESENCE_KIND,
|
|
12471
12839
|
HandTool,
|
|
12472
12840
|
HistoryStack,
|
|
12473
12841
|
ImageTool,
|
|
@@ -12485,6 +12853,7 @@ export {
|
|
|
12485
12853
|
PencilTool,
|
|
12486
12854
|
PingInput,
|
|
12487
12855
|
PingTool,
|
|
12856
|
+
RemoteFocusReceiver,
|
|
12488
12857
|
RemoteLaserOverlay,
|
|
12489
12858
|
RemoteMeasureOverlay,
|
|
12490
12859
|
RemotePingOverlay,
|
|
@@ -12495,7 +12864,10 @@ export {
|
|
|
12495
12864
|
ToolManager,
|
|
12496
12865
|
VERSION,
|
|
12497
12866
|
Viewport,
|
|
12867
|
+
applyCameraView,
|
|
12498
12868
|
boundsIntersect,
|
|
12869
|
+
cameraOriginForView,
|
|
12870
|
+
captureCameraView,
|
|
12499
12871
|
createArrow,
|
|
12500
12872
|
createGrid,
|
|
12501
12873
|
createHtmlElement,
|
|
@@ -12508,6 +12880,7 @@ export {
|
|
|
12508
12880
|
drawHexPath,
|
|
12509
12881
|
exportImage,
|
|
12510
12882
|
exportSvg,
|
|
12883
|
+
fitZoomForView,
|
|
12511
12884
|
getActiveFormats,
|
|
12512
12885
|
getArrowBounds,
|
|
12513
12886
|
getArrowControlPoint,
|
|
@@ -12523,6 +12896,7 @@ export {
|
|
|
12523
12896
|
getHexCellsInRectangle,
|
|
12524
12897
|
getHexCellsInSquare,
|
|
12525
12898
|
getHexDistance,
|
|
12899
|
+
isFocusPresence,
|
|
12526
12900
|
isLaserTrailPresence,
|
|
12527
12901
|
isMeasurePresence,
|
|
12528
12902
|
isNearBezier,
|
|
@@ -12532,6 +12906,7 @@ export {
|
|
|
12532
12906
|
snapPoint,
|
|
12533
12907
|
snapToHexCenter,
|
|
12534
12908
|
styleToPatch,
|
|
12909
|
+
toFocusPresence,
|
|
12535
12910
|
toLaserTrailPresence,
|
|
12536
12911
|
toMeasurePresence,
|
|
12537
12912
|
toPingPresence,
|