@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 +19 -0
- package/dist/index.cjs +52 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +52 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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 + (
|
|
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
|
-
|
|
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.
|
|
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,
|