@fieldnotes/core 0.4.1 → 0.5.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 +47 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +46 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -101,6 +101,8 @@ declare function exportState(elements: CanvasElement[], camera: {
|
|
|
101
101
|
}): CanvasState;
|
|
102
102
|
declare function parseState(json: string): CanvasState;
|
|
103
103
|
|
|
104
|
+
declare function snapPoint(point: Point, gridSize: number): Point;
|
|
105
|
+
|
|
104
106
|
interface ElementUpdateEvent {
|
|
105
107
|
previous: CanvasElement;
|
|
106
108
|
current: CanvasElement;
|
|
@@ -203,6 +205,8 @@ interface ToolContext {
|
|
|
203
205
|
switchTool?: (name: string) => void;
|
|
204
206
|
editElement?: (id: string) => void;
|
|
205
207
|
setCursor?: (cursor: string) => void;
|
|
208
|
+
snapToGrid?: boolean;
|
|
209
|
+
gridSize?: number;
|
|
206
210
|
}
|
|
207
211
|
interface PointerState {
|
|
208
212
|
x: number;
|
|
@@ -353,12 +357,16 @@ declare class Viewport {
|
|
|
353
357
|
readonly toolContext: ToolContext;
|
|
354
358
|
private resizeObserver;
|
|
355
359
|
private animFrameId;
|
|
360
|
+
private _snapToGrid;
|
|
361
|
+
private readonly _gridSize;
|
|
356
362
|
private needsRender;
|
|
357
363
|
private domNodes;
|
|
358
364
|
private htmlContent;
|
|
359
365
|
private interactingElementId;
|
|
360
366
|
constructor(container: HTMLElement, options?: ViewportOptions);
|
|
361
367
|
get ctx(): CanvasRenderingContext2D | null;
|
|
368
|
+
get snapToGrid(): boolean;
|
|
369
|
+
setSnapToGrid(enabled: boolean): void;
|
|
362
370
|
requestRender(): void;
|
|
363
371
|
exportState(): CanvasState;
|
|
364
372
|
exportJSON(): string;
|
|
@@ -612,6 +620,7 @@ declare class SelectTool implements Tool {
|
|
|
612
620
|
get isMarqueeActive(): boolean;
|
|
613
621
|
onActivate(ctx: ToolContext): void;
|
|
614
622
|
onDeactivate(ctx: ToolContext): void;
|
|
623
|
+
private snap;
|
|
615
624
|
onPointerDown(state: PointerState, ctx: ToolContext): void;
|
|
616
625
|
onPointerMove(state: PointerState, ctx: ToolContext): void;
|
|
617
626
|
onPointerUp(_state: PointerState, ctx: ToolContext): void;
|
|
@@ -729,10 +738,11 @@ declare class ShapeTool implements Tool {
|
|
|
729
738
|
onPointerUp(_state: PointerState, ctx: ToolContext): void;
|
|
730
739
|
renderOverlay(ctx: CanvasRenderingContext2D): void;
|
|
731
740
|
private computeRect;
|
|
741
|
+
private snap;
|
|
732
742
|
private onKeyDown;
|
|
733
743
|
private onKeyUp;
|
|
734
744
|
}
|
|
735
745
|
|
|
736
|
-
declare const VERSION = "0.
|
|
746
|
+
declare const VERSION = "0.5.0";
|
|
737
747
|
|
|
738
|
-
export { AddElementCommand, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, Background, type BackgroundOptions, type BackgroundPattern, BatchCommand, type Binding, type Bounds, Camera, type CameraOptions, type CanvasElement, type CanvasState, type Command, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type Size, type StrokeElement, type StrokePoint, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, UpdateElementCommand, VERSION, Viewport, type ViewportOptions, clearStaleBindings, createArrow, createHtmlElement, createId, createImage, createNote, createShape, createStroke, createText, exportState, findBindTarget, findBoundArrows, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getEdgeIntersection, getElementBounds, getElementCenter, isBindable, isNearBezier, parseState, unbindArrow, updateBoundArrow };
|
|
748
|
+
export { AddElementCommand, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, Background, type BackgroundOptions, type BackgroundPattern, BatchCommand, type Binding, type Bounds, Camera, type CameraOptions, type CanvasElement, type CanvasState, type Command, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type Size, type StrokeElement, type StrokePoint, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, UpdateElementCommand, VERSION, Viewport, type ViewportOptions, clearStaleBindings, createArrow, createHtmlElement, createId, createImage, createNote, createShape, createStroke, createText, exportState, findBindTarget, findBoundArrows, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getEdgeIntersection, getElementBounds, getElementCenter, isBindable, isNearBezier, parseState, snapPoint, unbindArrow, updateBoundArrow };
|
package/dist/index.d.ts
CHANGED
|
@@ -101,6 +101,8 @@ declare function exportState(elements: CanvasElement[], camera: {
|
|
|
101
101
|
}): CanvasState;
|
|
102
102
|
declare function parseState(json: string): CanvasState;
|
|
103
103
|
|
|
104
|
+
declare function snapPoint(point: Point, gridSize: number): Point;
|
|
105
|
+
|
|
104
106
|
interface ElementUpdateEvent {
|
|
105
107
|
previous: CanvasElement;
|
|
106
108
|
current: CanvasElement;
|
|
@@ -203,6 +205,8 @@ interface ToolContext {
|
|
|
203
205
|
switchTool?: (name: string) => void;
|
|
204
206
|
editElement?: (id: string) => void;
|
|
205
207
|
setCursor?: (cursor: string) => void;
|
|
208
|
+
snapToGrid?: boolean;
|
|
209
|
+
gridSize?: number;
|
|
206
210
|
}
|
|
207
211
|
interface PointerState {
|
|
208
212
|
x: number;
|
|
@@ -353,12 +357,16 @@ declare class Viewport {
|
|
|
353
357
|
readonly toolContext: ToolContext;
|
|
354
358
|
private resizeObserver;
|
|
355
359
|
private animFrameId;
|
|
360
|
+
private _snapToGrid;
|
|
361
|
+
private readonly _gridSize;
|
|
356
362
|
private needsRender;
|
|
357
363
|
private domNodes;
|
|
358
364
|
private htmlContent;
|
|
359
365
|
private interactingElementId;
|
|
360
366
|
constructor(container: HTMLElement, options?: ViewportOptions);
|
|
361
367
|
get ctx(): CanvasRenderingContext2D | null;
|
|
368
|
+
get snapToGrid(): boolean;
|
|
369
|
+
setSnapToGrid(enabled: boolean): void;
|
|
362
370
|
requestRender(): void;
|
|
363
371
|
exportState(): CanvasState;
|
|
364
372
|
exportJSON(): string;
|
|
@@ -612,6 +620,7 @@ declare class SelectTool implements Tool {
|
|
|
612
620
|
get isMarqueeActive(): boolean;
|
|
613
621
|
onActivate(ctx: ToolContext): void;
|
|
614
622
|
onDeactivate(ctx: ToolContext): void;
|
|
623
|
+
private snap;
|
|
615
624
|
onPointerDown(state: PointerState, ctx: ToolContext): void;
|
|
616
625
|
onPointerMove(state: PointerState, ctx: ToolContext): void;
|
|
617
626
|
onPointerUp(_state: PointerState, ctx: ToolContext): void;
|
|
@@ -729,10 +738,11 @@ declare class ShapeTool implements Tool {
|
|
|
729
738
|
onPointerUp(_state: PointerState, ctx: ToolContext): void;
|
|
730
739
|
renderOverlay(ctx: CanvasRenderingContext2D): void;
|
|
731
740
|
private computeRect;
|
|
741
|
+
private snap;
|
|
732
742
|
private onKeyDown;
|
|
733
743
|
private onKeyUp;
|
|
734
744
|
}
|
|
735
745
|
|
|
736
|
-
declare const VERSION = "0.
|
|
746
|
+
declare const VERSION = "0.5.0";
|
|
737
747
|
|
|
738
|
-
export { AddElementCommand, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, Background, type BackgroundOptions, type BackgroundPattern, BatchCommand, type Binding, type Bounds, Camera, type CameraOptions, type CanvasElement, type CanvasState, type Command, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type Size, type StrokeElement, type StrokePoint, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, UpdateElementCommand, VERSION, Viewport, type ViewportOptions, clearStaleBindings, createArrow, createHtmlElement, createId, createImage, createNote, createShape, createStroke, createText, exportState, findBindTarget, findBoundArrows, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getEdgeIntersection, getElementBounds, getElementCenter, isBindable, isNearBezier, parseState, unbindArrow, updateBoundArrow };
|
|
748
|
+
export { AddElementCommand, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, Background, type BackgroundOptions, type BackgroundPattern, BatchCommand, type Binding, type Bounds, Camera, type CameraOptions, type CanvasElement, type CanvasState, type Command, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type Size, type StrokeElement, type StrokePoint, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, UpdateElementCommand, VERSION, Viewport, type ViewportOptions, clearStaleBindings, createArrow, createHtmlElement, createId, createImage, createNote, createShape, createStroke, createText, exportState, findBindTarget, findBoundArrows, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getEdgeIntersection, getElementBounds, getElementCenter, isBindable, isNearBezier, parseState, snapPoint, unbindArrow, updateBoundArrow };
|
package/dist/index.js
CHANGED
|
@@ -119,6 +119,14 @@ function migrateElement(obj) {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
// src/core/snap.ts
|
|
123
|
+
function snapPoint(point, gridSize) {
|
|
124
|
+
return {
|
|
125
|
+
x: Math.round(point.x / gridSize) * gridSize || 0,
|
|
126
|
+
y: Math.round(point.y / gridSize) * gridSize || 0
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
122
130
|
// src/core/auto-save.ts
|
|
123
131
|
var DEFAULT_KEY = "fieldnotes-autosave";
|
|
124
132
|
var DEFAULT_DEBOUNCE_MS = 1e3;
|
|
@@ -1501,6 +1509,7 @@ var Viewport = class {
|
|
|
1501
1509
|
this.container = container;
|
|
1502
1510
|
this.camera = new Camera(options.camera);
|
|
1503
1511
|
this.background = new Background(options.background);
|
|
1512
|
+
this._gridSize = options.background?.spacing ?? 24;
|
|
1504
1513
|
this.store = new ElementStore();
|
|
1505
1514
|
this.toolManager = new ToolManager();
|
|
1506
1515
|
this.renderer = new ElementRenderer();
|
|
@@ -1523,7 +1532,9 @@ var Viewport = class {
|
|
|
1523
1532
|
editElement: (id) => this.startEditingElement(id),
|
|
1524
1533
|
setCursor: (cursor) => {
|
|
1525
1534
|
this.wrapper.style.cursor = cursor;
|
|
1526
|
-
}
|
|
1535
|
+
},
|
|
1536
|
+
snapToGrid: false,
|
|
1537
|
+
gridSize: this._gridSize
|
|
1527
1538
|
};
|
|
1528
1539
|
this.inputHandler = new InputHandler(this.wrapper, this.camera, {
|
|
1529
1540
|
toolManager: this.toolManager,
|
|
@@ -1568,6 +1579,8 @@ var Viewport = class {
|
|
|
1568
1579
|
toolContext;
|
|
1569
1580
|
resizeObserver = null;
|
|
1570
1581
|
animFrameId = 0;
|
|
1582
|
+
_snapToGrid = false;
|
|
1583
|
+
_gridSize;
|
|
1571
1584
|
needsRender = true;
|
|
1572
1585
|
domNodes = /* @__PURE__ */ new Map();
|
|
1573
1586
|
htmlContent = /* @__PURE__ */ new Map();
|
|
@@ -1575,6 +1588,13 @@ var Viewport = class {
|
|
|
1575
1588
|
get ctx() {
|
|
1576
1589
|
return this.canvasEl.getContext("2d");
|
|
1577
1590
|
}
|
|
1591
|
+
get snapToGrid() {
|
|
1592
|
+
return this._snapToGrid;
|
|
1593
|
+
}
|
|
1594
|
+
setSnapToGrid(enabled) {
|
|
1595
|
+
this._snapToGrid = enabled;
|
|
1596
|
+
this.toolContext.snapToGrid = enabled;
|
|
1597
|
+
}
|
|
1578
1598
|
requestRender() {
|
|
1579
1599
|
this.needsRender = true;
|
|
1580
1600
|
}
|
|
@@ -2323,10 +2343,13 @@ var SelectTool = class {
|
|
|
2323
2343
|
this.mode = { type: "idle" };
|
|
2324
2344
|
ctx.setCursor?.("default");
|
|
2325
2345
|
}
|
|
2346
|
+
snap(point, ctx) {
|
|
2347
|
+
return ctx.snapToGrid && ctx.gridSize ? snapPoint(point, ctx.gridSize) : point;
|
|
2348
|
+
}
|
|
2326
2349
|
onPointerDown(state, ctx) {
|
|
2327
2350
|
this.ctx = ctx;
|
|
2328
2351
|
const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
2329
|
-
this.lastWorld = world;
|
|
2352
|
+
this.lastWorld = this.snap(world, ctx);
|
|
2330
2353
|
this.currentWorld = world;
|
|
2331
2354
|
const arrowHit = hitTestArrowHandles(world, this._selectedIds, ctx);
|
|
2332
2355
|
if (arrowHit) {
|
|
@@ -2379,9 +2402,10 @@ var SelectTool = class {
|
|
|
2379
2402
|
}
|
|
2380
2403
|
if (this.mode.type === "dragging" && this._selectedIds.length > 0) {
|
|
2381
2404
|
ctx.setCursor?.("move");
|
|
2382
|
-
const
|
|
2383
|
-
const
|
|
2384
|
-
this.lastWorld
|
|
2405
|
+
const snapped = this.snap(world, ctx);
|
|
2406
|
+
const dx = snapped.x - this.lastWorld.x;
|
|
2407
|
+
const dy = snapped.y - this.lastWorld.y;
|
|
2408
|
+
this.lastWorld = snapped;
|
|
2385
2409
|
for (const id of this._selectedIds) {
|
|
2386
2410
|
const el = ctx.store.getById(id);
|
|
2387
2411
|
if (!el || el.locked) continue;
|
|
@@ -2730,7 +2754,7 @@ var ArrowTool = class {
|
|
|
2730
2754
|
this.fromBinding = { elementId: target.id };
|
|
2731
2755
|
this.fromTarget = target;
|
|
2732
2756
|
} else {
|
|
2733
|
-
this.start = world;
|
|
2757
|
+
this.start = ctx.snapToGrid && ctx.gridSize ? snapPoint(world, ctx.gridSize) : world;
|
|
2734
2758
|
this.fromBinding = void 0;
|
|
2735
2759
|
this.fromTarget = null;
|
|
2736
2760
|
}
|
|
@@ -2747,7 +2771,7 @@ var ArrowTool = class {
|
|
|
2747
2771
|
this.end = getElementCenter(target);
|
|
2748
2772
|
this.toTarget = target;
|
|
2749
2773
|
} else {
|
|
2750
|
-
this.end = world;
|
|
2774
|
+
this.end = ctx.snapToGrid && ctx.gridSize ? snapPoint(world, ctx.gridSize) : world;
|
|
2751
2775
|
this.toTarget = null;
|
|
2752
2776
|
}
|
|
2753
2777
|
ctx.requestRender();
|
|
@@ -2842,7 +2866,10 @@ var NoteTool = class {
|
|
|
2842
2866
|
onPointerMove(_state, _ctx) {
|
|
2843
2867
|
}
|
|
2844
2868
|
onPointerUp(state, ctx) {
|
|
2845
|
-
|
|
2869
|
+
let world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
2870
|
+
if (ctx.snapToGrid && ctx.gridSize) {
|
|
2871
|
+
world = snapPoint(world, ctx.gridSize);
|
|
2872
|
+
}
|
|
2846
2873
|
const note = createNote({
|
|
2847
2874
|
position: world,
|
|
2848
2875
|
size: { ...this.size },
|
|
@@ -2883,7 +2910,10 @@ var TextTool = class {
|
|
|
2883
2910
|
onPointerMove(_state, _ctx) {
|
|
2884
2911
|
}
|
|
2885
2912
|
onPointerUp(state, ctx) {
|
|
2886
|
-
|
|
2913
|
+
let world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
2914
|
+
if (ctx.snapToGrid && ctx.gridSize) {
|
|
2915
|
+
world = snapPoint(world, ctx.gridSize);
|
|
2916
|
+
}
|
|
2887
2917
|
const textEl = createText({
|
|
2888
2918
|
position: world,
|
|
2889
2919
|
fontSize: this.fontSize,
|
|
@@ -2965,12 +2995,12 @@ var ShapeTool = class {
|
|
|
2965
2995
|
}
|
|
2966
2996
|
onPointerDown(state, ctx) {
|
|
2967
2997
|
this.drawing = true;
|
|
2968
|
-
this.start = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
2998
|
+
this.start = this.snap(ctx.camera.screenToWorld({ x: state.x, y: state.y }), ctx);
|
|
2969
2999
|
this.end = { ...this.start };
|
|
2970
3000
|
}
|
|
2971
3001
|
onPointerMove(state, ctx) {
|
|
2972
3002
|
if (!this.drawing) return;
|
|
2973
|
-
this.end = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
3003
|
+
this.end = this.snap(ctx.camera.screenToWorld({ x: state.x, y: state.y }), ctx);
|
|
2974
3004
|
ctx.requestRender();
|
|
2975
3005
|
}
|
|
2976
3006
|
onPointerUp(_state, ctx) {
|
|
@@ -3034,6 +3064,9 @@ var ShapeTool = class {
|
|
|
3034
3064
|
}
|
|
3035
3065
|
return { position: { x, y }, size: { w, h } };
|
|
3036
3066
|
}
|
|
3067
|
+
snap(point, ctx) {
|
|
3068
|
+
return ctx.snapToGrid && ctx.gridSize ? snapPoint(point, ctx.gridSize) : point;
|
|
3069
|
+
}
|
|
3037
3070
|
onKeyDown = (e) => {
|
|
3038
3071
|
if (e.key === "Shift") this.shiftHeld = true;
|
|
3039
3072
|
};
|
|
@@ -3043,7 +3076,7 @@ var ShapeTool = class {
|
|
|
3043
3076
|
};
|
|
3044
3077
|
|
|
3045
3078
|
// src/index.ts
|
|
3046
|
-
var VERSION = "0.
|
|
3079
|
+
var VERSION = "0.5.0";
|
|
3047
3080
|
export {
|
|
3048
3081
|
AddElementCommand,
|
|
3049
3082
|
ArrowTool,
|
|
@@ -3094,6 +3127,7 @@ export {
|
|
|
3094
3127
|
isBindable,
|
|
3095
3128
|
isNearBezier,
|
|
3096
3129
|
parseState,
|
|
3130
|
+
snapPoint,
|
|
3097
3131
|
unbindArrow,
|
|
3098
3132
|
updateBoundArrow
|
|
3099
3133
|
};
|