@fieldnotes/core 0.40.4 → 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.d.cts CHANGED
@@ -46,6 +46,7 @@ interface NoteElement extends BaseElement {
46
46
  interface Binding {
47
47
  elementId: string;
48
48
  }
49
+ type ArrowStrokeStyle = 'solid' | 'dashed' | 'dotted';
49
50
  interface ArrowElement extends BaseElement {
50
51
  type: 'arrow';
51
52
  from: Point;
@@ -59,6 +60,8 @@ interface ArrowElement extends BaseElement {
59
60
  cachedControlPoint?: Point;
60
61
  /** Optional text rendered at the curve midpoint. */
61
62
  label?: string;
63
+ /** Line dash appearance. Absent = solid. Decoupled from binding. */
64
+ strokeStyle?: ArrowStrokeStyle;
62
65
  }
63
66
  interface ImageElement extends BaseElement {
64
67
  type: 'image';
@@ -426,6 +429,7 @@ interface ElementStyle {
426
429
  strokeWidth?: number;
427
430
  opacity?: number;
428
431
  fontSize?: number;
432
+ strokeStyle?: ArrowStrokeStyle;
429
433
  }
430
434
  declare function styleToPatch(element: CanvasElement, style: ElementStyle): Partial<CanvasElement>;
431
435
  declare function getElementStyle(element: CanvasElement): ElementStyle;
@@ -465,6 +469,8 @@ interface ViewportOptions {
465
469
  panBufferMargin?: number;
466
470
  /** Enable the built-in context menu. Default `true`. */
467
471
  contextMenu?: boolean;
472
+ /** Coast (inertial glide) after a pan flick. Default `true`. */
473
+ panInertia?: boolean;
468
474
  }
469
475
  declare class Viewport {
470
476
  private readonly container;
@@ -633,6 +639,7 @@ interface ArrowInput extends BaseDefaults {
633
639
  fromBinding?: Binding;
634
640
  toBinding?: Binding;
635
641
  label?: string;
642
+ strokeStyle?: ArrowStrokeStyle;
636
643
  }
637
644
  interface ImageInput extends BaseDefaults {
638
645
  position: Point;
@@ -825,6 +832,7 @@ declare class SelectTool implements Tool {
825
832
  interface ArrowToolOptions {
826
833
  color?: string;
827
834
  width?: number;
835
+ strokeStyle?: ArrowStrokeStyle;
828
836
  }
829
837
  declare class ArrowTool implements Tool {
830
838
  readonly name = "arrow";
@@ -833,6 +841,7 @@ declare class ArrowTool implements Tool {
833
841
  private end;
834
842
  private color;
835
843
  private width;
844
+ private strokeStyle;
836
845
  private fromBinding;
837
846
  private fromTarget;
838
847
  private toTarget;
@@ -1048,6 +1057,6 @@ declare class LaserTool implements Tool {
1048
1057
  private notifyOptionsChange;
1049
1058
  }
1050
1059
 
1051
- declare const VERSION = "0.40.4";
1060
+ declare const VERSION = "0.42.0";
1052
1061
 
1053
- export { type ActiveFormats, type AlignEdge, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, type DistributeAxis, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportImageOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, LaserTool, type LaserToolOptions, type Layer, LayerManager, MeasureTool, type MeasureToolOptions, type Measurement, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, type RenderStatsSnapshot, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, exportSvg, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInSquare, getHexDistance, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
1062
+ export { type ActiveFormats, type AlignEdge, type ArrowElement, type ArrowStrokeStyle, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, type DistributeAxis, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportImageOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, LaserTool, type LaserToolOptions, type Layer, LayerManager, MeasureTool, type MeasureToolOptions, type Measurement, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, type RenderStatsSnapshot, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, exportSvg, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInSquare, getHexDistance, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
package/dist/index.d.ts CHANGED
@@ -46,6 +46,7 @@ interface NoteElement extends BaseElement {
46
46
  interface Binding {
47
47
  elementId: string;
48
48
  }
49
+ type ArrowStrokeStyle = 'solid' | 'dashed' | 'dotted';
49
50
  interface ArrowElement extends BaseElement {
50
51
  type: 'arrow';
51
52
  from: Point;
@@ -59,6 +60,8 @@ interface ArrowElement extends BaseElement {
59
60
  cachedControlPoint?: Point;
60
61
  /** Optional text rendered at the curve midpoint. */
61
62
  label?: string;
63
+ /** Line dash appearance. Absent = solid. Decoupled from binding. */
64
+ strokeStyle?: ArrowStrokeStyle;
62
65
  }
63
66
  interface ImageElement extends BaseElement {
64
67
  type: 'image';
@@ -426,6 +429,7 @@ interface ElementStyle {
426
429
  strokeWidth?: number;
427
430
  opacity?: number;
428
431
  fontSize?: number;
432
+ strokeStyle?: ArrowStrokeStyle;
429
433
  }
430
434
  declare function styleToPatch(element: CanvasElement, style: ElementStyle): Partial<CanvasElement>;
431
435
  declare function getElementStyle(element: CanvasElement): ElementStyle;
@@ -465,6 +469,8 @@ interface ViewportOptions {
465
469
  panBufferMargin?: number;
466
470
  /** Enable the built-in context menu. Default `true`. */
467
471
  contextMenu?: boolean;
472
+ /** Coast (inertial glide) after a pan flick. Default `true`. */
473
+ panInertia?: boolean;
468
474
  }
469
475
  declare class Viewport {
470
476
  private readonly container;
@@ -633,6 +639,7 @@ interface ArrowInput extends BaseDefaults {
633
639
  fromBinding?: Binding;
634
640
  toBinding?: Binding;
635
641
  label?: string;
642
+ strokeStyle?: ArrowStrokeStyle;
636
643
  }
637
644
  interface ImageInput extends BaseDefaults {
638
645
  position: Point;
@@ -825,6 +832,7 @@ declare class SelectTool implements Tool {
825
832
  interface ArrowToolOptions {
826
833
  color?: string;
827
834
  width?: number;
835
+ strokeStyle?: ArrowStrokeStyle;
828
836
  }
829
837
  declare class ArrowTool implements Tool {
830
838
  readonly name = "arrow";
@@ -833,6 +841,7 @@ declare class ArrowTool implements Tool {
833
841
  private end;
834
842
  private color;
835
843
  private width;
844
+ private strokeStyle;
836
845
  private fromBinding;
837
846
  private fromTarget;
838
847
  private toTarget;
@@ -1048,6 +1057,6 @@ declare class LaserTool implements Tool {
1048
1057
  private notifyOptionsChange;
1049
1058
  }
1050
1059
 
1051
- declare const VERSION = "0.40.4";
1060
+ declare const VERSION = "0.42.0";
1052
1061
 
1053
- export { type ActiveFormats, type AlignEdge, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, type DistributeAxis, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportImageOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, LaserTool, type LaserToolOptions, type Layer, LayerManager, MeasureTool, type MeasureToolOptions, type Measurement, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, type RenderStatsSnapshot, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, exportSvg, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInSquare, getHexDistance, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
1062
+ export { type ActiveFormats, type AlignEdge, type ArrowElement, type ArrowStrokeStyle, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, type DistributeAxis, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportImageOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, LaserTool, type LaserToolOptions, type Layer, LayerManager, MeasureTool, type MeasureToolOptions, type Measurement, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, type RenderStatsSnapshot, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, exportSvg, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInSquare, getHexDistance, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
package/dist/index.js CHANGED
@@ -1471,6 +1471,81 @@ var KeyboardHandler = class {
1471
1471
  }
1472
1472
  };
1473
1473
 
1474
+ // src/canvas/pan-inertia.ts
1475
+ var VELOCITY_WINDOW_MS = 60;
1476
+ var FRICTION = 0.92;
1477
+ var MIN_START_SPEED = 2;
1478
+ var MIN_STOP_SPEED = 0.3;
1479
+ var PanInertia = class {
1480
+ constructor(deps) {
1481
+ this.deps = deps;
1482
+ }
1483
+ samples = [];
1484
+ vx = 0;
1485
+ vy = 0;
1486
+ rafId = null;
1487
+ sample(dx, dy) {
1488
+ const t = this.deps.now();
1489
+ this.samples.push({ dx, dy, t });
1490
+ this.prune(t);
1491
+ }
1492
+ release() {
1493
+ if (!this.deps.enabled()) {
1494
+ this.reset();
1495
+ return;
1496
+ }
1497
+ const t = this.deps.now();
1498
+ this.prune(t);
1499
+ const recent = this.samples;
1500
+ if (recent.length === 0) {
1501
+ this.reset();
1502
+ return;
1503
+ }
1504
+ let sx = 0;
1505
+ let sy = 0;
1506
+ for (const s of recent) {
1507
+ sx += s.dx;
1508
+ sy += s.dy;
1509
+ }
1510
+ this.vx = sx / recent.length;
1511
+ this.vy = sy / recent.length;
1512
+ this.samples = [];
1513
+ if (Math.hypot(this.vx, this.vy) < MIN_START_SPEED) {
1514
+ this.vx = 0;
1515
+ this.vy = 0;
1516
+ return;
1517
+ }
1518
+ this.rafId = this.deps.requestFrame(this.step);
1519
+ }
1520
+ cancel() {
1521
+ this.reset();
1522
+ }
1523
+ step = () => {
1524
+ if (this.rafId === null) return;
1525
+ this.deps.pan(this.vx, this.vy);
1526
+ this.vx *= FRICTION;
1527
+ this.vy *= FRICTION;
1528
+ if (Math.hypot(this.vx, this.vy) >= MIN_STOP_SPEED) {
1529
+ this.rafId = this.deps.requestFrame(this.step);
1530
+ } else {
1531
+ this.reset();
1532
+ }
1533
+ };
1534
+ prune(now) {
1535
+ const cutoff = now - VELOCITY_WINDOW_MS;
1536
+ this.samples = this.samples.filter((s) => s.t >= cutoff);
1537
+ }
1538
+ reset() {
1539
+ if (this.rafId !== null) {
1540
+ this.deps.cancelFrame(this.rafId);
1541
+ this.rafId = null;
1542
+ }
1543
+ this.samples = [];
1544
+ this.vx = 0;
1545
+ this.vy = 0;
1546
+ }
1547
+ };
1548
+
1474
1549
  // src/canvas/input-handler.ts
1475
1550
  var ZOOM_SENSITIVITY = 1e-3;
1476
1551
  var MIDDLE_BUTTON = 1;
@@ -1496,6 +1571,16 @@ var InputHandler = class {
1496
1571
  getLastPointerWorld: () => this.lastPointerWorld()
1497
1572
  });
1498
1573
  this.openContextMenu = options.openContextMenu;
1574
+ this.panInertiaEnabled = options.panInertia ?? true;
1575
+ this.panInertia = new PanInertia({
1576
+ pan: (dx, dy) => this.camera.pan(dx, dy),
1577
+ now: () => typeof performance !== "undefined" ? performance.now() : Date.now(),
1578
+ requestFrame: (cb) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(cb) : 0,
1579
+ cancelFrame: (id) => {
1580
+ if (typeof cancelAnimationFrame !== "undefined") cancelAnimationFrame(id);
1581
+ },
1582
+ enabled: () => this.panInertiaEnabled
1583
+ });
1499
1584
  this.scope = options.shortcuts?.scope ?? "focus";
1500
1585
  this.keyboard = new KeyboardHandler({
1501
1586
  element: this.element,
@@ -1545,6 +1630,8 @@ var InputHandler = class {
1545
1630
  keyboard;
1546
1631
  scope;
1547
1632
  openContextMenu;
1633
+ panInertia;
1634
+ panInertiaEnabled;
1548
1635
  setToolManager(toolManager, toolContext) {
1549
1636
  this.toolManager = toolManager;
1550
1637
  this.toolContext = toolContext;
@@ -1556,6 +1643,7 @@ var InputHandler = class {
1556
1643
  return this.keyboard.shortcuts;
1557
1644
  }
1558
1645
  destroy() {
1646
+ this.panInertia.cancel();
1559
1647
  this.actions.dispose();
1560
1648
  this.abortController.abort();
1561
1649
  this.inputFilter.reset();
@@ -1579,6 +1667,7 @@ var InputHandler = class {
1579
1667
  }
1580
1668
  onWheel = (e) => {
1581
1669
  e.preventDefault();
1670
+ this.panInertia.cancel();
1582
1671
  const rect = this.element.getBoundingClientRect();
1583
1672
  const zoomFactor = 1 - e.deltaY * ZOOM_SENSITIVITY;
1584
1673
  const newZoom = this.camera.zoom * zoomFactor;
@@ -1588,6 +1677,7 @@ var InputHandler = class {
1588
1677
  });
1589
1678
  };
1590
1679
  onPointerDown = (e) => {
1680
+ this.panInertia.cancel();
1591
1681
  this.focusSelf();
1592
1682
  this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });
1593
1683
  this.element.setPointerCapture?.(e.pointerId);
@@ -1628,6 +1718,7 @@ var InputHandler = class {
1628
1718
  const dy = e.clientY - this.lastPointer.y;
1629
1719
  this.lastPointer = { x: e.clientX, y: e.clientY };
1630
1720
  this.camera.pan(dx, dy);
1721
+ this.panInertia.sample(dx, dy);
1631
1722
  return;
1632
1723
  }
1633
1724
  if (e.pointerType === "pen" && !this.activePointers.has(e.pointerId)) {
@@ -1658,6 +1749,7 @@ var InputHandler = class {
1658
1749
  }
1659
1750
  if (this.isPanning && this.activePointers.size === 0) {
1660
1751
  this.isPanning = false;
1752
+ this.panInertia.release();
1661
1753
  }
1662
1754
  const upResult = this.inputFilter.filterUp(e);
1663
1755
  if (this.isToolActive) {
@@ -1678,6 +1770,7 @@ var InputHandler = class {
1678
1770
  return this.actions.hasClipboard();
1679
1771
  }
1680
1772
  startPinch() {
1773
+ this.panInertia.cancel();
1681
1774
  this.cancelLongPress();
1682
1775
  this.inputFilter.reset();
1683
1776
  this.deferredDown = null;
@@ -1699,6 +1792,7 @@ var InputHandler = class {
1699
1792
  const dx = center2.x - this.lastPointer.x;
1700
1793
  const dy = center2.y - this.lastPointer.y;
1701
1794
  this.camera.pan(dx, dy);
1795
+ this.panInertia.sample(dx, dy);
1702
1796
  this.lastPinchDistance = dist;
1703
1797
  this.lastPinchCenter = center2;
1704
1798
  this.lastPointer = { ...center2 };
@@ -2670,6 +2764,16 @@ function updateBoundArrow(arrow, store) {
2670
2764
  var ARROWHEAD_LENGTH = 12;
2671
2765
  var ARROWHEAD_ANGLE = Math.PI / 6;
2672
2766
  var ARROW_LABEL_FONT_SIZE = 14;
2767
+ function getArrowDashPattern(strokeStyle) {
2768
+ switch (strokeStyle) {
2769
+ case "dashed":
2770
+ return [8, 4];
2771
+ case "dotted":
2772
+ return [2, 4];
2773
+ default:
2774
+ return [];
2775
+ }
2776
+ }
2673
2777
  function renderArrow(ctx, arrow, store, labelEditingId) {
2674
2778
  const geometry = getArrowRenderGeometry(arrow);
2675
2779
  const { visualFrom, visualTo } = getVisualEndpoints(arrow, geometry, store);
@@ -2677,9 +2781,8 @@ function renderArrow(ctx, arrow, store, labelEditingId) {
2677
2781
  ctx.strokeStyle = arrow.color;
2678
2782
  ctx.lineWidth = arrow.width;
2679
2783
  ctx.lineCap = "round";
2680
- if (arrow.fromBinding || arrow.toBinding) {
2681
- ctx.setLineDash([8, 4]);
2682
- }
2784
+ const dash = getArrowDashPattern(arrow.strokeStyle);
2785
+ if (dash.length > 0) ctx.setLineDash(dash);
2683
2786
  ctx.beginPath();
2684
2787
  ctx.moveTo(visualFrom.x, visualFrom.y);
2685
2788
  if (arrow.bend !== 0) {
@@ -3599,6 +3702,7 @@ function createArrow(input) {
3599
3702
  if (input.fromBinding) result.fromBinding = input.fromBinding;
3600
3703
  if (input.toBinding) result.toBinding = input.toBinding;
3601
3704
  if (input.label !== void 0) result.label = input.label;
3705
+ if (input.strokeStyle !== void 0) result.strokeStyle = input.strokeStyle;
3602
3706
  return result;
3603
3707
  }
3604
3708
  function createImage(input) {
@@ -5002,7 +5106,8 @@ function emitArrow(arrow, store) {
5002
5106
  } else {
5003
5107
  d = `M${n(from.x)} ${n(from.y)} L${n(to.x)} ${n(to.y)}`;
5004
5108
  }
5005
- const dash = arrow.fromBinding || arrow.toBinding ? ' stroke-dasharray="8 4"' : "";
5109
+ const pattern = getArrowDashPattern(arrow.strokeStyle);
5110
+ const dash = pattern.length > 0 ? ` stroke-dasharray="${pattern.join(" ")}"` : "";
5006
5111
  let out = `<path d="${d}" fill="none" stroke="${esc(arrow.color)}" stroke-width="${n(arrow.width)}" stroke-linecap="round"${dash} />`;
5007
5112
  const angle = geometry.tangentEnd;
5008
5113
  const p1x = to.x - ARROWHEAD_LENGTH2 * Math.cos(angle - ARROWHEAD_ANGLE2);
@@ -6206,7 +6311,7 @@ function translateElementPatch(el, dx, dy) {
6206
6311
 
6207
6312
  // src/elements/element-style.ts
6208
6313
  function styleToPatch(element, style) {
6209
- const { color, fillColor, strokeWidth, opacity, fontSize } = style;
6314
+ const { color, fillColor, strokeWidth, opacity, fontSize, strokeStyle } = style;
6210
6315
  switch (element.type) {
6211
6316
  case "stroke":
6212
6317
  return {
@@ -6217,7 +6322,8 @@ function styleToPatch(element, style) {
6217
6322
  case "arrow":
6218
6323
  return {
6219
6324
  ...color !== void 0 ? { color } : {},
6220
- ...strokeWidth !== void 0 ? { width: strokeWidth } : {}
6325
+ ...strokeWidth !== void 0 ? { width: strokeWidth } : {},
6326
+ ...strokeStyle !== void 0 ? { strokeStyle } : {}
6221
6327
  };
6222
6328
  case "shape":
6223
6329
  return {
@@ -6258,7 +6364,11 @@ function getElementStyle(element) {
6258
6364
  case "stroke":
6259
6365
  return { color: element.color, strokeWidth: element.width, opacity: element.opacity };
6260
6366
  case "arrow":
6261
- return { color: element.color, strokeWidth: element.width };
6367
+ return {
6368
+ color: element.color,
6369
+ strokeWidth: element.width,
6370
+ ...element.strokeStyle !== void 0 ? { strokeStyle: element.strokeStyle } : {}
6371
+ };
6262
6372
  case "shape":
6263
6373
  return {
6264
6374
  color: element.strokeColor,
@@ -6332,6 +6442,8 @@ var SelectionOps = class {
6332
6442
  if (opacity !== void 0) result.opacity = opacity;
6333
6443
  const fontSize = sharedValue(styles.map((s) => s.fontSize));
6334
6444
  if (fontSize !== void 0) result.fontSize = fontSize;
6445
+ const strokeStyle = sharedValue(styles.map((s) => s.strokeStyle));
6446
+ if (strokeStyle !== void 0) result.strokeStyle = strokeStyle;
6335
6447
  return result;
6336
6448
  }
6337
6449
  applyStyle(style) {
@@ -6782,7 +6894,8 @@ var Viewport = class {
6782
6894
  shortcuts: options.shortcuts,
6783
6895
  addImage: (src, world) => this.addImage(src, world),
6784
6896
  getCenteredWorld: () => this.centeredPosition({ w: 300, h: 200 }),
6785
- onPaste: options.onPaste
6897
+ onPaste: options.onPaste,
6898
+ panInertia: options.panInertia
6786
6899
  });
6787
6900
  if (options.contextMenu !== false) {
6788
6901
  this.contextMenu = new ContextMenu({
@@ -8749,6 +8862,7 @@ var ArrowTool = class {
8749
8862
  end = { x: 0, y: 0 };
8750
8863
  color;
8751
8864
  width;
8865
+ strokeStyle;
8752
8866
  fromBinding;
8753
8867
  fromTarget = null;
8754
8868
  toTarget = null;
@@ -8756,9 +8870,10 @@ var ArrowTool = class {
8756
8870
  constructor(options = {}) {
8757
8871
  this.color = options.color ?? "#000000";
8758
8872
  this.width = options.width ?? 2;
8873
+ this.strokeStyle = options.strokeStyle ?? "solid";
8759
8874
  }
8760
8875
  getOptions() {
8761
- return { color: this.color, width: this.width };
8876
+ return { color: this.color, width: this.width, strokeStyle: this.strokeStyle };
8762
8877
  }
8763
8878
  onOptionsChange(listener) {
8764
8879
  this.optionListeners.add(listener);
@@ -8767,6 +8882,7 @@ var ArrowTool = class {
8767
8882
  setOptions(options) {
8768
8883
  if (options.color !== void 0) this.color = options.color;
8769
8884
  if (options.width !== void 0) this.width = options.width;
8885
+ if (options.strokeStyle !== void 0) this.strokeStyle = options.strokeStyle;
8770
8886
  this.notifyOptionsChange();
8771
8887
  }
8772
8888
  notifyOptionsChange() {
@@ -8826,6 +8942,7 @@ var ArrowTool = class {
8826
8942
  position: this.start,
8827
8943
  color: this.color,
8828
8944
  width: this.width,
8945
+ strokeStyle: this.strokeStyle,
8829
8946
  fromBinding: this.fromBinding,
8830
8947
  toBinding: this.toTarget ? { elementId: this.toTarget.id } : void 0,
8831
8948
  layerId: ctx.activeLayerId ?? ""
@@ -9693,7 +9810,7 @@ var LaserTool = class {
9693
9810
  };
9694
9811
 
9695
9812
  // src/index.ts
9696
- var VERSION = "0.40.4";
9813
+ var VERSION = "0.42.0";
9697
9814
  export {
9698
9815
  ArrowTool,
9699
9816
  AutoSave,