@fieldnotes/core 0.3.1 → 0.4.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 +185 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -4
- package/dist/index.d.ts +54 -4
- package/dist/index.js +183 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -74,7 +74,16 @@ interface TextElement extends BaseElement {
|
|
|
74
74
|
color: string;
|
|
75
75
|
textAlign: 'left' | 'center' | 'right';
|
|
76
76
|
}
|
|
77
|
-
type
|
|
77
|
+
type ShapeKind = 'rectangle' | 'ellipse';
|
|
78
|
+
interface ShapeElement extends BaseElement {
|
|
79
|
+
type: 'shape';
|
|
80
|
+
shape: ShapeKind;
|
|
81
|
+
size: Size;
|
|
82
|
+
strokeColor: string;
|
|
83
|
+
strokeWidth: number;
|
|
84
|
+
fillColor: string;
|
|
85
|
+
}
|
|
86
|
+
type CanvasElement = StrokeElement | NoteElement | ArrowElement | ImageElement | HtmlElement | TextElement | ShapeElement;
|
|
78
87
|
type ElementType = CanvasElement['type'];
|
|
79
88
|
|
|
80
89
|
interface CanvasState {
|
|
@@ -209,7 +218,7 @@ interface Tool {
|
|
|
209
218
|
onDeactivate?(ctx: ToolContext): void;
|
|
210
219
|
renderOverlay?(ctx: CanvasRenderingContext2D): void;
|
|
211
220
|
}
|
|
212
|
-
type ToolName = 'hand' | 'select' | 'pencil' | 'eraser' | 'arrow' | 'note' | 'image' | 'text';
|
|
221
|
+
type ToolName = 'hand' | 'select' | 'pencil' | 'eraser' | 'arrow' | 'note' | 'image' | 'text' | 'shape';
|
|
213
222
|
|
|
214
223
|
declare class ToolManager {
|
|
215
224
|
private tools;
|
|
@@ -406,6 +415,9 @@ declare class ElementRenderer {
|
|
|
406
415
|
private renderArrow;
|
|
407
416
|
private renderArrowhead;
|
|
408
417
|
private getVisualEndpoints;
|
|
418
|
+
private renderShape;
|
|
419
|
+
private fillShapePath;
|
|
420
|
+
private strokeShapePath;
|
|
409
421
|
}
|
|
410
422
|
|
|
411
423
|
declare class NoteEditor {
|
|
@@ -475,6 +487,15 @@ declare function createNote(input: NoteInput): NoteElement;
|
|
|
475
487
|
declare function createArrow(input: ArrowInput): ArrowElement;
|
|
476
488
|
declare function createImage(input: ImageInput): ImageElement;
|
|
477
489
|
declare function createHtmlElement(input: HtmlInput): HtmlElement;
|
|
490
|
+
interface ShapeInput extends BaseDefaults {
|
|
491
|
+
position: Point;
|
|
492
|
+
size: Size;
|
|
493
|
+
shape?: ShapeKind;
|
|
494
|
+
strokeColor?: string;
|
|
495
|
+
strokeWidth?: number;
|
|
496
|
+
fillColor?: string;
|
|
497
|
+
}
|
|
498
|
+
declare function createShape(input: ShapeInput): ShapeElement;
|
|
478
499
|
declare function createText(input: TextInput): TextElement;
|
|
479
500
|
|
|
480
501
|
interface Rect {
|
|
@@ -679,6 +700,35 @@ declare class ImageTool implements Tool {
|
|
|
679
700
|
onPointerUp(state: PointerState, ctx: ToolContext): void;
|
|
680
701
|
}
|
|
681
702
|
|
|
682
|
-
|
|
703
|
+
interface ShapeToolOptions {
|
|
704
|
+
shape?: ShapeKind;
|
|
705
|
+
strokeColor?: string;
|
|
706
|
+
strokeWidth?: number;
|
|
707
|
+
fillColor?: string;
|
|
708
|
+
}
|
|
709
|
+
declare class ShapeTool implements Tool {
|
|
710
|
+
readonly name = "shape";
|
|
711
|
+
private drawing;
|
|
712
|
+
private start;
|
|
713
|
+
private end;
|
|
714
|
+
private shiftHeld;
|
|
715
|
+
private shape;
|
|
716
|
+
private strokeColor;
|
|
717
|
+
private strokeWidth;
|
|
718
|
+
private fillColor;
|
|
719
|
+
constructor(options?: ShapeToolOptions);
|
|
720
|
+
setOptions(options: ShapeToolOptions): void;
|
|
721
|
+
onActivate(_ctx: ToolContext): void;
|
|
722
|
+
onDeactivate(_ctx: ToolContext): void;
|
|
723
|
+
onPointerDown(state: PointerState, ctx: ToolContext): void;
|
|
724
|
+
onPointerMove(state: PointerState, ctx: ToolContext): void;
|
|
725
|
+
onPointerUp(_state: PointerState, ctx: ToolContext): void;
|
|
726
|
+
renderOverlay(ctx: CanvasRenderingContext2D): void;
|
|
727
|
+
private computeRect;
|
|
728
|
+
private onKeyDown;
|
|
729
|
+
private onKeyUp;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
declare const VERSION = "0.4.0";
|
|
683
733
|
|
|
684
|
-
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 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, createStroke, createText, exportState, findBindTarget, findBoundArrows, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getEdgeIntersection, getElementBounds, getElementCenter, isBindable, isNearBezier, parseState, unbindArrow, updateBoundArrow };
|
|
734
|
+
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -74,7 +74,16 @@ interface TextElement extends BaseElement {
|
|
|
74
74
|
color: string;
|
|
75
75
|
textAlign: 'left' | 'center' | 'right';
|
|
76
76
|
}
|
|
77
|
-
type
|
|
77
|
+
type ShapeKind = 'rectangle' | 'ellipse';
|
|
78
|
+
interface ShapeElement extends BaseElement {
|
|
79
|
+
type: 'shape';
|
|
80
|
+
shape: ShapeKind;
|
|
81
|
+
size: Size;
|
|
82
|
+
strokeColor: string;
|
|
83
|
+
strokeWidth: number;
|
|
84
|
+
fillColor: string;
|
|
85
|
+
}
|
|
86
|
+
type CanvasElement = StrokeElement | NoteElement | ArrowElement | ImageElement | HtmlElement | TextElement | ShapeElement;
|
|
78
87
|
type ElementType = CanvasElement['type'];
|
|
79
88
|
|
|
80
89
|
interface CanvasState {
|
|
@@ -209,7 +218,7 @@ interface Tool {
|
|
|
209
218
|
onDeactivate?(ctx: ToolContext): void;
|
|
210
219
|
renderOverlay?(ctx: CanvasRenderingContext2D): void;
|
|
211
220
|
}
|
|
212
|
-
type ToolName = 'hand' | 'select' | 'pencil' | 'eraser' | 'arrow' | 'note' | 'image' | 'text';
|
|
221
|
+
type ToolName = 'hand' | 'select' | 'pencil' | 'eraser' | 'arrow' | 'note' | 'image' | 'text' | 'shape';
|
|
213
222
|
|
|
214
223
|
declare class ToolManager {
|
|
215
224
|
private tools;
|
|
@@ -406,6 +415,9 @@ declare class ElementRenderer {
|
|
|
406
415
|
private renderArrow;
|
|
407
416
|
private renderArrowhead;
|
|
408
417
|
private getVisualEndpoints;
|
|
418
|
+
private renderShape;
|
|
419
|
+
private fillShapePath;
|
|
420
|
+
private strokeShapePath;
|
|
409
421
|
}
|
|
410
422
|
|
|
411
423
|
declare class NoteEditor {
|
|
@@ -475,6 +487,15 @@ declare function createNote(input: NoteInput): NoteElement;
|
|
|
475
487
|
declare function createArrow(input: ArrowInput): ArrowElement;
|
|
476
488
|
declare function createImage(input: ImageInput): ImageElement;
|
|
477
489
|
declare function createHtmlElement(input: HtmlInput): HtmlElement;
|
|
490
|
+
interface ShapeInput extends BaseDefaults {
|
|
491
|
+
position: Point;
|
|
492
|
+
size: Size;
|
|
493
|
+
shape?: ShapeKind;
|
|
494
|
+
strokeColor?: string;
|
|
495
|
+
strokeWidth?: number;
|
|
496
|
+
fillColor?: string;
|
|
497
|
+
}
|
|
498
|
+
declare function createShape(input: ShapeInput): ShapeElement;
|
|
478
499
|
declare function createText(input: TextInput): TextElement;
|
|
479
500
|
|
|
480
501
|
interface Rect {
|
|
@@ -679,6 +700,35 @@ declare class ImageTool implements Tool {
|
|
|
679
700
|
onPointerUp(state: PointerState, ctx: ToolContext): void;
|
|
680
701
|
}
|
|
681
702
|
|
|
682
|
-
|
|
703
|
+
interface ShapeToolOptions {
|
|
704
|
+
shape?: ShapeKind;
|
|
705
|
+
strokeColor?: string;
|
|
706
|
+
strokeWidth?: number;
|
|
707
|
+
fillColor?: string;
|
|
708
|
+
}
|
|
709
|
+
declare class ShapeTool implements Tool {
|
|
710
|
+
readonly name = "shape";
|
|
711
|
+
private drawing;
|
|
712
|
+
private start;
|
|
713
|
+
private end;
|
|
714
|
+
private shiftHeld;
|
|
715
|
+
private shape;
|
|
716
|
+
private strokeColor;
|
|
717
|
+
private strokeWidth;
|
|
718
|
+
private fillColor;
|
|
719
|
+
constructor(options?: ShapeToolOptions);
|
|
720
|
+
setOptions(options: ShapeToolOptions): void;
|
|
721
|
+
onActivate(_ctx: ToolContext): void;
|
|
722
|
+
onDeactivate(_ctx: ToolContext): void;
|
|
723
|
+
onPointerDown(state: PointerState, ctx: ToolContext): void;
|
|
724
|
+
onPointerMove(state: PointerState, ctx: ToolContext): void;
|
|
725
|
+
onPointerUp(_state: PointerState, ctx: ToolContext): void;
|
|
726
|
+
renderOverlay(ctx: CanvasRenderingContext2D): void;
|
|
727
|
+
private computeRect;
|
|
728
|
+
private onKeyDown;
|
|
729
|
+
private onKeyUp;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
declare const VERSION = "0.4.0";
|
|
683
733
|
|
|
684
|
-
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 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, createStroke, createText, exportState, findBindTarget, findBoundArrows, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getEdgeIntersection, getElementBounds, getElementCenter, isBindable, isNearBezier, parseState, unbindArrow, updateBoundArrow };
|
|
734
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -70,7 +70,7 @@ function validateState(data) {
|
|
|
70
70
|
}
|
|
71
71
|
cleanBindings(obj["elements"]);
|
|
72
72
|
}
|
|
73
|
-
var VALID_TYPES = /* @__PURE__ */ new Set(["stroke", "note", "arrow", "image", "html", "text"]);
|
|
73
|
+
var VALID_TYPES = /* @__PURE__ */ new Set(["stroke", "note", "arrow", "image", "html", "text", "shape"]);
|
|
74
74
|
function validateElement(el) {
|
|
75
75
|
if (!el || typeof el !== "object") {
|
|
76
76
|
throw new Error("Invalid element: expected an object");
|
|
@@ -111,6 +111,9 @@ function migrateElement(obj) {
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
+
if (obj["type"] === "shape" && typeof obj["shape"] !== "string") {
|
|
115
|
+
obj["shape"] = "rectangle";
|
|
116
|
+
}
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
// src/core/auto-save.ts
|
|
@@ -694,7 +697,7 @@ function isNearLine(point, a, b, threshold) {
|
|
|
694
697
|
}
|
|
695
698
|
|
|
696
699
|
// src/elements/arrow-binding.ts
|
|
697
|
-
var BINDABLE_TYPES = /* @__PURE__ */ new Set(["note", "text", "image", "html"]);
|
|
700
|
+
var BINDABLE_TYPES = /* @__PURE__ */ new Set(["note", "text", "image", "html", "shape"]);
|
|
698
701
|
function isBindable(element) {
|
|
699
702
|
return BINDABLE_TYPES.has(element.type);
|
|
700
703
|
}
|
|
@@ -914,6 +917,9 @@ var ElementRenderer = class {
|
|
|
914
917
|
case "arrow":
|
|
915
918
|
this.renderArrow(ctx, element);
|
|
916
919
|
break;
|
|
920
|
+
case "shape":
|
|
921
|
+
this.renderShape(ctx, element);
|
|
922
|
+
break;
|
|
917
923
|
}
|
|
918
924
|
}
|
|
919
925
|
renderStroke(ctx, stroke) {
|
|
@@ -1006,6 +1012,49 @@ var ElementRenderer = class {
|
|
|
1006
1012
|
}
|
|
1007
1013
|
return { visualFrom, visualTo };
|
|
1008
1014
|
}
|
|
1015
|
+
renderShape(ctx, shape) {
|
|
1016
|
+
ctx.save();
|
|
1017
|
+
if (shape.fillColor !== "none") {
|
|
1018
|
+
ctx.fillStyle = shape.fillColor;
|
|
1019
|
+
this.fillShapePath(ctx, shape);
|
|
1020
|
+
}
|
|
1021
|
+
if (shape.strokeWidth > 0) {
|
|
1022
|
+
ctx.strokeStyle = shape.strokeColor;
|
|
1023
|
+
ctx.lineWidth = shape.strokeWidth;
|
|
1024
|
+
this.strokeShapePath(ctx, shape);
|
|
1025
|
+
}
|
|
1026
|
+
ctx.restore();
|
|
1027
|
+
}
|
|
1028
|
+
fillShapePath(ctx, shape) {
|
|
1029
|
+
switch (shape.shape) {
|
|
1030
|
+
case "rectangle":
|
|
1031
|
+
ctx.fillRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);
|
|
1032
|
+
break;
|
|
1033
|
+
case "ellipse": {
|
|
1034
|
+
const cx = shape.position.x + shape.size.w / 2;
|
|
1035
|
+
const cy = shape.position.y + shape.size.h / 2;
|
|
1036
|
+
ctx.beginPath();
|
|
1037
|
+
ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);
|
|
1038
|
+
ctx.fill();
|
|
1039
|
+
break;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
strokeShapePath(ctx, shape) {
|
|
1044
|
+
switch (shape.shape) {
|
|
1045
|
+
case "rectangle":
|
|
1046
|
+
ctx.strokeRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);
|
|
1047
|
+
break;
|
|
1048
|
+
case "ellipse": {
|
|
1049
|
+
const cx = shape.position.x + shape.size.w / 2;
|
|
1050
|
+
const cy = shape.position.y + shape.size.h / 2;
|
|
1051
|
+
ctx.beginPath();
|
|
1052
|
+
ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);
|
|
1053
|
+
ctx.stroke();
|
|
1054
|
+
break;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1009
1058
|
};
|
|
1010
1059
|
|
|
1011
1060
|
// src/elements/note-editor.ts
|
|
@@ -1413,6 +1462,20 @@ function createHtmlElement(input) {
|
|
|
1413
1462
|
size: input.size
|
|
1414
1463
|
};
|
|
1415
1464
|
}
|
|
1465
|
+
function createShape(input) {
|
|
1466
|
+
return {
|
|
1467
|
+
id: createId("shape"),
|
|
1468
|
+
type: "shape",
|
|
1469
|
+
position: input.position,
|
|
1470
|
+
zIndex: input.zIndex ?? 0,
|
|
1471
|
+
locked: input.locked ?? false,
|
|
1472
|
+
shape: input.shape ?? "rectangle",
|
|
1473
|
+
size: input.size,
|
|
1474
|
+
strokeColor: input.strokeColor ?? "#000000",
|
|
1475
|
+
strokeWidth: input.strokeWidth ?? 2,
|
|
1476
|
+
fillColor: input.fillColor ?? "none"
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1416
1479
|
function createText(input) {
|
|
1417
1480
|
return {
|
|
1418
1481
|
id: createId("text"),
|
|
@@ -2854,8 +2917,123 @@ var ImageTool = class {
|
|
|
2854
2917
|
}
|
|
2855
2918
|
};
|
|
2856
2919
|
|
|
2920
|
+
// src/tools/shape-tool.ts
|
|
2921
|
+
var ShapeTool = class {
|
|
2922
|
+
name = "shape";
|
|
2923
|
+
drawing = false;
|
|
2924
|
+
start = { x: 0, y: 0 };
|
|
2925
|
+
end = { x: 0, y: 0 };
|
|
2926
|
+
shiftHeld = false;
|
|
2927
|
+
shape;
|
|
2928
|
+
strokeColor;
|
|
2929
|
+
strokeWidth;
|
|
2930
|
+
fillColor;
|
|
2931
|
+
constructor(options = {}) {
|
|
2932
|
+
this.shape = options.shape ?? "rectangle";
|
|
2933
|
+
this.strokeColor = options.strokeColor ?? "#000000";
|
|
2934
|
+
this.strokeWidth = options.strokeWidth ?? 2;
|
|
2935
|
+
this.fillColor = options.fillColor ?? "none";
|
|
2936
|
+
}
|
|
2937
|
+
setOptions(options) {
|
|
2938
|
+
if (options.shape !== void 0) this.shape = options.shape;
|
|
2939
|
+
if (options.strokeColor !== void 0) this.strokeColor = options.strokeColor;
|
|
2940
|
+
if (options.strokeWidth !== void 0) this.strokeWidth = options.strokeWidth;
|
|
2941
|
+
if (options.fillColor !== void 0) this.fillColor = options.fillColor;
|
|
2942
|
+
}
|
|
2943
|
+
onActivate(_ctx) {
|
|
2944
|
+
if (typeof window !== "undefined") {
|
|
2945
|
+
window.addEventListener("keydown", this.onKeyDown);
|
|
2946
|
+
window.addEventListener("keyup", this.onKeyUp);
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
onDeactivate(_ctx) {
|
|
2950
|
+
this.shiftHeld = false;
|
|
2951
|
+
if (typeof window !== "undefined") {
|
|
2952
|
+
window.removeEventListener("keydown", this.onKeyDown);
|
|
2953
|
+
window.removeEventListener("keyup", this.onKeyUp);
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
onPointerDown(state, ctx) {
|
|
2957
|
+
this.drawing = true;
|
|
2958
|
+
this.start = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
2959
|
+
this.end = { ...this.start };
|
|
2960
|
+
}
|
|
2961
|
+
onPointerMove(state, ctx) {
|
|
2962
|
+
if (!this.drawing) return;
|
|
2963
|
+
this.end = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
2964
|
+
ctx.requestRender();
|
|
2965
|
+
}
|
|
2966
|
+
onPointerUp(_state, ctx) {
|
|
2967
|
+
if (!this.drawing) return;
|
|
2968
|
+
this.drawing = false;
|
|
2969
|
+
const { position, size } = this.computeRect();
|
|
2970
|
+
if (size.w === 0 || size.h === 0) return;
|
|
2971
|
+
const shape = createShape({
|
|
2972
|
+
position,
|
|
2973
|
+
size,
|
|
2974
|
+
shape: this.shape,
|
|
2975
|
+
strokeColor: this.strokeColor,
|
|
2976
|
+
strokeWidth: this.strokeWidth,
|
|
2977
|
+
fillColor: this.fillColor
|
|
2978
|
+
});
|
|
2979
|
+
ctx.store.add(shape);
|
|
2980
|
+
ctx.requestRender();
|
|
2981
|
+
ctx.switchTool?.("select");
|
|
2982
|
+
}
|
|
2983
|
+
renderOverlay(ctx) {
|
|
2984
|
+
if (!this.drawing) return;
|
|
2985
|
+
const { position, size } = this.computeRect();
|
|
2986
|
+
if (size.w === 0 && size.h === 0) return;
|
|
2987
|
+
ctx.save();
|
|
2988
|
+
ctx.globalAlpha = 0.5;
|
|
2989
|
+
ctx.strokeStyle = this.strokeColor;
|
|
2990
|
+
ctx.lineWidth = this.strokeWidth;
|
|
2991
|
+
if (this.fillColor !== "none") {
|
|
2992
|
+
ctx.fillStyle = this.fillColor;
|
|
2993
|
+
}
|
|
2994
|
+
switch (this.shape) {
|
|
2995
|
+
case "rectangle":
|
|
2996
|
+
if (this.fillColor !== "none") {
|
|
2997
|
+
ctx.fillRect(position.x, position.y, size.w, size.h);
|
|
2998
|
+
}
|
|
2999
|
+
ctx.strokeRect(position.x, position.y, size.w, size.h);
|
|
3000
|
+
break;
|
|
3001
|
+
case "ellipse": {
|
|
3002
|
+
const cx = position.x + size.w / 2;
|
|
3003
|
+
const cy = position.y + size.h / 2;
|
|
3004
|
+
ctx.beginPath();
|
|
3005
|
+
ctx.ellipse(cx, cy, size.w / 2, size.h / 2, 0, 0, Math.PI * 2);
|
|
3006
|
+
if (this.fillColor !== "none") ctx.fill();
|
|
3007
|
+
ctx.stroke();
|
|
3008
|
+
break;
|
|
3009
|
+
}
|
|
3010
|
+
}
|
|
3011
|
+
ctx.restore();
|
|
3012
|
+
}
|
|
3013
|
+
computeRect() {
|
|
3014
|
+
let x = Math.min(this.start.x, this.end.x);
|
|
3015
|
+
let y = Math.min(this.start.y, this.end.y);
|
|
3016
|
+
let w = Math.abs(this.end.x - this.start.x);
|
|
3017
|
+
let h = Math.abs(this.end.y - this.start.y);
|
|
3018
|
+
if (this.shiftHeld) {
|
|
3019
|
+
const side = Math.max(w, h);
|
|
3020
|
+
w = side;
|
|
3021
|
+
h = side;
|
|
3022
|
+
x = this.end.x >= this.start.x ? this.start.x : this.start.x - side;
|
|
3023
|
+
y = this.end.y >= this.start.y ? this.start.y : this.start.y - side;
|
|
3024
|
+
}
|
|
3025
|
+
return { position: { x, y }, size: { w, h } };
|
|
3026
|
+
}
|
|
3027
|
+
onKeyDown = (e) => {
|
|
3028
|
+
if (e.key === "Shift") this.shiftHeld = true;
|
|
3029
|
+
};
|
|
3030
|
+
onKeyUp = (e) => {
|
|
3031
|
+
if (e.key === "Shift") this.shiftHeld = false;
|
|
3032
|
+
};
|
|
3033
|
+
};
|
|
3034
|
+
|
|
2857
3035
|
// src/index.ts
|
|
2858
|
-
var VERSION = "0.
|
|
3036
|
+
var VERSION = "0.4.0";
|
|
2859
3037
|
export {
|
|
2860
3038
|
AddElementCommand,
|
|
2861
3039
|
ArrowTool,
|
|
@@ -2877,6 +3055,7 @@ export {
|
|
|
2877
3055
|
PencilTool,
|
|
2878
3056
|
RemoveElementCommand,
|
|
2879
3057
|
SelectTool,
|
|
3058
|
+
ShapeTool,
|
|
2880
3059
|
TextTool,
|
|
2881
3060
|
ToolManager,
|
|
2882
3061
|
UpdateElementCommand,
|
|
@@ -2888,6 +3067,7 @@ export {
|
|
|
2888
3067
|
createId,
|
|
2889
3068
|
createImage,
|
|
2890
3069
|
createNote,
|
|
3070
|
+
createShape,
|
|
2891
3071
|
createStroke,
|
|
2892
3072
|
createText,
|
|
2893
3073
|
exportState,
|