@fieldnotes/core 0.29.0 → 0.30.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 +595 -583
- package/dist/index.cjs +75 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -3
- package/dist/index.d.ts +14 -3
- package/dist/index.js +75 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -27,6 +27,8 @@ interface StrokeElement extends BaseElement {
|
|
|
27
27
|
color: string;
|
|
28
28
|
width: number;
|
|
29
29
|
opacity: number;
|
|
30
|
+
/** Optional canvas blend mode (e.g. highlighter uses 'multiply'). */
|
|
31
|
+
blendMode?: 'multiply';
|
|
30
32
|
}
|
|
31
33
|
interface NoteElement extends BaseElement {
|
|
32
34
|
type: 'note';
|
|
@@ -72,7 +74,7 @@ interface TextElement extends BaseElement {
|
|
|
72
74
|
color: string;
|
|
73
75
|
textAlign: 'left' | 'center' | 'right';
|
|
74
76
|
}
|
|
75
|
-
type ShapeKind = 'rectangle' | 'ellipse';
|
|
77
|
+
type ShapeKind = 'rectangle' | 'ellipse' | 'line';
|
|
76
78
|
interface ShapeElement extends BaseElement {
|
|
77
79
|
type: 'shape';
|
|
78
80
|
shape: ShapeKind;
|
|
@@ -80,6 +82,8 @@ interface ShapeElement extends BaseElement {
|
|
|
80
82
|
strokeColor: string;
|
|
81
83
|
strokeWidth: number;
|
|
82
84
|
fillColor: string;
|
|
85
|
+
/** Line-only: which bbox diagonal the segment runs along. Absent/false = main diagonal. */
|
|
86
|
+
flip?: boolean;
|
|
83
87
|
}
|
|
84
88
|
type HexOrientation = 'pointy' | 'flat';
|
|
85
89
|
interface GridElement extends BaseElement {
|
|
@@ -562,6 +566,7 @@ interface StrokeInput extends BaseDefaults {
|
|
|
562
566
|
color?: string;
|
|
563
567
|
width?: number;
|
|
564
568
|
opacity?: number;
|
|
569
|
+
blendMode?: 'multiply';
|
|
565
570
|
}
|
|
566
571
|
interface NoteInput extends BaseDefaults {
|
|
567
572
|
position: Point;
|
|
@@ -612,6 +617,7 @@ interface ShapeInput extends BaseDefaults {
|
|
|
612
617
|
strokeColor?: string;
|
|
613
618
|
strokeWidth?: number;
|
|
614
619
|
fillColor?: string;
|
|
620
|
+
flip?: boolean;
|
|
615
621
|
}
|
|
616
622
|
declare function createShape(input: ShapeInput): ShapeElement;
|
|
617
623
|
interface GridInput extends BaseDefaults {
|
|
@@ -669,14 +675,17 @@ declare class HandTool implements Tool {
|
|
|
669
675
|
}
|
|
670
676
|
|
|
671
677
|
interface PencilToolOptions {
|
|
678
|
+
name?: string;
|
|
672
679
|
color?: string;
|
|
673
680
|
width?: number;
|
|
674
681
|
smoothing?: number;
|
|
675
682
|
minPointDistance?: number;
|
|
676
683
|
progressiveSimplifyThreshold?: number;
|
|
684
|
+
opacity?: number;
|
|
685
|
+
blendMode?: 'multiply';
|
|
677
686
|
}
|
|
678
687
|
declare class PencilTool implements Tool {
|
|
679
|
-
readonly name
|
|
688
|
+
readonly name: string;
|
|
680
689
|
private drawing;
|
|
681
690
|
private points;
|
|
682
691
|
private color;
|
|
@@ -685,6 +694,8 @@ declare class PencilTool implements Tool {
|
|
|
685
694
|
private minPointDistance;
|
|
686
695
|
private progressiveThreshold;
|
|
687
696
|
private nextSimplifyAt;
|
|
697
|
+
private opacity;
|
|
698
|
+
private blendMode;
|
|
688
699
|
private optionListeners;
|
|
689
700
|
constructor(options?: PencilToolOptions);
|
|
690
701
|
onActivate(ctx: ToolContext): void;
|
|
@@ -960,6 +971,6 @@ declare class TemplateTool implements Tool {
|
|
|
960
971
|
private notifyOptionsChange;
|
|
961
972
|
}
|
|
962
973
|
|
|
963
|
-
declare const VERSION = "0.
|
|
974
|
+
declare const VERSION = "0.30.0";
|
|
964
975
|
|
|
965
976
|
export { type ActiveFormats, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportImageOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, type Layer, LayerManager, MeasureTool, type MeasureToolOptions, type Measurement, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, type RenderStatsSnapshot, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInSquare, getHexDistance, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ interface StrokeElement extends BaseElement {
|
|
|
27
27
|
color: string;
|
|
28
28
|
width: number;
|
|
29
29
|
opacity: number;
|
|
30
|
+
/** Optional canvas blend mode (e.g. highlighter uses 'multiply'). */
|
|
31
|
+
blendMode?: 'multiply';
|
|
30
32
|
}
|
|
31
33
|
interface NoteElement extends BaseElement {
|
|
32
34
|
type: 'note';
|
|
@@ -72,7 +74,7 @@ interface TextElement extends BaseElement {
|
|
|
72
74
|
color: string;
|
|
73
75
|
textAlign: 'left' | 'center' | 'right';
|
|
74
76
|
}
|
|
75
|
-
type ShapeKind = 'rectangle' | 'ellipse';
|
|
77
|
+
type ShapeKind = 'rectangle' | 'ellipse' | 'line';
|
|
76
78
|
interface ShapeElement extends BaseElement {
|
|
77
79
|
type: 'shape';
|
|
78
80
|
shape: ShapeKind;
|
|
@@ -80,6 +82,8 @@ interface ShapeElement extends BaseElement {
|
|
|
80
82
|
strokeColor: string;
|
|
81
83
|
strokeWidth: number;
|
|
82
84
|
fillColor: string;
|
|
85
|
+
/** Line-only: which bbox diagonal the segment runs along. Absent/false = main diagonal. */
|
|
86
|
+
flip?: boolean;
|
|
83
87
|
}
|
|
84
88
|
type HexOrientation = 'pointy' | 'flat';
|
|
85
89
|
interface GridElement extends BaseElement {
|
|
@@ -562,6 +566,7 @@ interface StrokeInput extends BaseDefaults {
|
|
|
562
566
|
color?: string;
|
|
563
567
|
width?: number;
|
|
564
568
|
opacity?: number;
|
|
569
|
+
blendMode?: 'multiply';
|
|
565
570
|
}
|
|
566
571
|
interface NoteInput extends BaseDefaults {
|
|
567
572
|
position: Point;
|
|
@@ -612,6 +617,7 @@ interface ShapeInput extends BaseDefaults {
|
|
|
612
617
|
strokeColor?: string;
|
|
613
618
|
strokeWidth?: number;
|
|
614
619
|
fillColor?: string;
|
|
620
|
+
flip?: boolean;
|
|
615
621
|
}
|
|
616
622
|
declare function createShape(input: ShapeInput): ShapeElement;
|
|
617
623
|
interface GridInput extends BaseDefaults {
|
|
@@ -669,14 +675,17 @@ declare class HandTool implements Tool {
|
|
|
669
675
|
}
|
|
670
676
|
|
|
671
677
|
interface PencilToolOptions {
|
|
678
|
+
name?: string;
|
|
672
679
|
color?: string;
|
|
673
680
|
width?: number;
|
|
674
681
|
smoothing?: number;
|
|
675
682
|
minPointDistance?: number;
|
|
676
683
|
progressiveSimplifyThreshold?: number;
|
|
684
|
+
opacity?: number;
|
|
685
|
+
blendMode?: 'multiply';
|
|
677
686
|
}
|
|
678
687
|
declare class PencilTool implements Tool {
|
|
679
|
-
readonly name
|
|
688
|
+
readonly name: string;
|
|
680
689
|
private drawing;
|
|
681
690
|
private points;
|
|
682
691
|
private color;
|
|
@@ -685,6 +694,8 @@ declare class PencilTool implements Tool {
|
|
|
685
694
|
private minPointDistance;
|
|
686
695
|
private progressiveThreshold;
|
|
687
696
|
private nextSimplifyAt;
|
|
697
|
+
private opacity;
|
|
698
|
+
private blendMode;
|
|
688
699
|
private optionListeners;
|
|
689
700
|
constructor(options?: PencilToolOptions);
|
|
690
701
|
onActivate(ctx: ToolContext): void;
|
|
@@ -960,6 +971,6 @@ declare class TemplateTool implements Tool {
|
|
|
960
971
|
private notifyOptionsChange;
|
|
961
972
|
}
|
|
962
973
|
|
|
963
|
-
declare const VERSION = "0.
|
|
974
|
+
declare const VERSION = "0.30.0";
|
|
964
975
|
|
|
965
976
|
export { type ActiveFormats, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportImageOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, type Layer, LayerManager, MeasureTool, type MeasureToolOptions, type Measurement, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, type RenderStatsSnapshot, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInSquare, getHexDistance, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
|
package/dist/index.js
CHANGED
|
@@ -2195,6 +2195,19 @@ function getArrowRenderGeometry(arrow) {
|
|
|
2195
2195
|
return geometry;
|
|
2196
2196
|
}
|
|
2197
2197
|
|
|
2198
|
+
// src/elements/shape-geometry.ts
|
|
2199
|
+
function lineEndpoints(shape) {
|
|
2200
|
+
const { x, y } = shape.position;
|
|
2201
|
+
const { w, h } = shape.size;
|
|
2202
|
+
return shape.flip ? [
|
|
2203
|
+
{ x, y: y + h },
|
|
2204
|
+
{ x: x + w, y }
|
|
2205
|
+
] : [
|
|
2206
|
+
{ x, y },
|
|
2207
|
+
{ x: x + w, y: y + h }
|
|
2208
|
+
];
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2198
2211
|
// src/elements/arrow-binding.ts
|
|
2199
2212
|
var BINDABLE_TYPES = /* @__PURE__ */ new Set(["note", "text", "image", "html", "shape"]);
|
|
2200
2213
|
function isBindable(element) {
|
|
@@ -2719,6 +2732,7 @@ var ElementRenderer = class {
|
|
|
2719
2732
|
renderStroke(ctx, stroke) {
|
|
2720
2733
|
if (stroke.points.length < 2) return;
|
|
2721
2734
|
ctx.save();
|
|
2735
|
+
if (stroke.blendMode) ctx.globalCompositeOperation = stroke.blendMode;
|
|
2722
2736
|
ctx.translate(stroke.position.x, stroke.position.y);
|
|
2723
2737
|
ctx.strokeStyle = stroke.color;
|
|
2724
2738
|
ctx.lineCap = "round";
|
|
@@ -2841,7 +2855,7 @@ var ElementRenderer = class {
|
|
|
2841
2855
|
}
|
|
2842
2856
|
renderShape(ctx, shape) {
|
|
2843
2857
|
ctx.save();
|
|
2844
|
-
if (shape.fillColor !== "none") {
|
|
2858
|
+
if (shape.fillColor !== "none" && shape.shape !== "line") {
|
|
2845
2859
|
ctx.fillStyle = shape.fillColor;
|
|
2846
2860
|
this.fillShapePath(ctx, shape);
|
|
2847
2861
|
}
|
|
@@ -2880,6 +2894,15 @@ var ElementRenderer = class {
|
|
|
2880
2894
|
ctx.stroke();
|
|
2881
2895
|
break;
|
|
2882
2896
|
}
|
|
2897
|
+
case "line": {
|
|
2898
|
+
const [a, b] = lineEndpoints(shape);
|
|
2899
|
+
ctx.lineCap = "round";
|
|
2900
|
+
ctx.beginPath();
|
|
2901
|
+
ctx.moveTo(a.x, a.y);
|
|
2902
|
+
ctx.lineTo(b.x, b.y);
|
|
2903
|
+
ctx.stroke();
|
|
2904
|
+
break;
|
|
2905
|
+
}
|
|
2883
2906
|
}
|
|
2884
2907
|
}
|
|
2885
2908
|
renderGrid(ctx, grid) {
|
|
@@ -3153,7 +3176,7 @@ var ElementRenderer = class {
|
|
|
3153
3176
|
// src/elements/element-factory.ts
|
|
3154
3177
|
var DEFAULT_NOTE_FONT_SIZE = 18;
|
|
3155
3178
|
function createStroke(input) {
|
|
3156
|
-
|
|
3179
|
+
const result = {
|
|
3157
3180
|
id: createId("stroke"),
|
|
3158
3181
|
type: "stroke",
|
|
3159
3182
|
position: input.position ?? { x: 0, y: 0 },
|
|
@@ -3165,6 +3188,8 @@ function createStroke(input) {
|
|
|
3165
3188
|
width: input.width ?? 2,
|
|
3166
3189
|
opacity: input.opacity ?? 1
|
|
3167
3190
|
};
|
|
3191
|
+
if (input.blendMode) result.blendMode = input.blendMode;
|
|
3192
|
+
return result;
|
|
3168
3193
|
}
|
|
3169
3194
|
function createNote(input) {
|
|
3170
3195
|
return {
|
|
@@ -3229,7 +3254,7 @@ function createHtmlElement(input) {
|
|
|
3229
3254
|
return el;
|
|
3230
3255
|
}
|
|
3231
3256
|
function createShape(input) {
|
|
3232
|
-
|
|
3257
|
+
const result = {
|
|
3233
3258
|
id: createId("shape"),
|
|
3234
3259
|
type: "shape",
|
|
3235
3260
|
position: input.position,
|
|
@@ -3242,6 +3267,8 @@ function createShape(input) {
|
|
|
3242
3267
|
strokeWidth: input.strokeWidth ?? 2,
|
|
3243
3268
|
fillColor: input.fillColor ?? "none"
|
|
3244
3269
|
};
|
|
3270
|
+
if (input.flip) result.flip = input.flip;
|
|
3271
|
+
return result;
|
|
3245
3272
|
}
|
|
3246
3273
|
function createGrid(input) {
|
|
3247
3274
|
return {
|
|
@@ -6072,7 +6099,7 @@ var DEFAULT_MIN_POINT_DISTANCE = 3;
|
|
|
6072
6099
|
var DEFAULT_PROGRESSIVE_THRESHOLD = 200;
|
|
6073
6100
|
var PROGRESSIVE_HOT_ZONE = 30;
|
|
6074
6101
|
var PencilTool = class {
|
|
6075
|
-
name
|
|
6102
|
+
name;
|
|
6076
6103
|
drawing = false;
|
|
6077
6104
|
points = [];
|
|
6078
6105
|
color;
|
|
@@ -6081,14 +6108,19 @@ var PencilTool = class {
|
|
|
6081
6108
|
minPointDistance;
|
|
6082
6109
|
progressiveThreshold;
|
|
6083
6110
|
nextSimplifyAt;
|
|
6111
|
+
opacity;
|
|
6112
|
+
blendMode;
|
|
6084
6113
|
optionListeners = /* @__PURE__ */ new Set();
|
|
6085
6114
|
constructor(options = {}) {
|
|
6115
|
+
this.name = options.name ?? "pencil";
|
|
6086
6116
|
this.color = options.color ?? "#000000";
|
|
6087
6117
|
this.width = options.width ?? 2;
|
|
6088
6118
|
this.smoothing = options.smoothing ?? DEFAULT_SMOOTHING;
|
|
6089
6119
|
this.minPointDistance = options.minPointDistance ?? DEFAULT_MIN_POINT_DISTANCE;
|
|
6090
6120
|
this.progressiveThreshold = options.progressiveSimplifyThreshold ?? DEFAULT_PROGRESSIVE_THRESHOLD;
|
|
6091
6121
|
this.nextSimplifyAt = this.progressiveThreshold;
|
|
6122
|
+
this.opacity = options.opacity ?? 1;
|
|
6123
|
+
this.blendMode = options.blendMode;
|
|
6092
6124
|
}
|
|
6093
6125
|
onActivate(ctx) {
|
|
6094
6126
|
ctx.setCursor?.("crosshair");
|
|
@@ -6102,7 +6134,9 @@ var PencilTool = class {
|
|
|
6102
6134
|
width: this.width,
|
|
6103
6135
|
smoothing: this.smoothing,
|
|
6104
6136
|
minPointDistance: this.minPointDistance,
|
|
6105
|
-
progressiveSimplifyThreshold: this.progressiveThreshold
|
|
6137
|
+
progressiveSimplifyThreshold: this.progressiveThreshold,
|
|
6138
|
+
opacity: this.opacity,
|
|
6139
|
+
blendMode: this.blendMode
|
|
6106
6140
|
};
|
|
6107
6141
|
}
|
|
6108
6142
|
onOptionsChange(listener) {
|
|
@@ -6116,6 +6150,8 @@ var PencilTool = class {
|
|
|
6116
6150
|
if (options.minPointDistance !== void 0) this.minPointDistance = options.minPointDistance;
|
|
6117
6151
|
if (options.progressiveSimplifyThreshold !== void 0)
|
|
6118
6152
|
this.progressiveThreshold = options.progressiveSimplifyThreshold;
|
|
6153
|
+
if (options.opacity !== void 0) this.opacity = options.opacity;
|
|
6154
|
+
if (options.blendMode !== void 0) this.blendMode = options.blendMode;
|
|
6119
6155
|
this.notifyOptionsChange();
|
|
6120
6156
|
}
|
|
6121
6157
|
onPointerDown(state, ctx) {
|
|
@@ -6157,7 +6193,9 @@ var PencilTool = class {
|
|
|
6157
6193
|
points: simplified,
|
|
6158
6194
|
color: this.color,
|
|
6159
6195
|
width: this.width,
|
|
6160
|
-
layerId: ctx.activeLayerId ?? ""
|
|
6196
|
+
layerId: ctx.activeLayerId ?? "",
|
|
6197
|
+
opacity: this.opacity,
|
|
6198
|
+
blendMode: this.blendMode
|
|
6161
6199
|
});
|
|
6162
6200
|
ctx.store.add(stroke);
|
|
6163
6201
|
computeStrokeSegments(stroke);
|
|
@@ -6173,7 +6211,8 @@ var PencilTool = class {
|
|
|
6173
6211
|
ctx.strokeStyle = this.color;
|
|
6174
6212
|
ctx.lineCap = "round";
|
|
6175
6213
|
ctx.lineJoin = "round";
|
|
6176
|
-
ctx.globalAlpha = 0.8;
|
|
6214
|
+
ctx.globalAlpha = this.blendMode ? this.opacity : 0.8;
|
|
6215
|
+
if (this.blendMode) ctx.globalCompositeOperation = this.blendMode;
|
|
6177
6216
|
const segments = smoothToSegments(this.points);
|
|
6178
6217
|
for (const seg of segments) {
|
|
6179
6218
|
const w = (pressureToWidth(seg.start.pressure, this.width) + pressureToWidth(seg.end.pressure, this.width)) / 2;
|
|
@@ -7063,6 +7102,11 @@ var SelectTool = class {
|
|
|
7063
7102
|
}
|
|
7064
7103
|
isInsideBounds(point, el) {
|
|
7065
7104
|
if (el.type === "grid") return false;
|
|
7105
|
+
if (el.type === "shape" && el.shape === "line") {
|
|
7106
|
+
const [a, b] = lineEndpoints(el);
|
|
7107
|
+
const threshold = Math.max(el.strokeWidth / 2, 6);
|
|
7108
|
+
return distSqToSegment(point, a, b) <= threshold * threshold;
|
|
7109
|
+
}
|
|
7066
7110
|
if ("size" in el) {
|
|
7067
7111
|
const s = el.size;
|
|
7068
7112
|
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;
|
|
@@ -7376,6 +7420,15 @@ var ImageTool = class {
|
|
|
7376
7420
|
};
|
|
7377
7421
|
|
|
7378
7422
|
// src/tools/shape-tool.ts
|
|
7423
|
+
function snapTo45(start, end) {
|
|
7424
|
+
const dx = end.x - start.x;
|
|
7425
|
+
const dy = end.y - start.y;
|
|
7426
|
+
const len = Math.hypot(dx, dy);
|
|
7427
|
+
if (len === 0) return { ...end };
|
|
7428
|
+
const step = Math.PI / 4;
|
|
7429
|
+
const angle = Math.round(Math.atan2(dy, dx) / step) * step;
|
|
7430
|
+
return { x: start.x + Math.cos(angle) * len, y: start.y + Math.sin(angle) * len };
|
|
7431
|
+
}
|
|
7379
7432
|
var ShapeTool = class {
|
|
7380
7433
|
name = "shape";
|
|
7381
7434
|
drawing = false;
|
|
@@ -7433,13 +7486,17 @@ var ShapeTool = class {
|
|
|
7433
7486
|
onPointerMove(state, ctx) {
|
|
7434
7487
|
if (!this.drawing) return;
|
|
7435
7488
|
this.end = this.snap(ctx.camera.screenToWorld({ x: state.x, y: state.y }), ctx);
|
|
7489
|
+
if (this.shape === "line" && this.shiftHeld) {
|
|
7490
|
+
this.end = snapTo45(this.start, this.end);
|
|
7491
|
+
}
|
|
7436
7492
|
ctx.requestRender();
|
|
7437
7493
|
}
|
|
7438
7494
|
onPointerUp(_state, ctx) {
|
|
7439
7495
|
if (!this.drawing) return;
|
|
7440
7496
|
this.drawing = false;
|
|
7441
7497
|
const { position, size } = this.computeRect();
|
|
7442
|
-
|
|
7498
|
+
const isLine = this.shape === "line";
|
|
7499
|
+
if (isLine ? size.w === 0 && size.h === 0 : size.w === 0 || size.h === 0) return;
|
|
7443
7500
|
const shape = createShape({
|
|
7444
7501
|
position,
|
|
7445
7502
|
size,
|
|
@@ -7447,6 +7504,7 @@ var ShapeTool = class {
|
|
|
7447
7504
|
strokeColor: this.strokeColor,
|
|
7448
7505
|
strokeWidth: this.strokeWidth,
|
|
7449
7506
|
fillColor: this.fillColor,
|
|
7507
|
+
...isLine ? { flip: this.end.x > this.start.x !== this.end.y > this.start.y } : {},
|
|
7450
7508
|
layerId: ctx.activeLayerId ?? ""
|
|
7451
7509
|
});
|
|
7452
7510
|
ctx.store.add(shape);
|
|
@@ -7480,6 +7538,13 @@ var ShapeTool = class {
|
|
|
7480
7538
|
ctx.stroke();
|
|
7481
7539
|
break;
|
|
7482
7540
|
}
|
|
7541
|
+
case "line":
|
|
7542
|
+
ctx.lineCap = "round";
|
|
7543
|
+
ctx.beginPath();
|
|
7544
|
+
ctx.moveTo(this.start.x, this.start.y);
|
|
7545
|
+
ctx.lineTo(this.end.x, this.end.y);
|
|
7546
|
+
ctx.stroke();
|
|
7547
|
+
break;
|
|
7483
7548
|
}
|
|
7484
7549
|
ctx.restore();
|
|
7485
7550
|
}
|
|
@@ -7488,7 +7553,7 @@ var ShapeTool = class {
|
|
|
7488
7553
|
let y = Math.min(this.start.y, this.end.y);
|
|
7489
7554
|
let w = Math.abs(this.end.x - this.start.x);
|
|
7490
7555
|
let h = Math.abs(this.end.y - this.start.y);
|
|
7491
|
-
if (this.shiftHeld) {
|
|
7556
|
+
if (this.shiftHeld && this.shape !== "line") {
|
|
7492
7557
|
const side = Math.max(w, h);
|
|
7493
7558
|
w = side;
|
|
7494
7559
|
h = side;
|
|
@@ -7904,7 +7969,7 @@ var TemplateTool = class {
|
|
|
7904
7969
|
};
|
|
7905
7970
|
|
|
7906
7971
|
// src/index.ts
|
|
7907
|
-
var VERSION = "0.
|
|
7972
|
+
var VERSION = "0.30.0";
|
|
7908
7973
|
export {
|
|
7909
7974
|
ArrowTool,
|
|
7910
7975
|
AutoSave,
|