@pooder/kit 2.0.0 → 3.0.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/CHANGELOG.md +11 -0
- package/dist/index.d.mts +246 -134
- package/dist/index.d.ts +246 -134
- package/dist/index.js +2051 -1045
- package/dist/index.mjs +2042 -1050
- package/package.json +3 -2
- package/src/CanvasService.ts +65 -0
- package/src/background.ts +156 -109
- package/src/coordinate.ts +49 -0
- package/src/dieline.ts +536 -336
- package/src/film.ts +120 -89
- package/src/geometry.ts +251 -38
- package/src/hole.ts +422 -286
- package/src/image.ts +374 -174
- package/src/index.ts +1 -0
- package/src/mirror.ts +86 -49
- package/src/ruler.ts +188 -118
- package/src/tracer.ts +372 -0
- package/src/white-ink.ts +186 -142
package/src/mirror.ts
CHANGED
|
@@ -1,39 +1,99 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Extension,
|
|
3
|
+
ExtensionContext,
|
|
4
|
+
ContributionPointIds,
|
|
5
|
+
CommandContribution,
|
|
6
|
+
ConfigurationContribution,
|
|
7
|
+
} from "@pooder/core";
|
|
8
|
+
import CanvasService from "./CanvasService";
|
|
2
9
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
}
|
|
10
|
+
export class MirrorTool implements Extension {
|
|
11
|
+
id = "pooder.kit.mirror";
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
public options: MirrorToolOptions = {
|
|
10
|
-
enabled: false,
|
|
13
|
+
public metadata = {
|
|
14
|
+
name: "MirrorTool",
|
|
11
15
|
};
|
|
16
|
+
private enabled = false;
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
enabled: {
|
|
15
|
-
type: "boolean",
|
|
16
|
-
label: "Mirror View",
|
|
17
|
-
},
|
|
18
|
-
};
|
|
18
|
+
private canvasService?: CanvasService;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
constructor(
|
|
21
|
+
options?: Partial<{
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
}>,
|
|
24
|
+
) {
|
|
25
|
+
if (options) {
|
|
26
|
+
Object.assign(this, options);
|
|
23
27
|
}
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
toJSON() {
|
|
31
|
+
return {
|
|
32
|
+
enabled: this.enabled,
|
|
33
|
+
};
|
|
28
34
|
}
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
this.applyMirror(editor, false);
|
|
36
|
+
loadFromJSON(json: any) {
|
|
37
|
+
this.enabled = json.enabled;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
activate(context: ExtensionContext) {
|
|
41
|
+
this.canvasService = context.services.get<CanvasService>("CanvasService");
|
|
42
|
+
if (!this.canvasService) {
|
|
43
|
+
console.warn("CanvasService not found for MirrorTool");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const configService = context.services.get<any>("ConfigurationService");
|
|
48
|
+
if (configService) {
|
|
49
|
+
// Load initial config
|
|
50
|
+
this.enabled = configService.get("mirror.enabled", this.enabled);
|
|
51
|
+
|
|
52
|
+
// Listen for changes
|
|
53
|
+
configService.onAnyChange((e: { key: string; value: any }) => {
|
|
54
|
+
if (e.key === "mirror.enabled") {
|
|
55
|
+
this.applyMirror(e.value);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Initialize with current state (if enabled was persisted)
|
|
61
|
+
if (this.enabled) {
|
|
62
|
+
this.applyMirror(true);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
deactivate(context: ExtensionContext) {
|
|
67
|
+
this.applyMirror(false);
|
|
68
|
+
this.canvasService = undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
contribute() {
|
|
72
|
+
return {
|
|
73
|
+
[ContributionPointIds.CONFIGURATIONS]: [
|
|
74
|
+
{
|
|
75
|
+
id: "mirror.enabled",
|
|
76
|
+
type: "boolean",
|
|
77
|
+
label: "Enable Mirror",
|
|
78
|
+
default: false,
|
|
79
|
+
},
|
|
80
|
+
] as ConfigurationContribution[],
|
|
81
|
+
[ContributionPointIds.COMMANDS]: [
|
|
82
|
+
{
|
|
83
|
+
command: "setMirror",
|
|
84
|
+
title: "Set Mirror",
|
|
85
|
+
handler: (enabled: boolean) => {
|
|
86
|
+
this.applyMirror(enabled);
|
|
87
|
+
return true;
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
] as CommandContribution[],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private applyMirror(enabled: boolean) {
|
|
95
|
+
if (!this.canvasService) return;
|
|
96
|
+
const canvas = this.canvasService.canvas;
|
|
37
97
|
if (!canvas) return;
|
|
38
98
|
|
|
39
99
|
const width = canvas.width || 800;
|
|
@@ -54,6 +114,7 @@ export class MirrorTool implements Extension<MirrorToolOptions> {
|
|
|
54
114
|
|
|
55
115
|
canvas.setViewportTransform(vpt as any);
|
|
56
116
|
canvas.requestRenderAll();
|
|
117
|
+
this.enabled = true;
|
|
57
118
|
} else if (!enabled && isFlipped) {
|
|
58
119
|
// Restore
|
|
59
120
|
vpt[0] = -vpt[0]; // Unflip scale
|
|
@@ -61,31 +122,7 @@ export class MirrorTool implements Extension<MirrorToolOptions> {
|
|
|
61
122
|
|
|
62
123
|
canvas.setViewportTransform(vpt as any);
|
|
63
124
|
canvas.requestRenderAll();
|
|
125
|
+
this.enabled = false;
|
|
64
126
|
}
|
|
65
127
|
}
|
|
66
|
-
|
|
67
|
-
commands: Record<string, Command> = {
|
|
68
|
-
toggleMirror: {
|
|
69
|
-
execute: (editor: Editor) => {
|
|
70
|
-
this.options.enabled = !this.options.enabled;
|
|
71
|
-
this.applyMirror(editor, this.options.enabled);
|
|
72
|
-
return true;
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
setMirror: {
|
|
76
|
-
execute: (editor: Editor, enabled: boolean) => {
|
|
77
|
-
if (this.options.enabled === enabled) return true;
|
|
78
|
-
this.options.enabled = enabled;
|
|
79
|
-
this.applyMirror(editor, enabled);
|
|
80
|
-
return true;
|
|
81
|
-
},
|
|
82
|
-
schema: {
|
|
83
|
-
enabled: {
|
|
84
|
-
type: "boolean",
|
|
85
|
-
label: "Enabled",
|
|
86
|
-
required: true,
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
128
|
}
|
package/src/ruler.ts
CHANGED
|
@@ -1,111 +1,216 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Command,
|
|
3
|
-
Editor,
|
|
4
|
-
EditorState,
|
|
5
2
|
Extension,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Text,
|
|
3
|
+
ExtensionContext,
|
|
4
|
+
ContributionPointIds,
|
|
5
|
+
CommandContribution,
|
|
6
|
+
ConfigurationContribution,
|
|
11
7
|
} from "@pooder/core";
|
|
8
|
+
import { Rect, Line, Text } from "fabric";
|
|
9
|
+
import CanvasService from "./CanvasService";
|
|
12
10
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
thickness: number;
|
|
16
|
-
backgroundColor: string;
|
|
17
|
-
textColor: string;
|
|
18
|
-
lineColor: string;
|
|
19
|
-
fontSize: number;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export class RulerTool implements Extension<RulerToolOptions> {
|
|
23
|
-
public name = "RulerTool";
|
|
24
|
-
public options: RulerToolOptions = {
|
|
25
|
-
unit: "px",
|
|
26
|
-
thickness: 20,
|
|
27
|
-
backgroundColor: "#f0f0f0",
|
|
28
|
-
textColor: "#333333",
|
|
29
|
-
lineColor: "#999999",
|
|
30
|
-
fontSize: 10,
|
|
31
|
-
};
|
|
11
|
+
export class RulerTool implements Extension {
|
|
12
|
+
id = "pooder.kit.ruler";
|
|
32
13
|
|
|
33
|
-
public
|
|
34
|
-
|
|
35
|
-
type: "select",
|
|
36
|
-
options: ["px", "mm", "cm", "in"],
|
|
37
|
-
label: "Unit",
|
|
38
|
-
},
|
|
39
|
-
thickness: { type: "number", min: 10, max: 100, label: "Thickness" },
|
|
40
|
-
backgroundColor: { type: "color", label: "Background Color" },
|
|
41
|
-
textColor: { type: "color", label: "Text Color" },
|
|
42
|
-
lineColor: { type: "color", label: "Line Color" },
|
|
43
|
-
fontSize: { type: "number", min: 8, max: 24, label: "Font Size" },
|
|
14
|
+
public metadata = {
|
|
15
|
+
name: "RulerTool",
|
|
44
16
|
};
|
|
45
17
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
18
|
+
private unit: "px" | "mm" | "cm" | "in" = "px";
|
|
19
|
+
private thickness: number = 20;
|
|
20
|
+
private backgroundColor: string = "#f0f0f0";
|
|
21
|
+
private textColor: string = "#333333";
|
|
22
|
+
private lineColor: string = "#999999";
|
|
23
|
+
private fontSize: number = 10;
|
|
24
|
+
|
|
25
|
+
private canvasService?: CanvasService;
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
options?: Partial<{
|
|
29
|
+
unit: "px" | "mm" | "cm" | "in";
|
|
30
|
+
thickness: number;
|
|
31
|
+
backgroundColor: string;
|
|
32
|
+
textColor: string;
|
|
33
|
+
lineColor: string;
|
|
34
|
+
fontSize: number;
|
|
35
|
+
}>,
|
|
36
|
+
) {
|
|
37
|
+
if (options) {
|
|
38
|
+
Object.assign(this, options);
|
|
39
|
+
}
|
|
49
40
|
}
|
|
50
41
|
|
|
51
|
-
|
|
52
|
-
this.
|
|
53
|
-
|
|
42
|
+
activate(context: ExtensionContext) {
|
|
43
|
+
this.canvasService = context.services.get<CanvasService>("CanvasService");
|
|
44
|
+
if (!this.canvasService) {
|
|
45
|
+
console.warn("CanvasService not found for RulerTool");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const configService = context.services.get<any>("ConfigurationService");
|
|
50
|
+
if (configService) {
|
|
51
|
+
// Load initial config
|
|
52
|
+
this.unit = configService.get("ruler.unit", this.unit);
|
|
53
|
+
this.thickness = configService.get("ruler.thickness", this.thickness);
|
|
54
|
+
this.backgroundColor = configService.get(
|
|
55
|
+
"ruler.backgroundColor",
|
|
56
|
+
this.backgroundColor,
|
|
57
|
+
);
|
|
58
|
+
this.textColor = configService.get("ruler.textColor", this.textColor);
|
|
59
|
+
this.lineColor = configService.get("ruler.lineColor", this.lineColor);
|
|
60
|
+
this.fontSize = configService.get("ruler.fontSize", this.fontSize);
|
|
61
|
+
|
|
62
|
+
// Listen for changes
|
|
63
|
+
configService.onAnyChange((e: { key: string; value: any }) => {
|
|
64
|
+
if (e.key.startsWith("ruler.")) {
|
|
65
|
+
const prop = e.key.split(".")[1];
|
|
66
|
+
if (prop && prop in this) {
|
|
67
|
+
(this as any)[prop] = e.value;
|
|
68
|
+
this.updateRuler();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
54
73
|
|
|
55
|
-
|
|
56
|
-
this.updateRuler(
|
|
74
|
+
this.createLayer();
|
|
75
|
+
this.updateRuler();
|
|
57
76
|
}
|
|
58
77
|
|
|
59
|
-
|
|
60
|
-
this.destroyLayer(
|
|
78
|
+
deactivate(context: ExtensionContext) {
|
|
79
|
+
this.destroyLayer();
|
|
80
|
+
this.canvasService = undefined;
|
|
61
81
|
}
|
|
62
82
|
|
|
63
|
-
|
|
64
|
-
return
|
|
65
|
-
.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
contribute() {
|
|
84
|
+
return {
|
|
85
|
+
[ContributionPointIds.CONFIGURATIONS]: [
|
|
86
|
+
{
|
|
87
|
+
id: "ruler.unit",
|
|
88
|
+
type: "select",
|
|
89
|
+
label: "Unit",
|
|
90
|
+
options: ["px", "mm", "cm", "in"],
|
|
91
|
+
default: "px",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "ruler.thickness",
|
|
95
|
+
type: "number",
|
|
96
|
+
label: "Thickness",
|
|
97
|
+
min: 10,
|
|
98
|
+
max: 100,
|
|
99
|
+
default: 20,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: "ruler.backgroundColor",
|
|
103
|
+
type: "color",
|
|
104
|
+
label: "Background Color",
|
|
105
|
+
default: "#f0f0f0",
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: "ruler.textColor",
|
|
109
|
+
type: "color",
|
|
110
|
+
label: "Text Color",
|
|
111
|
+
default: "#333333",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: "ruler.lineColor",
|
|
115
|
+
type: "color",
|
|
116
|
+
label: "Line Color",
|
|
117
|
+
default: "#999999",
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: "ruler.fontSize",
|
|
121
|
+
type: "number",
|
|
122
|
+
label: "Font Size",
|
|
123
|
+
min: 8,
|
|
124
|
+
max: 24,
|
|
125
|
+
default: 10,
|
|
126
|
+
},
|
|
127
|
+
] as ConfigurationContribution[],
|
|
128
|
+
[ContributionPointIds.COMMANDS]: [
|
|
129
|
+
{
|
|
130
|
+
command: "setUnit",
|
|
131
|
+
title: "Set Ruler Unit",
|
|
132
|
+
handler: (unit: "px" | "mm" | "cm" | "in") => {
|
|
133
|
+
if (this.unit === unit) return true;
|
|
134
|
+
this.unit = unit;
|
|
135
|
+
this.updateRuler();
|
|
136
|
+
return true;
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
command: "setTheme",
|
|
141
|
+
title: "Set Ruler Theme",
|
|
142
|
+
handler: (
|
|
143
|
+
theme: Partial<{
|
|
144
|
+
backgroundColor: string;
|
|
145
|
+
textColor: string;
|
|
146
|
+
lineColor: string;
|
|
147
|
+
fontSize: number;
|
|
148
|
+
thickness: number;
|
|
149
|
+
}>,
|
|
150
|
+
) => {
|
|
151
|
+
const oldState = {
|
|
152
|
+
backgroundColor: this.backgroundColor,
|
|
153
|
+
textColor: this.textColor,
|
|
154
|
+
lineColor: this.lineColor,
|
|
155
|
+
fontSize: this.fontSize,
|
|
156
|
+
thickness: this.thickness,
|
|
157
|
+
};
|
|
158
|
+
const newState = { ...oldState, ...theme };
|
|
159
|
+
if (JSON.stringify(newState) === JSON.stringify(oldState))
|
|
160
|
+
return true;
|
|
161
|
+
|
|
162
|
+
Object.assign(this, newState);
|
|
163
|
+
this.updateRuler();
|
|
164
|
+
return true;
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
] as CommandContribution[],
|
|
168
|
+
};
|
|
69
169
|
}
|
|
70
170
|
|
|
71
|
-
private
|
|
72
|
-
|
|
171
|
+
private getLayer() {
|
|
172
|
+
return this.canvasService?.getLayer("ruler-overlay");
|
|
173
|
+
}
|
|
73
174
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const height = editor.canvas.height || 600;
|
|
175
|
+
private createLayer() {
|
|
176
|
+
if (!this.canvasService) return;
|
|
77
177
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
selectable: false,
|
|
82
|
-
evented: false,
|
|
83
|
-
data: { id: "ruler-overlay" },
|
|
84
|
-
} as any);
|
|
178
|
+
const canvas = this.canvasService.canvas;
|
|
179
|
+
const width = canvas.width || 800;
|
|
180
|
+
const height = canvas.height || 600;
|
|
85
181
|
|
|
86
|
-
|
|
87
|
-
|
|
182
|
+
const layer = this.canvasService.createLayer("ruler-overlay", {
|
|
183
|
+
width,
|
|
184
|
+
height,
|
|
185
|
+
selectable: false,
|
|
186
|
+
evented: false,
|
|
187
|
+
left: 0,
|
|
188
|
+
top: 0,
|
|
189
|
+
originX: "left",
|
|
190
|
+
originY: "top",
|
|
191
|
+
});
|
|
88
192
|
|
|
89
|
-
|
|
193
|
+
canvas.bringObjectToFront(layer);
|
|
90
194
|
}
|
|
91
195
|
|
|
92
|
-
private destroyLayer(
|
|
93
|
-
|
|
196
|
+
private destroyLayer() {
|
|
197
|
+
if (!this.canvasService) return;
|
|
198
|
+
const layer = this.getLayer();
|
|
94
199
|
if (layer) {
|
|
95
|
-
|
|
200
|
+
this.canvasService.canvas.remove(layer);
|
|
96
201
|
}
|
|
97
202
|
}
|
|
98
203
|
|
|
99
|
-
private updateRuler(
|
|
100
|
-
|
|
204
|
+
private updateRuler() {
|
|
205
|
+
if (!this.canvasService) return;
|
|
206
|
+
const layer = this.getLayer();
|
|
101
207
|
if (!layer) return;
|
|
102
208
|
|
|
103
209
|
layer.remove(...layer.getObjects());
|
|
104
210
|
|
|
105
|
-
const { thickness, backgroundColor, lineColor, textColor, fontSize } =
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
const height = editor.canvas.height || 600;
|
|
211
|
+
const { thickness, backgroundColor, lineColor, textColor, fontSize } = this;
|
|
212
|
+
const width = this.canvasService.canvas.width || 800;
|
|
213
|
+
const height = this.canvasService.canvas.height || 600;
|
|
109
214
|
|
|
110
215
|
// Backgrounds
|
|
111
216
|
const topBg = new Rect({
|
|
@@ -140,7 +245,9 @@ export class RulerTool implements Extension<RulerToolOptions> {
|
|
|
140
245
|
evented: false,
|
|
141
246
|
});
|
|
142
247
|
|
|
143
|
-
layer.add(topBg
|
|
248
|
+
layer.add(topBg);
|
|
249
|
+
layer.add(leftBg);
|
|
250
|
+
layer.add(cornerBg);
|
|
144
251
|
|
|
145
252
|
// Drawing Constants (Pixel based for now)
|
|
146
253
|
const step = 100; // Major tick
|
|
@@ -212,44 +319,7 @@ export class RulerTool implements Extension<RulerToolOptions> {
|
|
|
212
319
|
}
|
|
213
320
|
|
|
214
321
|
// Always bring ruler to front
|
|
215
|
-
|
|
216
|
-
|
|
322
|
+
this.canvasService.canvas.bringObjectToFront(layer);
|
|
323
|
+
this.canvasService.canvas.requestRenderAll();
|
|
217
324
|
}
|
|
218
|
-
|
|
219
|
-
commands: Record<string, Command> = {
|
|
220
|
-
setUnit: {
|
|
221
|
-
execute: (editor: Editor, unit: "px" | "mm" | "cm" | "in") => {
|
|
222
|
-
if (this.options.unit === unit) return true;
|
|
223
|
-
this.options.unit = unit;
|
|
224
|
-
this.updateRuler(editor);
|
|
225
|
-
return true;
|
|
226
|
-
},
|
|
227
|
-
schema: {
|
|
228
|
-
unit: {
|
|
229
|
-
type: "string",
|
|
230
|
-
label: "Unit",
|
|
231
|
-
options: ["px", "mm", "cm", "in"],
|
|
232
|
-
required: true,
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
setTheme: {
|
|
237
|
-
execute: (editor: Editor, theme: Partial<RulerToolOptions>) => {
|
|
238
|
-
const newOptions = { ...this.options, ...theme };
|
|
239
|
-
if (JSON.stringify(newOptions) === JSON.stringify(this.options))
|
|
240
|
-
return true;
|
|
241
|
-
|
|
242
|
-
this.options = newOptions;
|
|
243
|
-
this.updateRuler(editor);
|
|
244
|
-
return true;
|
|
245
|
-
},
|
|
246
|
-
schema: {
|
|
247
|
-
theme: {
|
|
248
|
-
type: "object",
|
|
249
|
-
label: "Theme",
|
|
250
|
-
required: true,
|
|
251
|
-
},
|
|
252
|
-
},
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
325
|
}
|