@fieldnotes/core 0.3.1 → 0.4.1
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 +197 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -4
- package/dist/index.d.ts +58 -4
- package/dist/index.js +195 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -40,6 +40,7 @@ __export(index_exports, {
|
|
|
40
40
|
PencilTool: () => PencilTool,
|
|
41
41
|
RemoveElementCommand: () => RemoveElementCommand,
|
|
42
42
|
SelectTool: () => SelectTool,
|
|
43
|
+
ShapeTool: () => ShapeTool,
|
|
43
44
|
TextTool: () => TextTool,
|
|
44
45
|
ToolManager: () => ToolManager,
|
|
45
46
|
UpdateElementCommand: () => UpdateElementCommand,
|
|
@@ -51,6 +52,7 @@ __export(index_exports, {
|
|
|
51
52
|
createId: () => createId,
|
|
52
53
|
createImage: () => createImage,
|
|
53
54
|
createNote: () => createNote,
|
|
55
|
+
createShape: () => createShape,
|
|
54
56
|
createStroke: () => createStroke,
|
|
55
57
|
createText: () => createText,
|
|
56
58
|
exportState: () => exportState,
|
|
@@ -144,7 +146,7 @@ function validateState(data) {
|
|
|
144
146
|
}
|
|
145
147
|
cleanBindings(obj["elements"]);
|
|
146
148
|
}
|
|
147
|
-
var VALID_TYPES = /* @__PURE__ */ new Set(["stroke", "note", "arrow", "image", "html", "text"]);
|
|
149
|
+
var VALID_TYPES = /* @__PURE__ */ new Set(["stroke", "note", "arrow", "image", "html", "text", "shape"]);
|
|
148
150
|
function validateElement(el) {
|
|
149
151
|
if (!el || typeof el !== "object") {
|
|
150
152
|
throw new Error("Invalid element: expected an object");
|
|
@@ -185,6 +187,12 @@ function migrateElement(obj) {
|
|
|
185
187
|
}
|
|
186
188
|
}
|
|
187
189
|
}
|
|
190
|
+
if (obj["type"] === "shape" && typeof obj["shape"] !== "string") {
|
|
191
|
+
obj["shape"] = "rectangle";
|
|
192
|
+
}
|
|
193
|
+
if (obj["type"] === "note" && typeof obj["textColor"] !== "string") {
|
|
194
|
+
obj["textColor"] = "#000000";
|
|
195
|
+
}
|
|
188
196
|
}
|
|
189
197
|
|
|
190
198
|
// src/core/auto-save.ts
|
|
@@ -768,7 +776,7 @@ function isNearLine(point, a, b, threshold) {
|
|
|
768
776
|
}
|
|
769
777
|
|
|
770
778
|
// src/elements/arrow-binding.ts
|
|
771
|
-
var BINDABLE_TYPES = /* @__PURE__ */ new Set(["note", "text", "image", "html"]);
|
|
779
|
+
var BINDABLE_TYPES = /* @__PURE__ */ new Set(["note", "text", "image", "html", "shape"]);
|
|
772
780
|
function isBindable(element) {
|
|
773
781
|
return BINDABLE_TYPES.has(element.type);
|
|
774
782
|
}
|
|
@@ -988,6 +996,9 @@ var ElementRenderer = class {
|
|
|
988
996
|
case "arrow":
|
|
989
997
|
this.renderArrow(ctx, element);
|
|
990
998
|
break;
|
|
999
|
+
case "shape":
|
|
1000
|
+
this.renderShape(ctx, element);
|
|
1001
|
+
break;
|
|
991
1002
|
}
|
|
992
1003
|
}
|
|
993
1004
|
renderStroke(ctx, stroke) {
|
|
@@ -1080,6 +1091,49 @@ var ElementRenderer = class {
|
|
|
1080
1091
|
}
|
|
1081
1092
|
return { visualFrom, visualTo };
|
|
1082
1093
|
}
|
|
1094
|
+
renderShape(ctx, shape) {
|
|
1095
|
+
ctx.save();
|
|
1096
|
+
if (shape.fillColor !== "none") {
|
|
1097
|
+
ctx.fillStyle = shape.fillColor;
|
|
1098
|
+
this.fillShapePath(ctx, shape);
|
|
1099
|
+
}
|
|
1100
|
+
if (shape.strokeWidth > 0) {
|
|
1101
|
+
ctx.strokeStyle = shape.strokeColor;
|
|
1102
|
+
ctx.lineWidth = shape.strokeWidth;
|
|
1103
|
+
this.strokeShapePath(ctx, shape);
|
|
1104
|
+
}
|
|
1105
|
+
ctx.restore();
|
|
1106
|
+
}
|
|
1107
|
+
fillShapePath(ctx, shape) {
|
|
1108
|
+
switch (shape.shape) {
|
|
1109
|
+
case "rectangle":
|
|
1110
|
+
ctx.fillRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);
|
|
1111
|
+
break;
|
|
1112
|
+
case "ellipse": {
|
|
1113
|
+
const cx = shape.position.x + shape.size.w / 2;
|
|
1114
|
+
const cy = shape.position.y + shape.size.h / 2;
|
|
1115
|
+
ctx.beginPath();
|
|
1116
|
+
ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);
|
|
1117
|
+
ctx.fill();
|
|
1118
|
+
break;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
strokeShapePath(ctx, shape) {
|
|
1123
|
+
switch (shape.shape) {
|
|
1124
|
+
case "rectangle":
|
|
1125
|
+
ctx.strokeRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);
|
|
1126
|
+
break;
|
|
1127
|
+
case "ellipse": {
|
|
1128
|
+
const cx = shape.position.x + shape.size.w / 2;
|
|
1129
|
+
const cy = shape.position.y + shape.size.h / 2;
|
|
1130
|
+
ctx.beginPath();
|
|
1131
|
+
ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);
|
|
1132
|
+
ctx.stroke();
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1083
1137
|
};
|
|
1084
1138
|
|
|
1085
1139
|
// src/elements/note-editor.ts
|
|
@@ -1446,7 +1500,8 @@ function createNote(input) {
|
|
|
1446
1500
|
locked: input.locked ?? false,
|
|
1447
1501
|
size: input.size ?? { w: 200, h: 100 },
|
|
1448
1502
|
text: input.text ?? "",
|
|
1449
|
-
backgroundColor: input.backgroundColor ?? "#ffeb3b"
|
|
1503
|
+
backgroundColor: input.backgroundColor ?? "#ffeb3b",
|
|
1504
|
+
textColor: input.textColor ?? "#000000"
|
|
1450
1505
|
};
|
|
1451
1506
|
}
|
|
1452
1507
|
function createArrow(input) {
|
|
@@ -1487,6 +1542,20 @@ function createHtmlElement(input) {
|
|
|
1487
1542
|
size: input.size
|
|
1488
1543
|
};
|
|
1489
1544
|
}
|
|
1545
|
+
function createShape(input) {
|
|
1546
|
+
return {
|
|
1547
|
+
id: createId("shape"),
|
|
1548
|
+
type: "shape",
|
|
1549
|
+
position: input.position,
|
|
1550
|
+
zIndex: input.zIndex ?? 0,
|
|
1551
|
+
locked: input.locked ?? false,
|
|
1552
|
+
shape: input.shape ?? "rectangle",
|
|
1553
|
+
size: input.size,
|
|
1554
|
+
strokeColor: input.strokeColor ?? "#000000",
|
|
1555
|
+
strokeWidth: input.strokeWidth ?? 2,
|
|
1556
|
+
fillColor: input.fillColor ?? "none"
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1490
1559
|
function createText(input) {
|
|
1491
1560
|
return {
|
|
1492
1561
|
id: createId("text"),
|
|
@@ -1831,6 +1900,7 @@ var Viewport = class {
|
|
|
1831
1900
|
node.dataset["initialized"] = "true";
|
|
1832
1901
|
Object.assign(node.style, {
|
|
1833
1902
|
backgroundColor: element.backgroundColor,
|
|
1903
|
+
color: element.textColor,
|
|
1834
1904
|
padding: "8px",
|
|
1835
1905
|
borderRadius: "4px",
|
|
1836
1906
|
boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
|
|
@@ -1852,6 +1922,7 @@ var Viewport = class {
|
|
|
1852
1922
|
node.textContent = element.text || "";
|
|
1853
1923
|
}
|
|
1854
1924
|
node.style.backgroundColor = element.backgroundColor;
|
|
1925
|
+
node.style.color = element.textColor;
|
|
1855
1926
|
}
|
|
1856
1927
|
}
|
|
1857
1928
|
if (element.type === "image") {
|
|
@@ -2830,13 +2901,16 @@ var ArrowTool = class {
|
|
|
2830
2901
|
var NoteTool = class {
|
|
2831
2902
|
name = "note";
|
|
2832
2903
|
backgroundColor;
|
|
2904
|
+
textColor;
|
|
2833
2905
|
size;
|
|
2834
2906
|
constructor(options = {}) {
|
|
2835
2907
|
this.backgroundColor = options.backgroundColor ?? "#ffeb3b";
|
|
2908
|
+
this.textColor = options.textColor ?? "#000000";
|
|
2836
2909
|
this.size = options.size ?? { w: 200, h: 100 };
|
|
2837
2910
|
}
|
|
2838
2911
|
setOptions(options) {
|
|
2839
2912
|
if (options.backgroundColor !== void 0) this.backgroundColor = options.backgroundColor;
|
|
2913
|
+
if (options.textColor !== void 0) this.textColor = options.textColor;
|
|
2840
2914
|
if (options.size !== void 0) this.size = options.size;
|
|
2841
2915
|
}
|
|
2842
2916
|
onPointerDown(_state, _ctx) {
|
|
@@ -2848,7 +2922,8 @@ var NoteTool = class {
|
|
|
2848
2922
|
const note = createNote({
|
|
2849
2923
|
position: world,
|
|
2850
2924
|
size: { ...this.size },
|
|
2851
|
-
backgroundColor: this.backgroundColor
|
|
2925
|
+
backgroundColor: this.backgroundColor,
|
|
2926
|
+
textColor: this.textColor
|
|
2852
2927
|
});
|
|
2853
2928
|
ctx.store.add(note);
|
|
2854
2929
|
ctx.requestRender();
|
|
@@ -2928,8 +3003,123 @@ var ImageTool = class {
|
|
|
2928
3003
|
}
|
|
2929
3004
|
};
|
|
2930
3005
|
|
|
3006
|
+
// src/tools/shape-tool.ts
|
|
3007
|
+
var ShapeTool = class {
|
|
3008
|
+
name = "shape";
|
|
3009
|
+
drawing = false;
|
|
3010
|
+
start = { x: 0, y: 0 };
|
|
3011
|
+
end = { x: 0, y: 0 };
|
|
3012
|
+
shiftHeld = false;
|
|
3013
|
+
shape;
|
|
3014
|
+
strokeColor;
|
|
3015
|
+
strokeWidth;
|
|
3016
|
+
fillColor;
|
|
3017
|
+
constructor(options = {}) {
|
|
3018
|
+
this.shape = options.shape ?? "rectangle";
|
|
3019
|
+
this.strokeColor = options.strokeColor ?? "#000000";
|
|
3020
|
+
this.strokeWidth = options.strokeWidth ?? 2;
|
|
3021
|
+
this.fillColor = options.fillColor ?? "none";
|
|
3022
|
+
}
|
|
3023
|
+
setOptions(options) {
|
|
3024
|
+
if (options.shape !== void 0) this.shape = options.shape;
|
|
3025
|
+
if (options.strokeColor !== void 0) this.strokeColor = options.strokeColor;
|
|
3026
|
+
if (options.strokeWidth !== void 0) this.strokeWidth = options.strokeWidth;
|
|
3027
|
+
if (options.fillColor !== void 0) this.fillColor = options.fillColor;
|
|
3028
|
+
}
|
|
3029
|
+
onActivate(_ctx) {
|
|
3030
|
+
if (typeof window !== "undefined") {
|
|
3031
|
+
window.addEventListener("keydown", this.onKeyDown);
|
|
3032
|
+
window.addEventListener("keyup", this.onKeyUp);
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
3035
|
+
onDeactivate(_ctx) {
|
|
3036
|
+
this.shiftHeld = false;
|
|
3037
|
+
if (typeof window !== "undefined") {
|
|
3038
|
+
window.removeEventListener("keydown", this.onKeyDown);
|
|
3039
|
+
window.removeEventListener("keyup", this.onKeyUp);
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
onPointerDown(state, ctx) {
|
|
3043
|
+
this.drawing = true;
|
|
3044
|
+
this.start = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
3045
|
+
this.end = { ...this.start };
|
|
3046
|
+
}
|
|
3047
|
+
onPointerMove(state, ctx) {
|
|
3048
|
+
if (!this.drawing) return;
|
|
3049
|
+
this.end = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
3050
|
+
ctx.requestRender();
|
|
3051
|
+
}
|
|
3052
|
+
onPointerUp(_state, ctx) {
|
|
3053
|
+
if (!this.drawing) return;
|
|
3054
|
+
this.drawing = false;
|
|
3055
|
+
const { position, size } = this.computeRect();
|
|
3056
|
+
if (size.w === 0 || size.h === 0) return;
|
|
3057
|
+
const shape = createShape({
|
|
3058
|
+
position,
|
|
3059
|
+
size,
|
|
3060
|
+
shape: this.shape,
|
|
3061
|
+
strokeColor: this.strokeColor,
|
|
3062
|
+
strokeWidth: this.strokeWidth,
|
|
3063
|
+
fillColor: this.fillColor
|
|
3064
|
+
});
|
|
3065
|
+
ctx.store.add(shape);
|
|
3066
|
+
ctx.requestRender();
|
|
3067
|
+
ctx.switchTool?.("select");
|
|
3068
|
+
}
|
|
3069
|
+
renderOverlay(ctx) {
|
|
3070
|
+
if (!this.drawing) return;
|
|
3071
|
+
const { position, size } = this.computeRect();
|
|
3072
|
+
if (size.w === 0 && size.h === 0) return;
|
|
3073
|
+
ctx.save();
|
|
3074
|
+
ctx.globalAlpha = 0.5;
|
|
3075
|
+
ctx.strokeStyle = this.strokeColor;
|
|
3076
|
+
ctx.lineWidth = this.strokeWidth;
|
|
3077
|
+
if (this.fillColor !== "none") {
|
|
3078
|
+
ctx.fillStyle = this.fillColor;
|
|
3079
|
+
}
|
|
3080
|
+
switch (this.shape) {
|
|
3081
|
+
case "rectangle":
|
|
3082
|
+
if (this.fillColor !== "none") {
|
|
3083
|
+
ctx.fillRect(position.x, position.y, size.w, size.h);
|
|
3084
|
+
}
|
|
3085
|
+
ctx.strokeRect(position.x, position.y, size.w, size.h);
|
|
3086
|
+
break;
|
|
3087
|
+
case "ellipse": {
|
|
3088
|
+
const cx = position.x + size.w / 2;
|
|
3089
|
+
const cy = position.y + size.h / 2;
|
|
3090
|
+
ctx.beginPath();
|
|
3091
|
+
ctx.ellipse(cx, cy, size.w / 2, size.h / 2, 0, 0, Math.PI * 2);
|
|
3092
|
+
if (this.fillColor !== "none") ctx.fill();
|
|
3093
|
+
ctx.stroke();
|
|
3094
|
+
break;
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
ctx.restore();
|
|
3098
|
+
}
|
|
3099
|
+
computeRect() {
|
|
3100
|
+
let x = Math.min(this.start.x, this.end.x);
|
|
3101
|
+
let y = Math.min(this.start.y, this.end.y);
|
|
3102
|
+
let w = Math.abs(this.end.x - this.start.x);
|
|
3103
|
+
let h = Math.abs(this.end.y - this.start.y);
|
|
3104
|
+
if (this.shiftHeld) {
|
|
3105
|
+
const side = Math.max(w, h);
|
|
3106
|
+
w = side;
|
|
3107
|
+
h = side;
|
|
3108
|
+
x = this.end.x >= this.start.x ? this.start.x : this.start.x - side;
|
|
3109
|
+
y = this.end.y >= this.start.y ? this.start.y : this.start.y - side;
|
|
3110
|
+
}
|
|
3111
|
+
return { position: { x, y }, size: { w, h } };
|
|
3112
|
+
}
|
|
3113
|
+
onKeyDown = (e) => {
|
|
3114
|
+
if (e.key === "Shift") this.shiftHeld = true;
|
|
3115
|
+
};
|
|
3116
|
+
onKeyUp = (e) => {
|
|
3117
|
+
if (e.key === "Shift") this.shiftHeld = false;
|
|
3118
|
+
};
|
|
3119
|
+
};
|
|
3120
|
+
|
|
2931
3121
|
// src/index.ts
|
|
2932
|
-
var VERSION = "0.
|
|
3122
|
+
var VERSION = "0.4.1";
|
|
2933
3123
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2934
3124
|
0 && (module.exports = {
|
|
2935
3125
|
AddElementCommand,
|
|
@@ -2952,6 +3142,7 @@ var VERSION = "0.3.1";
|
|
|
2952
3142
|
PencilTool,
|
|
2953
3143
|
RemoveElementCommand,
|
|
2954
3144
|
SelectTool,
|
|
3145
|
+
ShapeTool,
|
|
2955
3146
|
TextTool,
|
|
2956
3147
|
ToolManager,
|
|
2957
3148
|
UpdateElementCommand,
|
|
@@ -2963,6 +3154,7 @@ var VERSION = "0.3.1";
|
|
|
2963
3154
|
createId,
|
|
2964
3155
|
createImage,
|
|
2965
3156
|
createNote,
|
|
3157
|
+
createShape,
|
|
2966
3158
|
createStroke,
|
|
2967
3159
|
createText,
|
|
2968
3160
|
exportState,
|