@fieldnotes/core 0.6.0 → 0.7.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 +61 -11
- package/dist/index.cjs +217 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -3
- package/dist/index.d.ts +37 -3
- package/dist/index.js +216 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -85,7 +85,17 @@ interface ShapeElement extends BaseElement {
|
|
|
85
85
|
strokeWidth: number;
|
|
86
86
|
fillColor: string;
|
|
87
87
|
}
|
|
88
|
-
type
|
|
88
|
+
type HexOrientation = 'pointy' | 'flat';
|
|
89
|
+
interface GridElement extends BaseElement {
|
|
90
|
+
type: 'grid';
|
|
91
|
+
gridType: 'square' | 'hex';
|
|
92
|
+
hexOrientation: HexOrientation;
|
|
93
|
+
cellSize: number;
|
|
94
|
+
strokeColor: string;
|
|
95
|
+
strokeWidth: number;
|
|
96
|
+
opacity: number;
|
|
97
|
+
}
|
|
98
|
+
type CanvasElement = StrokeElement | NoteElement | ArrowElement | ImageElement | HtmlElement | TextElement | ShapeElement | GridElement;
|
|
89
99
|
type ElementType = CanvasElement['type'];
|
|
90
100
|
|
|
91
101
|
interface Layer {
|
|
@@ -437,6 +447,16 @@ declare class Viewport {
|
|
|
437
447
|
w: number;
|
|
438
448
|
h: number;
|
|
439
449
|
}): string;
|
|
450
|
+
addGrid(input: {
|
|
451
|
+
gridType?: 'square' | 'hex';
|
|
452
|
+
hexOrientation?: 'pointy' | 'flat';
|
|
453
|
+
cellSize?: number;
|
|
454
|
+
strokeColor?: string;
|
|
455
|
+
strokeWidth?: number;
|
|
456
|
+
opacity?: number;
|
|
457
|
+
}): string;
|
|
458
|
+
updateGrid(updates: Partial<Pick<GridElement, 'gridType' | 'hexOrientation' | 'cellSize' | 'strokeColor' | 'strokeWidth' | 'opacity'>>): void;
|
|
459
|
+
removeGrid(): void;
|
|
440
460
|
destroy(): void;
|
|
441
461
|
private startRenderLoop;
|
|
442
462
|
private render;
|
|
@@ -469,8 +489,12 @@ declare class ElementRenderer {
|
|
|
469
489
|
private store;
|
|
470
490
|
private imageCache;
|
|
471
491
|
private onImageLoad;
|
|
492
|
+
private camera;
|
|
493
|
+
private canvasSize;
|
|
472
494
|
setStore(store: ElementStore): void;
|
|
473
495
|
setOnImageLoad(callback: () => void): void;
|
|
496
|
+
setCamera(camera: Camera): void;
|
|
497
|
+
setCanvasSize(w: number, h: number): void;
|
|
474
498
|
isDomElement(element: CanvasElement): boolean;
|
|
475
499
|
renderCanvasElement(ctx: CanvasRenderingContext2D, element: CanvasElement): void;
|
|
476
500
|
private renderStroke;
|
|
@@ -480,6 +504,7 @@ declare class ElementRenderer {
|
|
|
480
504
|
private renderShape;
|
|
481
505
|
private fillShapePath;
|
|
482
506
|
private strokeShapePath;
|
|
507
|
+
private renderGrid;
|
|
483
508
|
private renderImage;
|
|
484
509
|
private getImage;
|
|
485
510
|
}
|
|
@@ -562,6 +587,15 @@ interface ShapeInput extends BaseDefaults {
|
|
|
562
587
|
fillColor?: string;
|
|
563
588
|
}
|
|
564
589
|
declare function createShape(input: ShapeInput): ShapeElement;
|
|
590
|
+
interface GridInput extends BaseDefaults {
|
|
591
|
+
gridType?: 'square' | 'hex';
|
|
592
|
+
hexOrientation?: HexOrientation;
|
|
593
|
+
cellSize?: number;
|
|
594
|
+
strokeColor?: string;
|
|
595
|
+
strokeWidth?: number;
|
|
596
|
+
opacity?: number;
|
|
597
|
+
}
|
|
598
|
+
declare function createGrid(input: GridInput): GridElement;
|
|
565
599
|
declare function createText(input: TextInput): TextElement;
|
|
566
600
|
|
|
567
601
|
interface Rect {
|
|
@@ -824,6 +858,6 @@ declare class UpdateLayerCommand implements Command {
|
|
|
824
858
|
undo(_store: ElementStore): void;
|
|
825
859
|
}
|
|
826
860
|
|
|
827
|
-
declare const VERSION = "0.6.
|
|
861
|
+
declare const VERSION = "0.6.1";
|
|
828
862
|
|
|
829
|
-
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, CreateLayerCommand, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, type Layer, LayerManager, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, RemoveLayerCommand, 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, UpdateLayerCommand, 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 };
|
|
863
|
+
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, CreateLayerCommand, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, type GridElement, HandTool, type HexOrientation, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, type Layer, LayerManager, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, RemoveLayerCommand, 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, UpdateLayerCommand, VERSION, Viewport, type ViewportOptions, clearStaleBindings, createArrow, createGrid, 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
|
@@ -85,7 +85,17 @@ interface ShapeElement extends BaseElement {
|
|
|
85
85
|
strokeWidth: number;
|
|
86
86
|
fillColor: string;
|
|
87
87
|
}
|
|
88
|
-
type
|
|
88
|
+
type HexOrientation = 'pointy' | 'flat';
|
|
89
|
+
interface GridElement extends BaseElement {
|
|
90
|
+
type: 'grid';
|
|
91
|
+
gridType: 'square' | 'hex';
|
|
92
|
+
hexOrientation: HexOrientation;
|
|
93
|
+
cellSize: number;
|
|
94
|
+
strokeColor: string;
|
|
95
|
+
strokeWidth: number;
|
|
96
|
+
opacity: number;
|
|
97
|
+
}
|
|
98
|
+
type CanvasElement = StrokeElement | NoteElement | ArrowElement | ImageElement | HtmlElement | TextElement | ShapeElement | GridElement;
|
|
89
99
|
type ElementType = CanvasElement['type'];
|
|
90
100
|
|
|
91
101
|
interface Layer {
|
|
@@ -437,6 +447,16 @@ declare class Viewport {
|
|
|
437
447
|
w: number;
|
|
438
448
|
h: number;
|
|
439
449
|
}): string;
|
|
450
|
+
addGrid(input: {
|
|
451
|
+
gridType?: 'square' | 'hex';
|
|
452
|
+
hexOrientation?: 'pointy' | 'flat';
|
|
453
|
+
cellSize?: number;
|
|
454
|
+
strokeColor?: string;
|
|
455
|
+
strokeWidth?: number;
|
|
456
|
+
opacity?: number;
|
|
457
|
+
}): string;
|
|
458
|
+
updateGrid(updates: Partial<Pick<GridElement, 'gridType' | 'hexOrientation' | 'cellSize' | 'strokeColor' | 'strokeWidth' | 'opacity'>>): void;
|
|
459
|
+
removeGrid(): void;
|
|
440
460
|
destroy(): void;
|
|
441
461
|
private startRenderLoop;
|
|
442
462
|
private render;
|
|
@@ -469,8 +489,12 @@ declare class ElementRenderer {
|
|
|
469
489
|
private store;
|
|
470
490
|
private imageCache;
|
|
471
491
|
private onImageLoad;
|
|
492
|
+
private camera;
|
|
493
|
+
private canvasSize;
|
|
472
494
|
setStore(store: ElementStore): void;
|
|
473
495
|
setOnImageLoad(callback: () => void): void;
|
|
496
|
+
setCamera(camera: Camera): void;
|
|
497
|
+
setCanvasSize(w: number, h: number): void;
|
|
474
498
|
isDomElement(element: CanvasElement): boolean;
|
|
475
499
|
renderCanvasElement(ctx: CanvasRenderingContext2D, element: CanvasElement): void;
|
|
476
500
|
private renderStroke;
|
|
@@ -480,6 +504,7 @@ declare class ElementRenderer {
|
|
|
480
504
|
private renderShape;
|
|
481
505
|
private fillShapePath;
|
|
482
506
|
private strokeShapePath;
|
|
507
|
+
private renderGrid;
|
|
483
508
|
private renderImage;
|
|
484
509
|
private getImage;
|
|
485
510
|
}
|
|
@@ -562,6 +587,15 @@ interface ShapeInput extends BaseDefaults {
|
|
|
562
587
|
fillColor?: string;
|
|
563
588
|
}
|
|
564
589
|
declare function createShape(input: ShapeInput): ShapeElement;
|
|
590
|
+
interface GridInput extends BaseDefaults {
|
|
591
|
+
gridType?: 'square' | 'hex';
|
|
592
|
+
hexOrientation?: HexOrientation;
|
|
593
|
+
cellSize?: number;
|
|
594
|
+
strokeColor?: string;
|
|
595
|
+
strokeWidth?: number;
|
|
596
|
+
opacity?: number;
|
|
597
|
+
}
|
|
598
|
+
declare function createGrid(input: GridInput): GridElement;
|
|
565
599
|
declare function createText(input: TextInput): TextElement;
|
|
566
600
|
|
|
567
601
|
interface Rect {
|
|
@@ -824,6 +858,6 @@ declare class UpdateLayerCommand implements Command {
|
|
|
824
858
|
undo(_store: ElementStore): void;
|
|
825
859
|
}
|
|
826
860
|
|
|
827
|
-
declare const VERSION = "0.6.
|
|
861
|
+
declare const VERSION = "0.6.1";
|
|
828
862
|
|
|
829
|
-
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, CreateLayerCommand, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, type Layer, LayerManager, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, RemoveLayerCommand, 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, UpdateLayerCommand, 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 };
|
|
863
|
+
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, CreateLayerCommand, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, type GridElement, HandTool, type HexOrientation, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, type Layer, LayerManager, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, RemoveLayerCommand, 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, UpdateLayerCommand, VERSION, Viewport, type ViewportOptions, clearStaleBindings, createArrow, createGrid, 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
|
@@ -84,7 +84,7 @@ function validateState(data) {
|
|
|
84
84
|
];
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
var VALID_TYPES = /* @__PURE__ */ new Set(["stroke", "note", "arrow", "image", "html", "text", "shape"]);
|
|
87
|
+
var VALID_TYPES = /* @__PURE__ */ new Set(["stroke", "note", "arrow", "image", "html", "text", "shape", "grid"]);
|
|
88
88
|
function validateElement(el) {
|
|
89
89
|
if (!el || typeof el !== "object") {
|
|
90
90
|
throw new Error("Invalid element: expected an object");
|
|
@@ -205,7 +205,11 @@ var AutoSave = class {
|
|
|
205
205
|
if (typeof localStorage === "undefined") return;
|
|
206
206
|
const layers = this.layerManager?.snapshot() ?? [];
|
|
207
207
|
const state = exportState(this.store.snapshot(), this.camera, layers);
|
|
208
|
-
|
|
208
|
+
try {
|
|
209
|
+
localStorage.setItem(this.key, JSON.stringify(state));
|
|
210
|
+
} catch {
|
|
211
|
+
console.warn("Auto-save failed: storage quota exceeded. State too large for localStorage.");
|
|
212
|
+
}
|
|
209
213
|
}
|
|
210
214
|
};
|
|
211
215
|
|
|
@@ -941,6 +945,118 @@ function smoothToSegments(points) {
|
|
|
941
945
|
return segments;
|
|
942
946
|
}
|
|
943
947
|
|
|
948
|
+
// src/elements/grid-renderer.ts
|
|
949
|
+
function getSquareGridLines(bounds, cellSize) {
|
|
950
|
+
if (cellSize <= 0) return { verticals: [], horizontals: [] };
|
|
951
|
+
const verticals = [];
|
|
952
|
+
const startX = Math.floor(bounds.minX / cellSize) * cellSize;
|
|
953
|
+
const endX = Math.ceil(bounds.maxX / cellSize) * cellSize;
|
|
954
|
+
for (let x = startX; x <= endX; x += cellSize) {
|
|
955
|
+
verticals.push(x);
|
|
956
|
+
}
|
|
957
|
+
const horizontals = [];
|
|
958
|
+
const startY = Math.floor(bounds.minY / cellSize) * cellSize;
|
|
959
|
+
const endY = Math.ceil(bounds.maxY / cellSize) * cellSize;
|
|
960
|
+
for (let y = startY; y <= endY; y += cellSize) {
|
|
961
|
+
horizontals.push(y);
|
|
962
|
+
}
|
|
963
|
+
return { verticals, horizontals };
|
|
964
|
+
}
|
|
965
|
+
function getHexVertices(cx, cy, circumradius, orientation) {
|
|
966
|
+
const vertices = [];
|
|
967
|
+
const angleOffset = orientation === "pointy" ? -Math.PI / 2 : 0;
|
|
968
|
+
for (let i = 0; i < 6; i++) {
|
|
969
|
+
const angle = Math.PI / 3 * i + angleOffset;
|
|
970
|
+
vertices.push({
|
|
971
|
+
x: cx + circumradius * Math.cos(angle),
|
|
972
|
+
y: cy + circumradius * Math.sin(angle)
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
return vertices;
|
|
976
|
+
}
|
|
977
|
+
function getHexCenters(bounds, circumradius, orientation) {
|
|
978
|
+
if (circumradius <= 0) return [];
|
|
979
|
+
const centers = [];
|
|
980
|
+
if (orientation === "pointy") {
|
|
981
|
+
const hexW = Math.sqrt(3) * circumradius;
|
|
982
|
+
const hexH = 2 * circumradius;
|
|
983
|
+
const rowH = hexH * 0.75;
|
|
984
|
+
const startRow = Math.floor((bounds.minY - circumradius) / rowH);
|
|
985
|
+
const endRow = Math.ceil((bounds.maxY + circumradius) / rowH);
|
|
986
|
+
const startCol = Math.floor((bounds.minX - hexW) / hexW);
|
|
987
|
+
const endCol = Math.ceil((bounds.maxX + hexW) / hexW);
|
|
988
|
+
for (let row = startRow; row <= endRow; row++) {
|
|
989
|
+
const offsetX = row % 2 !== 0 ? hexW / 2 : 0;
|
|
990
|
+
for (let col = startCol; col <= endCol; col++) {
|
|
991
|
+
centers.push({
|
|
992
|
+
x: col * hexW + offsetX,
|
|
993
|
+
y: row * rowH
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
} else {
|
|
998
|
+
const hexW = 2 * circumradius;
|
|
999
|
+
const hexH = Math.sqrt(3) * circumradius;
|
|
1000
|
+
const colW = hexW * 0.75;
|
|
1001
|
+
const startCol = Math.floor((bounds.minX - circumradius) / colW);
|
|
1002
|
+
const endCol = Math.ceil((bounds.maxX + circumradius) / colW);
|
|
1003
|
+
const startRow = Math.floor((bounds.minY - hexH) / hexH);
|
|
1004
|
+
const endRow = Math.ceil((bounds.maxY + hexH) / hexH);
|
|
1005
|
+
for (let col = startCol; col <= endCol; col++) {
|
|
1006
|
+
const offsetY = col % 2 !== 0 ? hexH / 2 : 0;
|
|
1007
|
+
for (let row = startRow; row <= endRow; row++) {
|
|
1008
|
+
centers.push({
|
|
1009
|
+
x: col * colW,
|
|
1010
|
+
y: row * hexH + offsetY
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
return centers;
|
|
1016
|
+
}
|
|
1017
|
+
function renderSquareGrid(ctx, bounds, cellSize, strokeColor, strokeWidth, opacity) {
|
|
1018
|
+
if (cellSize <= 0) return;
|
|
1019
|
+
const { verticals, horizontals } = getSquareGridLines(bounds, cellSize);
|
|
1020
|
+
ctx.save();
|
|
1021
|
+
ctx.strokeStyle = strokeColor;
|
|
1022
|
+
ctx.lineWidth = strokeWidth;
|
|
1023
|
+
ctx.globalAlpha = opacity;
|
|
1024
|
+
ctx.beginPath();
|
|
1025
|
+
for (const x of verticals) {
|
|
1026
|
+
ctx.moveTo(x, bounds.minY);
|
|
1027
|
+
ctx.lineTo(x, bounds.maxY);
|
|
1028
|
+
}
|
|
1029
|
+
for (const y of horizontals) {
|
|
1030
|
+
ctx.moveTo(bounds.minX, y);
|
|
1031
|
+
ctx.lineTo(bounds.maxX, y);
|
|
1032
|
+
}
|
|
1033
|
+
ctx.stroke();
|
|
1034
|
+
ctx.restore();
|
|
1035
|
+
}
|
|
1036
|
+
function renderHexGrid(ctx, bounds, cellSize, orientation, strokeColor, strokeWidth, opacity) {
|
|
1037
|
+
if (cellSize <= 0) return;
|
|
1038
|
+
const centers = getHexCenters(bounds, cellSize, orientation);
|
|
1039
|
+
ctx.save();
|
|
1040
|
+
ctx.strokeStyle = strokeColor;
|
|
1041
|
+
ctx.lineWidth = strokeWidth;
|
|
1042
|
+
ctx.globalAlpha = opacity;
|
|
1043
|
+
ctx.beginPath();
|
|
1044
|
+
for (const center of centers) {
|
|
1045
|
+
const verts = getHexVertices(center.x, center.y, cellSize, orientation);
|
|
1046
|
+
const first = verts[0];
|
|
1047
|
+
if (!first) continue;
|
|
1048
|
+
ctx.moveTo(first.x, first.y);
|
|
1049
|
+
for (let i = 1; i < verts.length; i++) {
|
|
1050
|
+
const v = verts[i];
|
|
1051
|
+
if (!v) continue;
|
|
1052
|
+
ctx.lineTo(v.x, v.y);
|
|
1053
|
+
}
|
|
1054
|
+
ctx.closePath();
|
|
1055
|
+
}
|
|
1056
|
+
ctx.stroke();
|
|
1057
|
+
ctx.restore();
|
|
1058
|
+
}
|
|
1059
|
+
|
|
944
1060
|
// src/elements/element-renderer.ts
|
|
945
1061
|
var DOM_ELEMENT_TYPES = /* @__PURE__ */ new Set(["note", "html", "text"]);
|
|
946
1062
|
var ARROWHEAD_LENGTH = 12;
|
|
@@ -949,12 +1065,20 @@ var ElementRenderer = class {
|
|
|
949
1065
|
store = null;
|
|
950
1066
|
imageCache = /* @__PURE__ */ new Map();
|
|
951
1067
|
onImageLoad = null;
|
|
1068
|
+
camera = null;
|
|
1069
|
+
canvasSize = null;
|
|
952
1070
|
setStore(store) {
|
|
953
1071
|
this.store = store;
|
|
954
1072
|
}
|
|
955
1073
|
setOnImageLoad(callback) {
|
|
956
1074
|
this.onImageLoad = callback;
|
|
957
1075
|
}
|
|
1076
|
+
setCamera(camera) {
|
|
1077
|
+
this.camera = camera;
|
|
1078
|
+
}
|
|
1079
|
+
setCanvasSize(w, h) {
|
|
1080
|
+
this.canvasSize = { w, h };
|
|
1081
|
+
}
|
|
958
1082
|
isDomElement(element) {
|
|
959
1083
|
return DOM_ELEMENT_TYPES.has(element.type);
|
|
960
1084
|
}
|
|
@@ -972,6 +1096,9 @@ var ElementRenderer = class {
|
|
|
972
1096
|
case "image":
|
|
973
1097
|
this.renderImage(ctx, element);
|
|
974
1098
|
break;
|
|
1099
|
+
case "grid":
|
|
1100
|
+
this.renderGrid(ctx, element);
|
|
1101
|
+
break;
|
|
975
1102
|
}
|
|
976
1103
|
}
|
|
977
1104
|
renderStroke(ctx, stroke) {
|
|
@@ -1107,6 +1234,42 @@ var ElementRenderer = class {
|
|
|
1107
1234
|
}
|
|
1108
1235
|
}
|
|
1109
1236
|
}
|
|
1237
|
+
renderGrid(ctx, grid) {
|
|
1238
|
+
if (!this.canvasSize) return;
|
|
1239
|
+
const cam = this.camera;
|
|
1240
|
+
if (!cam) return;
|
|
1241
|
+
const topLeft = cam.screenToWorld({ x: 0, y: 0 });
|
|
1242
|
+
const bottomRight = cam.screenToWorld({
|
|
1243
|
+
x: this.canvasSize.w,
|
|
1244
|
+
y: this.canvasSize.h
|
|
1245
|
+
});
|
|
1246
|
+
const bounds = {
|
|
1247
|
+
minX: topLeft.x,
|
|
1248
|
+
minY: topLeft.y,
|
|
1249
|
+
maxX: bottomRight.x,
|
|
1250
|
+
maxY: bottomRight.y
|
|
1251
|
+
};
|
|
1252
|
+
if (grid.gridType === "hex") {
|
|
1253
|
+
renderHexGrid(
|
|
1254
|
+
ctx,
|
|
1255
|
+
bounds,
|
|
1256
|
+
grid.cellSize,
|
|
1257
|
+
grid.hexOrientation,
|
|
1258
|
+
grid.strokeColor,
|
|
1259
|
+
grid.strokeWidth,
|
|
1260
|
+
grid.opacity
|
|
1261
|
+
);
|
|
1262
|
+
} else {
|
|
1263
|
+
renderSquareGrid(
|
|
1264
|
+
ctx,
|
|
1265
|
+
bounds,
|
|
1266
|
+
grid.cellSize,
|
|
1267
|
+
grid.strokeColor,
|
|
1268
|
+
grid.strokeWidth,
|
|
1269
|
+
grid.opacity
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1110
1273
|
renderImage(ctx, image) {
|
|
1111
1274
|
const img = this.getImage(image.src);
|
|
1112
1275
|
if (!img) return;
|
|
@@ -1549,6 +1712,22 @@ function createShape(input) {
|
|
|
1549
1712
|
fillColor: input.fillColor ?? "none"
|
|
1550
1713
|
};
|
|
1551
1714
|
}
|
|
1715
|
+
function createGrid(input) {
|
|
1716
|
+
return {
|
|
1717
|
+
id: createId("grid"),
|
|
1718
|
+
type: "grid",
|
|
1719
|
+
position: input.position ?? { x: 0, y: 0 },
|
|
1720
|
+
zIndex: input.zIndex ?? 0,
|
|
1721
|
+
locked: input.locked ?? false,
|
|
1722
|
+
layerId: input.layerId ?? "",
|
|
1723
|
+
gridType: input.gridType ?? "square",
|
|
1724
|
+
hexOrientation: input.hexOrientation ?? "pointy",
|
|
1725
|
+
cellSize: input.cellSize ?? 40,
|
|
1726
|
+
strokeColor: input.strokeColor ?? "#000000",
|
|
1727
|
+
strokeWidth: input.strokeWidth ?? 1,
|
|
1728
|
+
opacity: input.opacity ?? 1
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1552
1731
|
function createText(input) {
|
|
1553
1732
|
return {
|
|
1554
1733
|
id: createId("text"),
|
|
@@ -1726,6 +1905,7 @@ var Viewport = class {
|
|
|
1726
1905
|
this.toolManager = new ToolManager();
|
|
1727
1906
|
this.renderer = new ElementRenderer();
|
|
1728
1907
|
this.renderer.setStore(this.store);
|
|
1908
|
+
this.renderer.setCamera(this.camera);
|
|
1729
1909
|
this.renderer.setOnImageLoad(() => this.requestRender());
|
|
1730
1910
|
this.noteEditor = new NoteEditor();
|
|
1731
1911
|
this.noteEditor.setOnStop((id) => this.onTextEditStop(id));
|
|
@@ -1872,6 +2052,34 @@ var Viewport = class {
|
|
|
1872
2052
|
this.requestRender();
|
|
1873
2053
|
return el.id;
|
|
1874
2054
|
}
|
|
2055
|
+
addGrid(input) {
|
|
2056
|
+
const existing = this.store.getElementsByType("grid")[0];
|
|
2057
|
+
this.historyRecorder.begin();
|
|
2058
|
+
if (existing) {
|
|
2059
|
+
this.store.remove(existing.id);
|
|
2060
|
+
}
|
|
2061
|
+
const grid = createGrid({ ...input, layerId: this.layerManager.activeLayerId });
|
|
2062
|
+
this.store.add(grid);
|
|
2063
|
+
this.historyRecorder.commit();
|
|
2064
|
+
this.requestRender();
|
|
2065
|
+
return grid.id;
|
|
2066
|
+
}
|
|
2067
|
+
updateGrid(updates) {
|
|
2068
|
+
const grid = this.store.getElementsByType("grid")[0];
|
|
2069
|
+
if (!grid) return;
|
|
2070
|
+
this.historyRecorder.begin();
|
|
2071
|
+
this.store.update(grid.id, updates);
|
|
2072
|
+
this.historyRecorder.commit();
|
|
2073
|
+
this.requestRender();
|
|
2074
|
+
}
|
|
2075
|
+
removeGrid() {
|
|
2076
|
+
const grid = this.store.getElementsByType("grid")[0];
|
|
2077
|
+
if (!grid) return;
|
|
2078
|
+
this.historyRecorder.begin();
|
|
2079
|
+
this.store.remove(grid.id);
|
|
2080
|
+
this.historyRecorder.commit();
|
|
2081
|
+
this.requestRender();
|
|
2082
|
+
}
|
|
1875
2083
|
destroy() {
|
|
1876
2084
|
cancelAnimationFrame(this.animFrameId);
|
|
1877
2085
|
this.stopInteracting();
|
|
@@ -1903,6 +2111,7 @@ var Viewport = class {
|
|
|
1903
2111
|
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
1904
2112
|
ctx.save();
|
|
1905
2113
|
ctx.scale(dpr, dpr);
|
|
2114
|
+
this.renderer.setCanvasSize(this.canvasEl.clientWidth, this.canvasEl.clientHeight);
|
|
1906
2115
|
this.background.render(ctx, this.camera);
|
|
1907
2116
|
ctx.save();
|
|
1908
2117
|
ctx.translate(this.camera.position.x, this.camera.position.y);
|
|
@@ -2889,6 +3098,7 @@ var SelectTool = class {
|
|
|
2889
3098
|
for (const el of ctx.store.getAll()) {
|
|
2890
3099
|
if (ctx.isLayerVisible && !ctx.isLayerVisible(el.layerId)) continue;
|
|
2891
3100
|
if (ctx.isLayerLocked && ctx.isLayerLocked(el.layerId)) continue;
|
|
3101
|
+
if (el.type === "grid") continue;
|
|
2892
3102
|
const bounds = this.getElementBounds(el);
|
|
2893
3103
|
if (bounds && this.rectsOverlap(marquee, bounds)) {
|
|
2894
3104
|
ids.push(el.id);
|
|
@@ -2925,11 +3135,13 @@ var SelectTool = class {
|
|
|
2925
3135
|
for (const el of elements) {
|
|
2926
3136
|
if (ctx.isLayerVisible && !ctx.isLayerVisible(el.layerId)) continue;
|
|
2927
3137
|
if (ctx.isLayerLocked && ctx.isLayerLocked(el.layerId)) continue;
|
|
3138
|
+
if (el.type === "grid") continue;
|
|
2928
3139
|
if (this.isInsideBounds(world, el)) return el;
|
|
2929
3140
|
}
|
|
2930
3141
|
return null;
|
|
2931
3142
|
}
|
|
2932
3143
|
isInsideBounds(point, el) {
|
|
3144
|
+
if (el.type === "grid") return false;
|
|
2933
3145
|
if ("size" in el) {
|
|
2934
3146
|
const s = el.size;
|
|
2935
3147
|
return point.x >= el.position.x && point.x <= el.position.x + s.w && point.y >= el.position.y && point.y <= el.position.y + s.h;
|
|
@@ -3355,7 +3567,7 @@ var UpdateLayerCommand = class {
|
|
|
3355
3567
|
};
|
|
3356
3568
|
|
|
3357
3569
|
// src/index.ts
|
|
3358
|
-
var VERSION = "0.6.
|
|
3570
|
+
var VERSION = "0.6.1";
|
|
3359
3571
|
export {
|
|
3360
3572
|
AddElementCommand,
|
|
3361
3573
|
ArrowTool,
|
|
@@ -3389,6 +3601,7 @@ export {
|
|
|
3389
3601
|
Viewport,
|
|
3390
3602
|
clearStaleBindings,
|
|
3391
3603
|
createArrow,
|
|
3604
|
+
createGrid,
|
|
3392
3605
|
createHtmlElement,
|
|
3393
3606
|
createId,
|
|
3394
3607
|
createImage,
|