@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.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,9 @@ function migrateElement(obj) {
|
|
|
185
187
|
}
|
|
186
188
|
}
|
|
187
189
|
}
|
|
190
|
+
if (obj["type"] === "shape" && typeof obj["shape"] !== "string") {
|
|
191
|
+
obj["shape"] = "rectangle";
|
|
192
|
+
}
|
|
188
193
|
}
|
|
189
194
|
|
|
190
195
|
// src/core/auto-save.ts
|
|
@@ -768,7 +773,7 @@ function isNearLine(point, a, b, threshold) {
|
|
|
768
773
|
}
|
|
769
774
|
|
|
770
775
|
// src/elements/arrow-binding.ts
|
|
771
|
-
var BINDABLE_TYPES = /* @__PURE__ */ new Set(["note", "text", "image", "html"]);
|
|
776
|
+
var BINDABLE_TYPES = /* @__PURE__ */ new Set(["note", "text", "image", "html", "shape"]);
|
|
772
777
|
function isBindable(element) {
|
|
773
778
|
return BINDABLE_TYPES.has(element.type);
|
|
774
779
|
}
|
|
@@ -988,6 +993,9 @@ var ElementRenderer = class {
|
|
|
988
993
|
case "arrow":
|
|
989
994
|
this.renderArrow(ctx, element);
|
|
990
995
|
break;
|
|
996
|
+
case "shape":
|
|
997
|
+
this.renderShape(ctx, element);
|
|
998
|
+
break;
|
|
991
999
|
}
|
|
992
1000
|
}
|
|
993
1001
|
renderStroke(ctx, stroke) {
|
|
@@ -1080,6 +1088,49 @@ var ElementRenderer = class {
|
|
|
1080
1088
|
}
|
|
1081
1089
|
return { visualFrom, visualTo };
|
|
1082
1090
|
}
|
|
1091
|
+
renderShape(ctx, shape) {
|
|
1092
|
+
ctx.save();
|
|
1093
|
+
if (shape.fillColor !== "none") {
|
|
1094
|
+
ctx.fillStyle = shape.fillColor;
|
|
1095
|
+
this.fillShapePath(ctx, shape);
|
|
1096
|
+
}
|
|
1097
|
+
if (shape.strokeWidth > 0) {
|
|
1098
|
+
ctx.strokeStyle = shape.strokeColor;
|
|
1099
|
+
ctx.lineWidth = shape.strokeWidth;
|
|
1100
|
+
this.strokeShapePath(ctx, shape);
|
|
1101
|
+
}
|
|
1102
|
+
ctx.restore();
|
|
1103
|
+
}
|
|
1104
|
+
fillShapePath(ctx, shape) {
|
|
1105
|
+
switch (shape.shape) {
|
|
1106
|
+
case "rectangle":
|
|
1107
|
+
ctx.fillRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);
|
|
1108
|
+
break;
|
|
1109
|
+
case "ellipse": {
|
|
1110
|
+
const cx = shape.position.x + shape.size.w / 2;
|
|
1111
|
+
const cy = shape.position.y + shape.size.h / 2;
|
|
1112
|
+
ctx.beginPath();
|
|
1113
|
+
ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);
|
|
1114
|
+
ctx.fill();
|
|
1115
|
+
break;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
strokeShapePath(ctx, shape) {
|
|
1120
|
+
switch (shape.shape) {
|
|
1121
|
+
case "rectangle":
|
|
1122
|
+
ctx.strokeRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);
|
|
1123
|
+
break;
|
|
1124
|
+
case "ellipse": {
|
|
1125
|
+
const cx = shape.position.x + shape.size.w / 2;
|
|
1126
|
+
const cy = shape.position.y + shape.size.h / 2;
|
|
1127
|
+
ctx.beginPath();
|
|
1128
|
+
ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);
|
|
1129
|
+
ctx.stroke();
|
|
1130
|
+
break;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1083
1134
|
};
|
|
1084
1135
|
|
|
1085
1136
|
// src/elements/note-editor.ts
|
|
@@ -1487,6 +1538,20 @@ function createHtmlElement(input) {
|
|
|
1487
1538
|
size: input.size
|
|
1488
1539
|
};
|
|
1489
1540
|
}
|
|
1541
|
+
function createShape(input) {
|
|
1542
|
+
return {
|
|
1543
|
+
id: createId("shape"),
|
|
1544
|
+
type: "shape",
|
|
1545
|
+
position: input.position,
|
|
1546
|
+
zIndex: input.zIndex ?? 0,
|
|
1547
|
+
locked: input.locked ?? false,
|
|
1548
|
+
shape: input.shape ?? "rectangle",
|
|
1549
|
+
size: input.size,
|
|
1550
|
+
strokeColor: input.strokeColor ?? "#000000",
|
|
1551
|
+
strokeWidth: input.strokeWidth ?? 2,
|
|
1552
|
+
fillColor: input.fillColor ?? "none"
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1490
1555
|
function createText(input) {
|
|
1491
1556
|
return {
|
|
1492
1557
|
id: createId("text"),
|
|
@@ -2928,8 +2993,123 @@ var ImageTool = class {
|
|
|
2928
2993
|
}
|
|
2929
2994
|
};
|
|
2930
2995
|
|
|
2996
|
+
// src/tools/shape-tool.ts
|
|
2997
|
+
var ShapeTool = class {
|
|
2998
|
+
name = "shape";
|
|
2999
|
+
drawing = false;
|
|
3000
|
+
start = { x: 0, y: 0 };
|
|
3001
|
+
end = { x: 0, y: 0 };
|
|
3002
|
+
shiftHeld = false;
|
|
3003
|
+
shape;
|
|
3004
|
+
strokeColor;
|
|
3005
|
+
strokeWidth;
|
|
3006
|
+
fillColor;
|
|
3007
|
+
constructor(options = {}) {
|
|
3008
|
+
this.shape = options.shape ?? "rectangle";
|
|
3009
|
+
this.strokeColor = options.strokeColor ?? "#000000";
|
|
3010
|
+
this.strokeWidth = options.strokeWidth ?? 2;
|
|
3011
|
+
this.fillColor = options.fillColor ?? "none";
|
|
3012
|
+
}
|
|
3013
|
+
setOptions(options) {
|
|
3014
|
+
if (options.shape !== void 0) this.shape = options.shape;
|
|
3015
|
+
if (options.strokeColor !== void 0) this.strokeColor = options.strokeColor;
|
|
3016
|
+
if (options.strokeWidth !== void 0) this.strokeWidth = options.strokeWidth;
|
|
3017
|
+
if (options.fillColor !== void 0) this.fillColor = options.fillColor;
|
|
3018
|
+
}
|
|
3019
|
+
onActivate(_ctx) {
|
|
3020
|
+
if (typeof window !== "undefined") {
|
|
3021
|
+
window.addEventListener("keydown", this.onKeyDown);
|
|
3022
|
+
window.addEventListener("keyup", this.onKeyUp);
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
onDeactivate(_ctx) {
|
|
3026
|
+
this.shiftHeld = false;
|
|
3027
|
+
if (typeof window !== "undefined") {
|
|
3028
|
+
window.removeEventListener("keydown", this.onKeyDown);
|
|
3029
|
+
window.removeEventListener("keyup", this.onKeyUp);
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
onPointerDown(state, ctx) {
|
|
3033
|
+
this.drawing = true;
|
|
3034
|
+
this.start = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
3035
|
+
this.end = { ...this.start };
|
|
3036
|
+
}
|
|
3037
|
+
onPointerMove(state, ctx) {
|
|
3038
|
+
if (!this.drawing) return;
|
|
3039
|
+
this.end = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
3040
|
+
ctx.requestRender();
|
|
3041
|
+
}
|
|
3042
|
+
onPointerUp(_state, ctx) {
|
|
3043
|
+
if (!this.drawing) return;
|
|
3044
|
+
this.drawing = false;
|
|
3045
|
+
const { position, size } = this.computeRect();
|
|
3046
|
+
if (size.w === 0 || size.h === 0) return;
|
|
3047
|
+
const shape = createShape({
|
|
3048
|
+
position,
|
|
3049
|
+
size,
|
|
3050
|
+
shape: this.shape,
|
|
3051
|
+
strokeColor: this.strokeColor,
|
|
3052
|
+
strokeWidth: this.strokeWidth,
|
|
3053
|
+
fillColor: this.fillColor
|
|
3054
|
+
});
|
|
3055
|
+
ctx.store.add(shape);
|
|
3056
|
+
ctx.requestRender();
|
|
3057
|
+
ctx.switchTool?.("select");
|
|
3058
|
+
}
|
|
3059
|
+
renderOverlay(ctx) {
|
|
3060
|
+
if (!this.drawing) return;
|
|
3061
|
+
const { position, size } = this.computeRect();
|
|
3062
|
+
if (size.w === 0 && size.h === 0) return;
|
|
3063
|
+
ctx.save();
|
|
3064
|
+
ctx.globalAlpha = 0.5;
|
|
3065
|
+
ctx.strokeStyle = this.strokeColor;
|
|
3066
|
+
ctx.lineWidth = this.strokeWidth;
|
|
3067
|
+
if (this.fillColor !== "none") {
|
|
3068
|
+
ctx.fillStyle = this.fillColor;
|
|
3069
|
+
}
|
|
3070
|
+
switch (this.shape) {
|
|
3071
|
+
case "rectangle":
|
|
3072
|
+
if (this.fillColor !== "none") {
|
|
3073
|
+
ctx.fillRect(position.x, position.y, size.w, size.h);
|
|
3074
|
+
}
|
|
3075
|
+
ctx.strokeRect(position.x, position.y, size.w, size.h);
|
|
3076
|
+
break;
|
|
3077
|
+
case "ellipse": {
|
|
3078
|
+
const cx = position.x + size.w / 2;
|
|
3079
|
+
const cy = position.y + size.h / 2;
|
|
3080
|
+
ctx.beginPath();
|
|
3081
|
+
ctx.ellipse(cx, cy, size.w / 2, size.h / 2, 0, 0, Math.PI * 2);
|
|
3082
|
+
if (this.fillColor !== "none") ctx.fill();
|
|
3083
|
+
ctx.stroke();
|
|
3084
|
+
break;
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
ctx.restore();
|
|
3088
|
+
}
|
|
3089
|
+
computeRect() {
|
|
3090
|
+
let x = Math.min(this.start.x, this.end.x);
|
|
3091
|
+
let y = Math.min(this.start.y, this.end.y);
|
|
3092
|
+
let w = Math.abs(this.end.x - this.start.x);
|
|
3093
|
+
let h = Math.abs(this.end.y - this.start.y);
|
|
3094
|
+
if (this.shiftHeld) {
|
|
3095
|
+
const side = Math.max(w, h);
|
|
3096
|
+
w = side;
|
|
3097
|
+
h = side;
|
|
3098
|
+
x = this.end.x >= this.start.x ? this.start.x : this.start.x - side;
|
|
3099
|
+
y = this.end.y >= this.start.y ? this.start.y : this.start.y - side;
|
|
3100
|
+
}
|
|
3101
|
+
return { position: { x, y }, size: { w, h } };
|
|
3102
|
+
}
|
|
3103
|
+
onKeyDown = (e) => {
|
|
3104
|
+
if (e.key === "Shift") this.shiftHeld = true;
|
|
3105
|
+
};
|
|
3106
|
+
onKeyUp = (e) => {
|
|
3107
|
+
if (e.key === "Shift") this.shiftHeld = false;
|
|
3108
|
+
};
|
|
3109
|
+
};
|
|
3110
|
+
|
|
2931
3111
|
// src/index.ts
|
|
2932
|
-
var VERSION = "0.
|
|
3112
|
+
var VERSION = "0.4.0";
|
|
2933
3113
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2934
3114
|
0 && (module.exports = {
|
|
2935
3115
|
AddElementCommand,
|
|
@@ -2952,6 +3132,7 @@ var VERSION = "0.3.1";
|
|
|
2952
3132
|
PencilTool,
|
|
2953
3133
|
RemoveElementCommand,
|
|
2954
3134
|
SelectTool,
|
|
3135
|
+
ShapeTool,
|
|
2955
3136
|
TextTool,
|
|
2956
3137
|
ToolManager,
|
|
2957
3138
|
UpdateElementCommand,
|
|
@@ -2963,6 +3144,7 @@ var VERSION = "0.3.1";
|
|
|
2963
3144
|
createId,
|
|
2964
3145
|
createImage,
|
|
2965
3146
|
createNote,
|
|
3147
|
+
createShape,
|
|
2966
3148
|
createStroke,
|
|
2967
3149
|
createText,
|
|
2968
3150
|
exportState,
|