@fieldnotes/core 0.36.0 → 0.38.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/README.md CHANGED
@@ -104,6 +104,25 @@ viewport.addImage('/assets/map.png', { x: 0, y: 0 }, { w: 800, h: 600 });
104
104
 
105
105
  > **Important: Use URLs, not base64 data URLs.** Images are stored inline in the serialized state. A single base64-encoded photo can be 2-5MB, which will blow past the `localStorage` ~5MB quota and make JSON exports impractical. Upload images to your server or CDN and use the URL. For offline/local-first apps, store blobs in IndexedDB and reference them by URL.
106
106
 
107
+ ## Adding Shapes
108
+
109
+ ```typescript
110
+ // Default: a centered 100×100 rectangle
111
+ const id = viewport.addShape();
112
+
113
+ // Override shape, size, position, and colors
114
+ viewport.addShape({
115
+ shape: 'ellipse',
116
+ size: { w: 200, h: 120 },
117
+ position: { x: 0, y: 0 },
118
+ strokeColor: '#1d4ed8',
119
+ fillColor: '#dbeafe',
120
+ strokeWidth: 2,
121
+ });
122
+ ```
123
+
124
+ `addShape(opts?): string` creates a shape in a single undo step, selects the new shape, and returns its id. With no options it places a 100×100 rectangle centered in the current viewport — a keyboard-friendly path to shape creation.
125
+
107
126
  ## Grids
108
127
 
109
128
  Add square or hex grid overlays — useful for D&D combat maps, alignment, or graph paper backgrounds. Grids always render on top of images and other layer elements.
package/dist/index.cjs CHANGED
@@ -2083,9 +2083,10 @@ var Quadtree = class {
2083
2083
  };
2084
2084
 
2085
2085
  // src/elements/stroke-smoothing.ts
2086
- var MIN_PRESSURE_SCALE = 0.2;
2086
+ var MIN_PRESSURE_SCALE = 0.4;
2087
+ var MAX_PRESSURE_SCALE = 1.8;
2087
2088
  function pressureToWidth(pressure, baseWidth) {
2088
- return baseWidth * (MIN_PRESSURE_SCALE + (1 - MIN_PRESSURE_SCALE) * pressure);
2089
+ return baseWidth * (MIN_PRESSURE_SCALE + (MAX_PRESSURE_SCALE - MIN_PRESSURE_SCALE) * pressure);
2089
2090
  }
2090
2091
  function simplifyPoints(points, tolerance) {
2091
2092
  if (points.length <= 2) return points.slice();
@@ -3748,12 +3749,33 @@ var NoteToolbar = class {
3748
3749
  e.stopPropagation();
3749
3750
  });
3750
3751
  select.addEventListener("change", () => {
3751
- setFontSize(Number(select.value));
3752
+ this.applyFontSize(Number(select.value));
3752
3753
  this.updateActiveStates();
3753
3754
  this.anchor?.focus();
3754
3755
  });
3755
3756
  return select;
3756
3757
  }
3758
+ applyFontSize(size) {
3759
+ const sel = window.getSelection();
3760
+ const collapsed = !sel || sel.rangeCount === 0 || sel.getRangeAt(0).collapsed;
3761
+ if (collapsed && this.anchor) {
3762
+ const range = document.createRange();
3763
+ range.selectNodeContents(this.anchor);
3764
+ sel?.removeAllRanges();
3765
+ sel?.addRange(range);
3766
+ setFontSize(size);
3767
+ const after = window.getSelection();
3768
+ if (after) {
3769
+ const caret = document.createRange();
3770
+ caret.selectNodeContents(this.anchor);
3771
+ caret.collapse(false);
3772
+ after.removeAllRanges();
3773
+ after.addRange(caret);
3774
+ }
3775
+ return;
3776
+ }
3777
+ setFontSize(size);
3778
+ }
3757
3779
  positionToolbar(anchor) {
3758
3780
  if (!this.el) return;
3759
3781
  const rect = anchor.getBoundingClientRect();
@@ -6098,6 +6120,32 @@ var Viewport = class {
6098
6120
  this.requestRender();
6099
6121
  return el.id;
6100
6122
  }
6123
+ addShape(opts = {}) {
6124
+ const size = opts.size ?? { w: 100, h: 100 };
6125
+ const position = opts.position ?? this.centeredPosition(size);
6126
+ const shape = createShape({
6127
+ position,
6128
+ size,
6129
+ shape: opts.shape,
6130
+ strokeColor: opts.strokeColor,
6131
+ strokeWidth: opts.strokeWidth,
6132
+ fillColor: opts.fillColor,
6133
+ layerId: this.layerManager.activeLayerId
6134
+ });
6135
+ this.historyRecorder.begin();
6136
+ this.store.add(shape);
6137
+ this.historyRecorder.commit();
6138
+ this.getSelectTool()?.setSelection([shape.id]);
6139
+ this.requestRender();
6140
+ return shape.id;
6141
+ }
6142
+ centeredPosition(size) {
6143
+ const c = this.camera.screenToWorld({
6144
+ x: this.wrapper.clientWidth / 2,
6145
+ y: this.wrapper.clientHeight / 2
6146
+ });
6147
+ return { x: c.x - size.w / 2, y: c.y - size.h / 2 };
6148
+ }
6101
6149
  removeLayer(id) {
6102
6150
  this.historyRecorder.begin();
6103
6151
  this.layerManager.removeLayer(id);
@@ -8899,7 +8947,7 @@ var TemplateTool = class {
8899
8947
  };
8900
8948
 
8901
8949
  // src/index.ts
8902
- var VERSION = "0.36.0";
8950
+ var VERSION = "0.38.0";
8903
8951
  // Annotate the CommonJS export names for ESM import in node:
8904
8952
  0 && (module.exports = {
8905
8953
  ArrowTool,