@fieldnotes/core 0.1.2 → 0.2.1
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/README.md +332 -273
- package/dist/index.cjs +249 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -34
- package/dist/index.d.ts +70 -34
- package/dist/index.js +248 -48
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
AddElementCommand: () => AddElementCommand,
|
|
24
24
|
ArrowTool: () => ArrowTool,
|
|
25
|
+
AutoSave: () => AutoSave,
|
|
25
26
|
Background: () => Background,
|
|
26
27
|
BatchCommand: () => BatchCommand,
|
|
27
28
|
Camera: () => Camera,
|
|
@@ -151,8 +152,74 @@ function migrateElement(obj) {
|
|
|
151
152
|
if (obj["type"] === "arrow" && typeof obj["bend"] !== "number") {
|
|
152
153
|
obj["bend"] = 0;
|
|
153
154
|
}
|
|
155
|
+
if (obj["type"] === "stroke" && Array.isArray(obj["points"])) {
|
|
156
|
+
for (const pt of obj["points"]) {
|
|
157
|
+
if (typeof pt["pressure"] !== "number") {
|
|
158
|
+
pt["pressure"] = 0.5;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
154
162
|
}
|
|
155
163
|
|
|
164
|
+
// src/core/auto-save.ts
|
|
165
|
+
var DEFAULT_KEY = "fieldnotes-autosave";
|
|
166
|
+
var DEFAULT_DEBOUNCE_MS = 1e3;
|
|
167
|
+
var AutoSave = class {
|
|
168
|
+
constructor(store, camera, options = {}) {
|
|
169
|
+
this.store = store;
|
|
170
|
+
this.camera = camera;
|
|
171
|
+
this.key = options.key ?? DEFAULT_KEY;
|
|
172
|
+
this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
173
|
+
}
|
|
174
|
+
key;
|
|
175
|
+
debounceMs;
|
|
176
|
+
timerId = null;
|
|
177
|
+
unsubscribers = [];
|
|
178
|
+
start() {
|
|
179
|
+
const schedule = () => this.scheduleSave();
|
|
180
|
+
this.unsubscribers = [
|
|
181
|
+
this.store.on("add", schedule),
|
|
182
|
+
this.store.on("remove", schedule),
|
|
183
|
+
this.store.on("update", schedule),
|
|
184
|
+
this.camera.onChange(schedule)
|
|
185
|
+
];
|
|
186
|
+
}
|
|
187
|
+
stop() {
|
|
188
|
+
this.cancelPending();
|
|
189
|
+
this.unsubscribers.forEach((fn) => fn());
|
|
190
|
+
this.unsubscribers = [];
|
|
191
|
+
}
|
|
192
|
+
load() {
|
|
193
|
+
if (typeof localStorage === "undefined") return null;
|
|
194
|
+
const json = localStorage.getItem(this.key);
|
|
195
|
+
if (!json) return null;
|
|
196
|
+
try {
|
|
197
|
+
return parseState(json);
|
|
198
|
+
} catch {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
clear() {
|
|
203
|
+
if (typeof localStorage === "undefined") return;
|
|
204
|
+
localStorage.removeItem(this.key);
|
|
205
|
+
}
|
|
206
|
+
scheduleSave() {
|
|
207
|
+
this.cancelPending();
|
|
208
|
+
this.timerId = setTimeout(() => this.save(), this.debounceMs);
|
|
209
|
+
}
|
|
210
|
+
cancelPending() {
|
|
211
|
+
if (this.timerId !== null) {
|
|
212
|
+
clearTimeout(this.timerId);
|
|
213
|
+
this.timerId = null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
save() {
|
|
217
|
+
if (typeof localStorage === "undefined") return;
|
|
218
|
+
const state = exportState(this.store.snapshot(), this.camera);
|
|
219
|
+
localStorage.setItem(this.key, JSON.stringify(state));
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
156
223
|
// src/canvas/camera.ts
|
|
157
224
|
var DEFAULT_MIN_ZOOM = 0.1;
|
|
158
225
|
var DEFAULT_MAX_ZOOM = 10;
|
|
@@ -347,24 +414,8 @@ var InputHandler = class {
|
|
|
347
414
|
y: e.clientY - rect.top
|
|
348
415
|
});
|
|
349
416
|
};
|
|
350
|
-
isInteractiveHtmlContent(e) {
|
|
351
|
-
const target = e.target;
|
|
352
|
-
if (!target) return false;
|
|
353
|
-
const node = target.closest("[data-element-id]");
|
|
354
|
-
if (!node) return false;
|
|
355
|
-
const elementId = node.dataset["elementId"];
|
|
356
|
-
if (!elementId) return false;
|
|
357
|
-
const store = this.toolContext?.store;
|
|
358
|
-
if (!store) return false;
|
|
359
|
-
const element = store.getById(elementId);
|
|
360
|
-
if (!element || element.type !== "html") return false;
|
|
361
|
-
return true;
|
|
362
|
-
}
|
|
363
417
|
onPointerDown = (e) => {
|
|
364
418
|
this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });
|
|
365
|
-
if (this.isInteractiveHtmlContent(e)) {
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
419
|
this.element.setPointerCapture?.(e.pointerId);
|
|
369
420
|
if (this.activePointers.size === 2) {
|
|
370
421
|
this.startPinch();
|
|
@@ -690,6 +741,79 @@ function isNearLine(point, a, b, threshold) {
|
|
|
690
741
|
return Math.hypot(point.x - projX, point.y - projY) <= threshold;
|
|
691
742
|
}
|
|
692
743
|
|
|
744
|
+
// src/elements/stroke-smoothing.ts
|
|
745
|
+
var MIN_PRESSURE_SCALE = 0.2;
|
|
746
|
+
function pressureToWidth(pressure, baseWidth) {
|
|
747
|
+
return baseWidth * (MIN_PRESSURE_SCALE + (1 - MIN_PRESSURE_SCALE) * pressure);
|
|
748
|
+
}
|
|
749
|
+
function simplifyPoints(points, tolerance) {
|
|
750
|
+
if (points.length <= 2) return points.slice();
|
|
751
|
+
return rdp(points, 0, points.length - 1, tolerance);
|
|
752
|
+
}
|
|
753
|
+
function rdp(points, start, end, tolerance) {
|
|
754
|
+
const first = points[start];
|
|
755
|
+
const last = points[end];
|
|
756
|
+
if (!first || !last) return [];
|
|
757
|
+
if (end - start <= 1) return [first, last];
|
|
758
|
+
let maxDist = 0;
|
|
759
|
+
let maxIndex = start;
|
|
760
|
+
for (let i = start + 1; i < end; i++) {
|
|
761
|
+
const pt = points[i];
|
|
762
|
+
if (!pt) continue;
|
|
763
|
+
const dist = perpendicularDistance(pt, first, last);
|
|
764
|
+
if (dist > maxDist) {
|
|
765
|
+
maxDist = dist;
|
|
766
|
+
maxIndex = i;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
if (maxDist <= tolerance) return [first, last];
|
|
770
|
+
const left = rdp(points, start, maxIndex, tolerance);
|
|
771
|
+
const right = rdp(points, maxIndex, end, tolerance);
|
|
772
|
+
return left.concat(right.slice(1));
|
|
773
|
+
}
|
|
774
|
+
function perpendicularDistance(pt, lineStart, lineEnd) {
|
|
775
|
+
const dx = lineEnd.x - lineStart.x;
|
|
776
|
+
const dy = lineEnd.y - lineStart.y;
|
|
777
|
+
const lenSq = dx * dx + dy * dy;
|
|
778
|
+
if (lenSq === 0) {
|
|
779
|
+
const ex = pt.x - lineStart.x;
|
|
780
|
+
const ey = pt.y - lineStart.y;
|
|
781
|
+
return Math.sqrt(ex * ex + ey * ey);
|
|
782
|
+
}
|
|
783
|
+
const num = Math.abs(dy * pt.x - dx * pt.y + lineEnd.x * lineStart.y - lineEnd.y * lineStart.x);
|
|
784
|
+
return num / Math.sqrt(lenSq);
|
|
785
|
+
}
|
|
786
|
+
function smoothToSegments(points) {
|
|
787
|
+
if (points.length < 2) return [];
|
|
788
|
+
if (points.length === 2) {
|
|
789
|
+
const p0 = points[0];
|
|
790
|
+
const p1 = points[1];
|
|
791
|
+
if (!p0 || !p1) return [];
|
|
792
|
+
const mx = (p0.x + p1.x) / 2;
|
|
793
|
+
const my = (p0.y + p1.y) / 2;
|
|
794
|
+
return [{ start: p0, cp1: { x: mx, y: my }, cp2: { x: mx, y: my }, end: p1 }];
|
|
795
|
+
}
|
|
796
|
+
const segments = [];
|
|
797
|
+
const n = points.length;
|
|
798
|
+
for (let i = 0; i < n - 1; i++) {
|
|
799
|
+
const p0 = points[Math.max(0, i - 1)];
|
|
800
|
+
const p1 = points[i];
|
|
801
|
+
const p2 = points[i + 1];
|
|
802
|
+
const p3 = points[Math.min(n - 1, i + 2)];
|
|
803
|
+
if (!p0 || !p1 || !p2 || !p3) continue;
|
|
804
|
+
const cp1 = {
|
|
805
|
+
x: p1.x + (p2.x - p0.x) / 6,
|
|
806
|
+
y: p1.y + (p2.y - p0.y) / 6
|
|
807
|
+
};
|
|
808
|
+
const cp2 = {
|
|
809
|
+
x: p2.x - (p3.x - p1.x) / 6,
|
|
810
|
+
y: p2.y - (p3.y - p1.y) / 6
|
|
811
|
+
};
|
|
812
|
+
segments.push({ start: p1, cp1, cp2, end: p2 });
|
|
813
|
+
}
|
|
814
|
+
return segments;
|
|
815
|
+
}
|
|
816
|
+
|
|
693
817
|
// src/elements/element-renderer.ts
|
|
694
818
|
var DOM_ELEMENT_TYPES = /* @__PURE__ */ new Set(["note", "image", "html"]);
|
|
695
819
|
var ARROWHEAD_LENGTH = 12;
|
|
@@ -713,22 +837,18 @@ var ElementRenderer = class {
|
|
|
713
837
|
ctx.save();
|
|
714
838
|
ctx.translate(stroke.position.x, stroke.position.y);
|
|
715
839
|
ctx.strokeStyle = stroke.color;
|
|
716
|
-
ctx.lineWidth = stroke.width;
|
|
717
840
|
ctx.lineCap = "round";
|
|
718
841
|
ctx.lineJoin = "round";
|
|
719
842
|
ctx.globalAlpha = stroke.opacity;
|
|
720
|
-
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
ctx.
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
ctx.lineTo(pt.x, pt.y);
|
|
729
|
-
}
|
|
843
|
+
const segments = smoothToSegments(stroke.points);
|
|
844
|
+
for (const seg of segments) {
|
|
845
|
+
const w = (pressureToWidth(seg.start.pressure, stroke.width) + pressureToWidth(seg.end.pressure, stroke.width)) / 2;
|
|
846
|
+
ctx.lineWidth = w;
|
|
847
|
+
ctx.beginPath();
|
|
848
|
+
ctx.moveTo(seg.start.x, seg.start.y);
|
|
849
|
+
ctx.bezierCurveTo(seg.cp1.x, seg.cp1.y, seg.cp2.x, seg.cp2.y, seg.end.x, seg.end.y);
|
|
850
|
+
ctx.stroke();
|
|
730
851
|
}
|
|
731
|
-
ctx.stroke();
|
|
732
852
|
ctx.restore();
|
|
733
853
|
}
|
|
734
854
|
renderArrow(ctx, arrow) {
|
|
@@ -871,6 +991,9 @@ var ToolManager = class {
|
|
|
871
991
|
register(tool) {
|
|
872
992
|
this.tools.set(tool.name, tool);
|
|
873
993
|
}
|
|
994
|
+
getTool(name) {
|
|
995
|
+
return this.tools.get(name);
|
|
996
|
+
}
|
|
874
997
|
setTool(name, ctx) {
|
|
875
998
|
const tool = this.tools.get(name);
|
|
876
999
|
if (!tool) return;
|
|
@@ -1230,6 +1353,7 @@ var Viewport = class {
|
|
|
1230
1353
|
needsRender = true;
|
|
1231
1354
|
domNodes = /* @__PURE__ */ new Map();
|
|
1232
1355
|
htmlContent = /* @__PURE__ */ new Map();
|
|
1356
|
+
interactingElementId = null;
|
|
1233
1357
|
get ctx() {
|
|
1234
1358
|
return this.canvasEl.getContext("2d");
|
|
1235
1359
|
}
|
|
@@ -1275,6 +1399,7 @@ var Viewport = class {
|
|
|
1275
1399
|
this.store.add(image);
|
|
1276
1400
|
this.historyRecorder.commit();
|
|
1277
1401
|
this.requestRender();
|
|
1402
|
+
return image.id;
|
|
1278
1403
|
}
|
|
1279
1404
|
addHtmlElement(dom, position, size = { w: 200, h: 150 }) {
|
|
1280
1405
|
const el = createHtmlElement({ position, size });
|
|
@@ -1287,6 +1412,7 @@ var Viewport = class {
|
|
|
1287
1412
|
}
|
|
1288
1413
|
destroy() {
|
|
1289
1414
|
cancelAnimationFrame(this.animFrameId);
|
|
1415
|
+
this.stopInteracting();
|
|
1290
1416
|
this.noteEditor.destroy(this.store);
|
|
1291
1417
|
this.historyRecorder.destroy();
|
|
1292
1418
|
this.wrapper.removeEventListener("dblclick", this.onDblClick);
|
|
@@ -1344,11 +1470,69 @@ var Viewport = class {
|
|
|
1344
1470
|
}
|
|
1345
1471
|
onDblClick = (e) => {
|
|
1346
1472
|
const el = document.elementFromPoint(e.clientX, e.clientY);
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1473
|
+
const nodeEl = el?.closest("[data-element-id]");
|
|
1474
|
+
if (nodeEl) {
|
|
1475
|
+
const elementId = nodeEl.dataset["elementId"];
|
|
1476
|
+
if (elementId) {
|
|
1477
|
+
const element = this.store.getById(elementId);
|
|
1478
|
+
if (element?.type === "note") {
|
|
1479
|
+
this.startEditingNote(elementId);
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
const rect = this.wrapper.getBoundingClientRect();
|
|
1485
|
+
const screen = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
|
1486
|
+
const world = this.camera.screenToWorld(screen);
|
|
1487
|
+
const hit = this.hitTestWorld(world);
|
|
1488
|
+
if (hit?.type === "html") {
|
|
1489
|
+
this.startInteracting(hit.id);
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1492
|
+
hitTestWorld(world) {
|
|
1493
|
+
const elements = this.store.getAll().reverse();
|
|
1494
|
+
for (const el of elements) {
|
|
1495
|
+
if (!("size" in el)) continue;
|
|
1496
|
+
const { x, y } = el.position;
|
|
1497
|
+
const { w, h } = el.size;
|
|
1498
|
+
if (world.x >= x && world.x <= x + w && world.y >= y && world.y <= y + h) {
|
|
1499
|
+
return el;
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
return null;
|
|
1503
|
+
}
|
|
1504
|
+
startInteracting(id) {
|
|
1505
|
+
this.stopInteracting();
|
|
1506
|
+
const node = this.domNodes.get(id);
|
|
1507
|
+
if (!node) return;
|
|
1508
|
+
this.interactingElementId = id;
|
|
1509
|
+
node.style.pointerEvents = "auto";
|
|
1510
|
+
window.addEventListener("keydown", this.onInteractKeyDown);
|
|
1511
|
+
window.addEventListener("pointerdown", this.onInteractPointerDown);
|
|
1512
|
+
}
|
|
1513
|
+
stopInteracting() {
|
|
1514
|
+
if (!this.interactingElementId) return;
|
|
1515
|
+
const node = this.domNodes.get(this.interactingElementId);
|
|
1516
|
+
if (node) {
|
|
1517
|
+
node.style.pointerEvents = "none";
|
|
1518
|
+
}
|
|
1519
|
+
this.interactingElementId = null;
|
|
1520
|
+
window.removeEventListener("keydown", this.onInteractKeyDown);
|
|
1521
|
+
window.removeEventListener("pointerdown", this.onInteractPointerDown);
|
|
1522
|
+
}
|
|
1523
|
+
onInteractKeyDown = (e) => {
|
|
1524
|
+
if (e.key === "Escape") {
|
|
1525
|
+
this.stopInteracting();
|
|
1526
|
+
}
|
|
1527
|
+
};
|
|
1528
|
+
onInteractPointerDown = (e) => {
|
|
1529
|
+
if (!this.interactingElementId) return;
|
|
1530
|
+
const target = e.target;
|
|
1531
|
+
if (!target) return;
|
|
1532
|
+
const node = this.domNodes.get(this.interactingElementId);
|
|
1533
|
+
if (node && !node.contains(target)) {
|
|
1534
|
+
this.stopInteracting();
|
|
1535
|
+
}
|
|
1352
1536
|
};
|
|
1353
1537
|
onDragOver = (e) => {
|
|
1354
1538
|
e.preventDefault();
|
|
@@ -1446,7 +1630,8 @@ var Viewport = class {
|
|
|
1446
1630
|
if (content) {
|
|
1447
1631
|
node.dataset["initialized"] = "true";
|
|
1448
1632
|
Object.assign(node.style, {
|
|
1449
|
-
overflow: "hidden"
|
|
1633
|
+
overflow: "hidden",
|
|
1634
|
+
pointerEvents: "none"
|
|
1450
1635
|
});
|
|
1451
1636
|
node.appendChild(content);
|
|
1452
1637
|
}
|
|
@@ -1549,15 +1734,19 @@ var HandTool = class {
|
|
|
1549
1734
|
|
|
1550
1735
|
// src/tools/pencil-tool.ts
|
|
1551
1736
|
var MIN_POINTS_FOR_STROKE = 2;
|
|
1737
|
+
var DEFAULT_SMOOTHING = 1.5;
|
|
1738
|
+
var DEFAULT_PRESSURE = 0.5;
|
|
1552
1739
|
var PencilTool = class {
|
|
1553
1740
|
name = "pencil";
|
|
1554
1741
|
drawing = false;
|
|
1555
1742
|
points = [];
|
|
1556
1743
|
color;
|
|
1557
1744
|
width;
|
|
1745
|
+
smoothing;
|
|
1558
1746
|
constructor(options = {}) {
|
|
1559
1747
|
this.color = options.color ?? "#000000";
|
|
1560
1748
|
this.width = options.width ?? 2;
|
|
1749
|
+
this.smoothing = options.smoothing ?? DEFAULT_SMOOTHING;
|
|
1561
1750
|
}
|
|
1562
1751
|
onActivate(ctx) {
|
|
1563
1752
|
ctx.setCursor?.("crosshair");
|
|
@@ -1568,16 +1757,19 @@ var PencilTool = class {
|
|
|
1568
1757
|
setOptions(options) {
|
|
1569
1758
|
if (options.color !== void 0) this.color = options.color;
|
|
1570
1759
|
if (options.width !== void 0) this.width = options.width;
|
|
1760
|
+
if (options.smoothing !== void 0) this.smoothing = options.smoothing;
|
|
1571
1761
|
}
|
|
1572
1762
|
onPointerDown(state, ctx) {
|
|
1573
1763
|
this.drawing = true;
|
|
1574
1764
|
const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
1575
|
-
|
|
1765
|
+
const pressure = state.pressure === 0 ? DEFAULT_PRESSURE : state.pressure;
|
|
1766
|
+
this.points = [{ x: world.x, y: world.y, pressure }];
|
|
1576
1767
|
}
|
|
1577
1768
|
onPointerMove(state, ctx) {
|
|
1578
1769
|
if (!this.drawing) return;
|
|
1579
1770
|
const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
1580
|
-
|
|
1771
|
+
const pressure = state.pressure === 0 ? DEFAULT_PRESSURE : state.pressure;
|
|
1772
|
+
this.points.push({ x: world.x, y: world.y, pressure });
|
|
1581
1773
|
ctx.requestRender();
|
|
1582
1774
|
}
|
|
1583
1775
|
onPointerUp(_state, ctx) {
|
|
@@ -1587,8 +1779,9 @@ var PencilTool = class {
|
|
|
1587
1779
|
this.points = [];
|
|
1588
1780
|
return;
|
|
1589
1781
|
}
|
|
1782
|
+
const simplified = simplifyPoints(this.points, this.smoothing);
|
|
1590
1783
|
const stroke = createStroke({
|
|
1591
|
-
points:
|
|
1784
|
+
points: simplified,
|
|
1592
1785
|
color: this.color,
|
|
1593
1786
|
width: this.width
|
|
1594
1787
|
});
|
|
@@ -1600,19 +1793,18 @@ var PencilTool = class {
|
|
|
1600
1793
|
if (!this.drawing || this.points.length < 2) return;
|
|
1601
1794
|
ctx.save();
|
|
1602
1795
|
ctx.strokeStyle = this.color;
|
|
1603
|
-
ctx.lineWidth = this.width;
|
|
1604
1796
|
ctx.lineCap = "round";
|
|
1605
1797
|
ctx.lineJoin = "round";
|
|
1606
1798
|
ctx.globalAlpha = 0.8;
|
|
1607
|
-
|
|
1608
|
-
const
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1799
|
+
const segments = smoothToSegments(this.points);
|
|
1800
|
+
for (const seg of segments) {
|
|
1801
|
+
const w = (pressureToWidth(seg.start.pressure, this.width) + pressureToWidth(seg.end.pressure, this.width)) / 2;
|
|
1802
|
+
ctx.lineWidth = w;
|
|
1803
|
+
ctx.beginPath();
|
|
1804
|
+
ctx.moveTo(seg.start.x, seg.start.y);
|
|
1805
|
+
ctx.bezierCurveTo(seg.cp1.x, seg.cp1.y, seg.cp2.x, seg.cp2.y, seg.end.x, seg.end.y);
|
|
1806
|
+
ctx.stroke();
|
|
1614
1807
|
}
|
|
1615
|
-
ctx.stroke();
|
|
1616
1808
|
ctx.restore();
|
|
1617
1809
|
}
|
|
1618
1810
|
};
|
|
@@ -1900,7 +2092,7 @@ var SelectTool = class {
|
|
|
1900
2092
|
handleResize(world, ctx) {
|
|
1901
2093
|
if (this.mode.type !== "resizing") return;
|
|
1902
2094
|
const el = ctx.store.getById(this.mode.elementId);
|
|
1903
|
-
if (!el || !("size" in el)) return;
|
|
2095
|
+
if (!el || !("size" in el) || el.locked) return;
|
|
1904
2096
|
const { handle } = this.mode;
|
|
1905
2097
|
const dx = world.x - this.lastWorld.x;
|
|
1906
2098
|
const dy = world.y - this.lastWorld.y;
|
|
@@ -2107,6 +2299,10 @@ var ArrowTool = class {
|
|
|
2107
2299
|
this.color = options.color ?? "#000000";
|
|
2108
2300
|
this.width = options.width ?? 2;
|
|
2109
2301
|
}
|
|
2302
|
+
setOptions(options) {
|
|
2303
|
+
if (options.color !== void 0) this.color = options.color;
|
|
2304
|
+
if (options.width !== void 0) this.width = options.width;
|
|
2305
|
+
}
|
|
2110
2306
|
onPointerDown(state, ctx) {
|
|
2111
2307
|
this.drawing = true;
|
|
2112
2308
|
this.start = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
@@ -2171,6 +2367,10 @@ var NoteTool = class {
|
|
|
2171
2367
|
this.backgroundColor = options.backgroundColor ?? "#ffeb3b";
|
|
2172
2368
|
this.size = options.size ?? { w: 200, h: 100 };
|
|
2173
2369
|
}
|
|
2370
|
+
setOptions(options) {
|
|
2371
|
+
if (options.backgroundColor !== void 0) this.backgroundColor = options.backgroundColor;
|
|
2372
|
+
if (options.size !== void 0) this.size = options.size;
|
|
2373
|
+
}
|
|
2174
2374
|
onPointerDown(_state, _ctx) {
|
|
2175
2375
|
}
|
|
2176
2376
|
onPointerMove(_state, _ctx) {
|
|
@@ -2220,11 +2420,12 @@ var ImageTool = class {
|
|
|
2220
2420
|
};
|
|
2221
2421
|
|
|
2222
2422
|
// src/index.ts
|
|
2223
|
-
var VERSION = "0.1
|
|
2423
|
+
var VERSION = "0.2.1";
|
|
2224
2424
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2225
2425
|
0 && (module.exports = {
|
|
2226
2426
|
AddElementCommand,
|
|
2227
2427
|
ArrowTool,
|
|
2428
|
+
AutoSave,
|
|
2228
2429
|
Background,
|
|
2229
2430
|
BatchCommand,
|
|
2230
2431
|
Camera,
|