@fieldnotes/core 0.41.0 → 0.42.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 +97 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +97 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1554,6 +1554,81 @@ var KeyboardHandler = class {
|
|
|
1554
1554
|
}
|
|
1555
1555
|
};
|
|
1556
1556
|
|
|
1557
|
+
// src/canvas/pan-inertia.ts
|
|
1558
|
+
var VELOCITY_WINDOW_MS = 60;
|
|
1559
|
+
var FRICTION = 0.92;
|
|
1560
|
+
var MIN_START_SPEED = 2;
|
|
1561
|
+
var MIN_STOP_SPEED = 0.3;
|
|
1562
|
+
var PanInertia = class {
|
|
1563
|
+
constructor(deps) {
|
|
1564
|
+
this.deps = deps;
|
|
1565
|
+
}
|
|
1566
|
+
samples = [];
|
|
1567
|
+
vx = 0;
|
|
1568
|
+
vy = 0;
|
|
1569
|
+
rafId = null;
|
|
1570
|
+
sample(dx, dy) {
|
|
1571
|
+
const t = this.deps.now();
|
|
1572
|
+
this.samples.push({ dx, dy, t });
|
|
1573
|
+
this.prune(t);
|
|
1574
|
+
}
|
|
1575
|
+
release() {
|
|
1576
|
+
if (!this.deps.enabled()) {
|
|
1577
|
+
this.reset();
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1580
|
+
const t = this.deps.now();
|
|
1581
|
+
this.prune(t);
|
|
1582
|
+
const recent = this.samples;
|
|
1583
|
+
if (recent.length === 0) {
|
|
1584
|
+
this.reset();
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1587
|
+
let sx = 0;
|
|
1588
|
+
let sy = 0;
|
|
1589
|
+
for (const s of recent) {
|
|
1590
|
+
sx += s.dx;
|
|
1591
|
+
sy += s.dy;
|
|
1592
|
+
}
|
|
1593
|
+
this.vx = sx / recent.length;
|
|
1594
|
+
this.vy = sy / recent.length;
|
|
1595
|
+
this.samples = [];
|
|
1596
|
+
if (Math.hypot(this.vx, this.vy) < MIN_START_SPEED) {
|
|
1597
|
+
this.vx = 0;
|
|
1598
|
+
this.vy = 0;
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1601
|
+
this.rafId = this.deps.requestFrame(this.step);
|
|
1602
|
+
}
|
|
1603
|
+
cancel() {
|
|
1604
|
+
this.reset();
|
|
1605
|
+
}
|
|
1606
|
+
step = () => {
|
|
1607
|
+
if (this.rafId === null) return;
|
|
1608
|
+
this.deps.pan(this.vx, this.vy);
|
|
1609
|
+
this.vx *= FRICTION;
|
|
1610
|
+
this.vy *= FRICTION;
|
|
1611
|
+
if (Math.hypot(this.vx, this.vy) >= MIN_STOP_SPEED) {
|
|
1612
|
+
this.rafId = this.deps.requestFrame(this.step);
|
|
1613
|
+
} else {
|
|
1614
|
+
this.reset();
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1617
|
+
prune(now) {
|
|
1618
|
+
const cutoff = now - VELOCITY_WINDOW_MS;
|
|
1619
|
+
this.samples = this.samples.filter((s) => s.t >= cutoff);
|
|
1620
|
+
}
|
|
1621
|
+
reset() {
|
|
1622
|
+
if (this.rafId !== null) {
|
|
1623
|
+
this.deps.cancelFrame(this.rafId);
|
|
1624
|
+
this.rafId = null;
|
|
1625
|
+
}
|
|
1626
|
+
this.samples = [];
|
|
1627
|
+
this.vx = 0;
|
|
1628
|
+
this.vy = 0;
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
|
|
1557
1632
|
// src/canvas/input-handler.ts
|
|
1558
1633
|
var ZOOM_SENSITIVITY = 1e-3;
|
|
1559
1634
|
var MIDDLE_BUTTON = 1;
|
|
@@ -1579,6 +1654,16 @@ var InputHandler = class {
|
|
|
1579
1654
|
getLastPointerWorld: () => this.lastPointerWorld()
|
|
1580
1655
|
});
|
|
1581
1656
|
this.openContextMenu = options.openContextMenu;
|
|
1657
|
+
this.panInertiaEnabled = options.panInertia ?? true;
|
|
1658
|
+
this.panInertia = new PanInertia({
|
|
1659
|
+
pan: (dx, dy) => this.camera.pan(dx, dy),
|
|
1660
|
+
now: () => typeof performance !== "undefined" ? performance.now() : Date.now(),
|
|
1661
|
+
requestFrame: (cb) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(cb) : 0,
|
|
1662
|
+
cancelFrame: (id) => {
|
|
1663
|
+
if (typeof cancelAnimationFrame !== "undefined") cancelAnimationFrame(id);
|
|
1664
|
+
},
|
|
1665
|
+
enabled: () => this.panInertiaEnabled
|
|
1666
|
+
});
|
|
1582
1667
|
this.scope = options.shortcuts?.scope ?? "focus";
|
|
1583
1668
|
this.keyboard = new KeyboardHandler({
|
|
1584
1669
|
element: this.element,
|
|
@@ -1628,6 +1713,8 @@ var InputHandler = class {
|
|
|
1628
1713
|
keyboard;
|
|
1629
1714
|
scope;
|
|
1630
1715
|
openContextMenu;
|
|
1716
|
+
panInertia;
|
|
1717
|
+
panInertiaEnabled;
|
|
1631
1718
|
setToolManager(toolManager, toolContext) {
|
|
1632
1719
|
this.toolManager = toolManager;
|
|
1633
1720
|
this.toolContext = toolContext;
|
|
@@ -1639,6 +1726,7 @@ var InputHandler = class {
|
|
|
1639
1726
|
return this.keyboard.shortcuts;
|
|
1640
1727
|
}
|
|
1641
1728
|
destroy() {
|
|
1729
|
+
this.panInertia.cancel();
|
|
1642
1730
|
this.actions.dispose();
|
|
1643
1731
|
this.abortController.abort();
|
|
1644
1732
|
this.inputFilter.reset();
|
|
@@ -1662,6 +1750,7 @@ var InputHandler = class {
|
|
|
1662
1750
|
}
|
|
1663
1751
|
onWheel = (e) => {
|
|
1664
1752
|
e.preventDefault();
|
|
1753
|
+
this.panInertia.cancel();
|
|
1665
1754
|
const rect = this.element.getBoundingClientRect();
|
|
1666
1755
|
const zoomFactor = 1 - e.deltaY * ZOOM_SENSITIVITY;
|
|
1667
1756
|
const newZoom = this.camera.zoom * zoomFactor;
|
|
@@ -1671,6 +1760,7 @@ var InputHandler = class {
|
|
|
1671
1760
|
});
|
|
1672
1761
|
};
|
|
1673
1762
|
onPointerDown = (e) => {
|
|
1763
|
+
this.panInertia.cancel();
|
|
1674
1764
|
this.focusSelf();
|
|
1675
1765
|
this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });
|
|
1676
1766
|
this.element.setPointerCapture?.(e.pointerId);
|
|
@@ -1711,6 +1801,7 @@ var InputHandler = class {
|
|
|
1711
1801
|
const dy = e.clientY - this.lastPointer.y;
|
|
1712
1802
|
this.lastPointer = { x: e.clientX, y: e.clientY };
|
|
1713
1803
|
this.camera.pan(dx, dy);
|
|
1804
|
+
this.panInertia.sample(dx, dy);
|
|
1714
1805
|
return;
|
|
1715
1806
|
}
|
|
1716
1807
|
if (e.pointerType === "pen" && !this.activePointers.has(e.pointerId)) {
|
|
@@ -1741,6 +1832,7 @@ var InputHandler = class {
|
|
|
1741
1832
|
}
|
|
1742
1833
|
if (this.isPanning && this.activePointers.size === 0) {
|
|
1743
1834
|
this.isPanning = false;
|
|
1835
|
+
this.panInertia.release();
|
|
1744
1836
|
}
|
|
1745
1837
|
const upResult = this.inputFilter.filterUp(e);
|
|
1746
1838
|
if (this.isToolActive) {
|
|
@@ -1761,6 +1853,7 @@ var InputHandler = class {
|
|
|
1761
1853
|
return this.actions.hasClipboard();
|
|
1762
1854
|
}
|
|
1763
1855
|
startPinch() {
|
|
1856
|
+
this.panInertia.cancel();
|
|
1764
1857
|
this.cancelLongPress();
|
|
1765
1858
|
this.inputFilter.reset();
|
|
1766
1859
|
this.deferredDown = null;
|
|
@@ -1782,6 +1875,7 @@ var InputHandler = class {
|
|
|
1782
1875
|
const dx = center2.x - this.lastPointer.x;
|
|
1783
1876
|
const dy = center2.y - this.lastPointer.y;
|
|
1784
1877
|
this.camera.pan(dx, dy);
|
|
1878
|
+
this.panInertia.sample(dx, dy);
|
|
1785
1879
|
this.lastPinchDistance = dist;
|
|
1786
1880
|
this.lastPinchCenter = center2;
|
|
1787
1881
|
this.lastPointer = { ...center2 };
|
|
@@ -6883,7 +6977,8 @@ var Viewport = class {
|
|
|
6883
6977
|
shortcuts: options.shortcuts,
|
|
6884
6978
|
addImage: (src, world) => this.addImage(src, world),
|
|
6885
6979
|
getCenteredWorld: () => this.centeredPosition({ w: 300, h: 200 }),
|
|
6886
|
-
onPaste: options.onPaste
|
|
6980
|
+
onPaste: options.onPaste,
|
|
6981
|
+
panInertia: options.panInertia
|
|
6887
6982
|
});
|
|
6888
6983
|
if (options.contextMenu !== false) {
|
|
6889
6984
|
this.contextMenu = new ContextMenu({
|
|
@@ -9798,7 +9893,7 @@ var LaserTool = class {
|
|
|
9798
9893
|
};
|
|
9799
9894
|
|
|
9800
9895
|
// src/index.ts
|
|
9801
|
-
var VERSION = "0.
|
|
9896
|
+
var VERSION = "0.42.0";
|
|
9802
9897
|
// Annotate the CommonJS export names for ESM import in node:
|
|
9803
9898
|
0 && (module.exports = {
|
|
9804
9899
|
ArrowTool,
|