juxscript 1.1.30 → 1.1.32

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/index.d.ts CHANGED
@@ -27,6 +27,7 @@ import { menu } from './lib/components/menu.js';
27
27
  import { modal } from './lib/components/modal.js';
28
28
  import { nav } from './lib/components/nav.js';
29
29
  import { paragraph } from './lib/components/paragraph.js';
30
+ import { pen } from './lib/components/pen.js';
30
31
  import { progress } from './lib/components/progress.js';
31
32
  import { radio } from './lib/components/radio.js';
32
33
  import { script } from './lib/components/script.js';
@@ -74,6 +75,7 @@ export declare const jux: {
74
75
  modal: typeof modal;
75
76
  nav: typeof nav;
76
77
  paragraph: typeof paragraph;
78
+ pen: typeof pen;
77
79
  progress: typeof progress;
78
80
  radio: typeof radio;
79
81
  req: import("./lib/components/req.js").Req;
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAGzC,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDf,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -27,6 +27,7 @@ import { menu } from './lib/components/menu.js';
27
27
  import { modal } from './lib/components/modal.js';
28
28
  import { nav } from './lib/components/nav.js';
29
29
  import { paragraph } from './lib/components/paragraph.js';
30
+ import { pen } from './lib/components/pen.js'; // ✅ Import pen
30
31
  import { progress } from './lib/components/progress.js';
31
32
  import { radio } from './lib/components/radio.js';
32
33
  import { req } from './lib/components/req.js';
@@ -77,6 +78,7 @@ export const jux = {
77
78
  modal,
78
79
  nav,
79
80
  paragraph,
81
+ pen,
80
82
  progress,
81
83
  radio,
82
84
  req,
@@ -0,0 +1,125 @@
1
+ import { BaseComponent, BaseState } from './base/BaseComponent.js';
2
+ export interface PenShape {
3
+ id: string;
4
+ type: 'line' | 'rectangle' | 'circle' | 'text';
5
+ x: number;
6
+ y: number;
7
+ width?: number;
8
+ height?: number;
9
+ radius?: number;
10
+ text?: string;
11
+ color?: string;
12
+ fillColor?: string;
13
+ strokeWidth?: number;
14
+ connectedTo?: string[];
15
+ }
16
+ export interface PenConnection {
17
+ from: string;
18
+ to: string;
19
+ color?: string;
20
+ strokeWidth?: number;
21
+ dashed?: boolean;
22
+ }
23
+ export interface PenOptions {
24
+ width?: number | string;
25
+ height?: number | string;
26
+ backgroundColor?: string;
27
+ backgroundImage?: string;
28
+ border?: string;
29
+ text?: string;
30
+ radius?: number;
31
+ gridEnabled?: boolean;
32
+ gridSize?: number;
33
+ gridColor?: string;
34
+ style?: string;
35
+ class?: string;
36
+ }
37
+ type PenState = BaseState & {
38
+ width: number | string;
39
+ height: number | string;
40
+ backgroundColor: string;
41
+ backgroundImage: string;
42
+ border: string;
43
+ text: string;
44
+ radius: number;
45
+ gridEnabled: boolean;
46
+ gridSize: number;
47
+ gridColor: string;
48
+ shapes: PenShape[];
49
+ connections: PenConnection[];
50
+ };
51
+ export declare class Pen extends BaseComponent<PenState> {
52
+ private _canvas;
53
+ private _ctx;
54
+ private _animationFrame?;
55
+ constructor(id: string, options?: PenOptions);
56
+ protected getTriggerEvents(): readonly string[];
57
+ protected getCallbackEvents(): readonly string[];
58
+ update(prop: string, value: any): void;
59
+ width(value: number | string): this;
60
+ height(value: number | string): this;
61
+ backgroundColor(value: string): this;
62
+ backgroundImage(value: string): this;
63
+ border(value: string): this;
64
+ text(value: string): this;
65
+ radius(value: number): this;
66
+ grid(enabled: boolean, size?: number, color?: string): this;
67
+ /**
68
+ * Add a line shape
69
+ */
70
+ drawLine(x1: number, y1: number, x2: number, y2: number, options?: Partial<PenShape>): this;
71
+ /**
72
+ * Add a rectangle shape
73
+ */
74
+ drawRect(x: number, y: number, width: number, height: number, options?: Partial<PenShape>): this;
75
+ /**
76
+ * Add a circle shape
77
+ */
78
+ drawCircle(x: number, y: number, radius: number, options?: Partial<PenShape>): this;
79
+ /**
80
+ * Add text to canvas
81
+ */
82
+ drawText(x: number, y: number, text: string, options?: Partial<PenShape>): this;
83
+ /**
84
+ * Connect two shapes with a line
85
+ */
86
+ connect(fromId: string, toId: string, options?: Partial<PenConnection>): this;
87
+ /**
88
+ * Remove a shape by ID
89
+ */
90
+ removeShape(id: string): this;
91
+ /**
92
+ * Clear all shapes and connections
93
+ */
94
+ clear(): this;
95
+ /**
96
+ * Get shape by ID
97
+ */
98
+ getShape(id: string): PenShape | undefined;
99
+ /**
100
+ * Get all shapes
101
+ */
102
+ getShapes(): PenShape[];
103
+ /**
104
+ * Export canvas as data URL
105
+ */
106
+ toDataURL(type?: string): string;
107
+ /**
108
+ * Download canvas as image
109
+ */
110
+ download(filename?: string): this;
111
+ private _updateCanvasSize;
112
+ private _redraw;
113
+ private _drawContent;
114
+ private _drawGrid;
115
+ private _drawShape;
116
+ private _drawConnection;
117
+ render(targetId?: string): this;
118
+ /**
119
+ * Cleanup on destroy
120
+ */
121
+ destroy(): void;
122
+ }
123
+ export declare function pen(id: string, options?: PenOptions): Pen;
124
+ export {};
125
+ //# sourceMappingURL=pen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pen.d.ts","sourceRoot":"","sources":["pen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,443 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ // Event definitions
3
+ const TRIGGER_EVENTS = [];
4
+ const CALLBACK_EVENTS = ['draw', 'shapeAdd', 'shapeRemove', 'connectionAdd'];
5
+ export class Pen extends BaseComponent {
6
+ constructor(id, options = {}) {
7
+ super(id, {
8
+ width: options.width ?? '100%',
9
+ height: options.height ?? 400,
10
+ backgroundColor: options.backgroundColor ?? '#ffffff',
11
+ backgroundImage: options.backgroundImage ?? '',
12
+ border: options.border ?? '1px solid #e5e7eb',
13
+ text: options.text ?? '',
14
+ radius: options.radius ?? 0,
15
+ gridEnabled: options.gridEnabled ?? false,
16
+ gridSize: options.gridSize ?? 20,
17
+ gridColor: options.gridColor ?? '#f0f0f0',
18
+ shapes: [],
19
+ connections: [],
20
+ style: options.style ?? '',
21
+ class: options.class ?? ''
22
+ });
23
+ this._canvas = null;
24
+ this._ctx = null;
25
+ }
26
+ getTriggerEvents() {
27
+ return TRIGGER_EVENTS;
28
+ }
29
+ getCallbackEvents() {
30
+ return CALLBACK_EVENTS;
31
+ }
32
+ /* ═════════════════════════════════════════════════════════════════
33
+ * REACTIVE UPDATE
34
+ * ═════════════════════════════════════════════════════════════════ */
35
+ update(prop, value) {
36
+ super.update(prop, value);
37
+ if (!this._canvas || !this._ctx)
38
+ return;
39
+ switch (prop) {
40
+ case 'backgroundColor':
41
+ this._redraw();
42
+ break;
43
+ case 'backgroundImage':
44
+ this._redraw();
45
+ break;
46
+ case 'text':
47
+ this._redraw();
48
+ break;
49
+ case 'gridEnabled':
50
+ case 'gridSize':
51
+ case 'gridColor':
52
+ this._redraw();
53
+ break;
54
+ case 'shapes':
55
+ case 'connections':
56
+ this._redraw();
57
+ break;
58
+ }
59
+ }
60
+ /* ═════════════════════════════════════════════════════════════════
61
+ * FLUENT API
62
+ * ═════════════════════════════════════════════════════════════════ */
63
+ width(value) {
64
+ this.state.width = value;
65
+ if (this._canvas) {
66
+ this._canvas.style.width = typeof value === 'number' ? `${value}px` : value;
67
+ this._updateCanvasSize();
68
+ }
69
+ return this;
70
+ }
71
+ height(value) {
72
+ this.state.height = value;
73
+ if (this._canvas) {
74
+ this._canvas.style.height = typeof value === 'number' ? `${value}px` : value;
75
+ this._updateCanvasSize();
76
+ }
77
+ return this;
78
+ }
79
+ backgroundColor(value) {
80
+ this.state.backgroundColor = value;
81
+ return this;
82
+ }
83
+ backgroundImage(value) {
84
+ this.state.backgroundImage = value;
85
+ return this;
86
+ }
87
+ border(value) {
88
+ this.state.border = value;
89
+ if (this._canvas) {
90
+ this._canvas.style.border = value;
91
+ }
92
+ return this;
93
+ }
94
+ text(value) {
95
+ this.state.text = value;
96
+ return this;
97
+ }
98
+ radius(value) {
99
+ this.state.radius = value;
100
+ if (this._canvas) {
101
+ this._canvas.style.borderRadius = `${value}px`;
102
+ }
103
+ return this;
104
+ }
105
+ grid(enabled, size, color) {
106
+ this.state.gridEnabled = enabled;
107
+ if (size !== undefined)
108
+ this.state.gridSize = size;
109
+ if (color !== undefined)
110
+ this.state.gridColor = color;
111
+ return this;
112
+ }
113
+ /* ═════════════════════════════════════════════════════════════════
114
+ * DRAWING API
115
+ * ═════════════════════════════════════════════════════════════════ */
116
+ /**
117
+ * Add a line shape
118
+ */
119
+ drawLine(x1, y1, x2, y2, options = {}) {
120
+ const shape = {
121
+ id: options.id || `line-${Date.now()}-${Math.random()}`,
122
+ type: 'line',
123
+ x: x1,
124
+ y: y1,
125
+ width: x2 - x1,
126
+ height: y2 - y1,
127
+ color: options.color || '#000000',
128
+ strokeWidth: options.strokeWidth || 2,
129
+ connectedTo: options.connectedTo || []
130
+ };
131
+ this.state.shapes = [...this.state.shapes, shape];
132
+ this._triggerCallback('shapeAdd', shape);
133
+ return this;
134
+ }
135
+ /**
136
+ * Add a rectangle shape
137
+ */
138
+ drawRect(x, y, width, height, options = {}) {
139
+ const shape = {
140
+ id: options.id || `rect-${Date.now()}-${Math.random()}`,
141
+ type: 'rectangle',
142
+ x,
143
+ y,
144
+ width,
145
+ height,
146
+ color: options.color || '#000000',
147
+ fillColor: options.fillColor,
148
+ strokeWidth: options.strokeWidth || 2,
149
+ connectedTo: options.connectedTo || []
150
+ };
151
+ this.state.shapes = [...this.state.shapes, shape];
152
+ this._triggerCallback('shapeAdd', shape);
153
+ return this;
154
+ }
155
+ /**
156
+ * Add a circle shape
157
+ */
158
+ drawCircle(x, y, radius, options = {}) {
159
+ const shape = {
160
+ id: options.id || `circle-${Date.now()}-${Math.random()}`,
161
+ type: 'circle',
162
+ x,
163
+ y,
164
+ radius,
165
+ color: options.color || '#000000',
166
+ fillColor: options.fillColor,
167
+ strokeWidth: options.strokeWidth || 2,
168
+ connectedTo: options.connectedTo || []
169
+ };
170
+ this.state.shapes = [...this.state.shapes, shape];
171
+ this._triggerCallback('shapeAdd', shape);
172
+ return this;
173
+ }
174
+ /**
175
+ * Add text to canvas
176
+ */
177
+ drawText(x, y, text, options = {}) {
178
+ const shape = {
179
+ id: options.id || `text-${Date.now()}-${Math.random()}`,
180
+ type: 'text',
181
+ x,
182
+ y,
183
+ text,
184
+ color: options.color || '#000000',
185
+ connectedTo: options.connectedTo || []
186
+ };
187
+ this.state.shapes = [...this.state.shapes, shape];
188
+ this._triggerCallback('shapeAdd', shape);
189
+ return this;
190
+ }
191
+ /**
192
+ * Connect two shapes with a line
193
+ */
194
+ connect(fromId, toId, options = {}) {
195
+ const connection = {
196
+ from: fromId,
197
+ to: toId,
198
+ color: options.color || '#666666',
199
+ strokeWidth: options.strokeWidth || 1,
200
+ dashed: options.dashed || false
201
+ };
202
+ this.state.connections = [...this.state.connections, connection];
203
+ // Update connected shapes
204
+ const fromShape = this.state.shapes.find(s => s.id === fromId);
205
+ if (fromShape && !fromShape.connectedTo?.includes(toId)) {
206
+ fromShape.connectedTo = [...(fromShape.connectedTo || []), toId];
207
+ }
208
+ this._triggerCallback('connectionAdd', connection);
209
+ return this;
210
+ }
211
+ /**
212
+ * Remove a shape by ID
213
+ */
214
+ removeShape(id) {
215
+ this.state.shapes = this.state.shapes.filter(s => s.id !== id);
216
+ this.state.connections = this.state.connections.filter(c => c.from !== id && c.to !== id);
217
+ this._triggerCallback('shapeRemove', id);
218
+ return this;
219
+ }
220
+ /**
221
+ * Clear all shapes and connections
222
+ */
223
+ clear() {
224
+ this.state.shapes = [];
225
+ this.state.connections = [];
226
+ return this;
227
+ }
228
+ /**
229
+ * Get shape by ID
230
+ */
231
+ getShape(id) {
232
+ return this.state.shapes.find(s => s.id === id);
233
+ }
234
+ /**
235
+ * Get all shapes
236
+ */
237
+ getShapes() {
238
+ return this.state.shapes;
239
+ }
240
+ /**
241
+ * Export canvas as data URL
242
+ */
243
+ toDataURL(type = 'image/png') {
244
+ return this._canvas?.toDataURL(type) || '';
245
+ }
246
+ /**
247
+ * Download canvas as image
248
+ */
249
+ download(filename = 'pen-drawing.png') {
250
+ const dataURL = this.toDataURL();
251
+ const link = document.createElement('a');
252
+ link.download = filename;
253
+ link.href = dataURL;
254
+ link.click();
255
+ return this;
256
+ }
257
+ /* ═════════════════════════════════════════════════════════════════
258
+ * PRIVATE RENDERING
259
+ * ═════════════════════════════════════════════════════════════════ */
260
+ _updateCanvasSize() {
261
+ if (!this._canvas)
262
+ return;
263
+ const rect = this._canvas.getBoundingClientRect();
264
+ this._canvas.width = rect.width;
265
+ this._canvas.height = rect.height;
266
+ this._redraw();
267
+ }
268
+ _redraw() {
269
+ if (!this._ctx || !this._canvas)
270
+ return;
271
+ const { width, height } = this._canvas;
272
+ // Clear canvas
273
+ this._ctx.clearRect(0, 0, width, height);
274
+ // Draw background
275
+ if (this.state.backgroundColor) {
276
+ this._ctx.fillStyle = this.state.backgroundColor;
277
+ this._ctx.fillRect(0, 0, width, height);
278
+ }
279
+ // Draw background image
280
+ if (this.state.backgroundImage) {
281
+ const img = new Image();
282
+ img.src = this.state.backgroundImage;
283
+ img.onload = () => {
284
+ this._ctx?.drawImage(img, 0, 0, width, height);
285
+ this._drawContent();
286
+ };
287
+ }
288
+ else {
289
+ this._drawContent();
290
+ }
291
+ }
292
+ _drawContent() {
293
+ if (!this._ctx || !this._canvas)
294
+ return;
295
+ // Draw grid
296
+ if (this.state.gridEnabled) {
297
+ this._drawGrid();
298
+ }
299
+ // Draw connections first (under shapes)
300
+ this.state.connections.forEach(conn => this._drawConnection(conn));
301
+ // Draw shapes
302
+ this.state.shapes.forEach(shape => this._drawShape(shape));
303
+ // Draw text overlay
304
+ if (this.state.text) {
305
+ this._ctx.fillStyle = '#000000';
306
+ this._ctx.font = '16px sans-serif';
307
+ this._ctx.fillText(this.state.text, 10, 30);
308
+ }
309
+ this._triggerCallback('draw', { shapes: this.state.shapes, connections: this.state.connections });
310
+ }
311
+ _drawGrid() {
312
+ if (!this._ctx || !this._canvas)
313
+ return;
314
+ const { width, height } = this._canvas;
315
+ const { gridSize, gridColor } = this.state;
316
+ this._ctx.strokeStyle = gridColor;
317
+ this._ctx.lineWidth = 1;
318
+ // Vertical lines
319
+ for (let x = 0; x <= width; x += gridSize) {
320
+ this._ctx.beginPath();
321
+ this._ctx.moveTo(x, 0);
322
+ this._ctx.lineTo(x, height);
323
+ this._ctx.stroke();
324
+ }
325
+ // Horizontal lines
326
+ for (let y = 0; y <= height; y += gridSize) {
327
+ this._ctx.beginPath();
328
+ this._ctx.moveTo(0, y);
329
+ this._ctx.lineTo(width, y);
330
+ this._ctx.stroke();
331
+ }
332
+ }
333
+ _drawShape(shape) {
334
+ if (!this._ctx)
335
+ return;
336
+ this._ctx.strokeStyle = shape.color || '#000000';
337
+ this._ctx.lineWidth = shape.strokeWidth || 2;
338
+ switch (shape.type) {
339
+ case 'line':
340
+ this._ctx.beginPath();
341
+ this._ctx.moveTo(shape.x, shape.y);
342
+ this._ctx.lineTo(shape.x + (shape.width || 0), shape.y + (shape.height || 0));
343
+ this._ctx.stroke();
344
+ break;
345
+ case 'rectangle':
346
+ if (shape.fillColor) {
347
+ this._ctx.fillStyle = shape.fillColor;
348
+ this._ctx.fillRect(shape.x, shape.y, shape.width || 0, shape.height || 0);
349
+ }
350
+ this._ctx.strokeRect(shape.x, shape.y, shape.width || 0, shape.height || 0);
351
+ break;
352
+ case 'circle':
353
+ this._ctx.beginPath();
354
+ this._ctx.arc(shape.x, shape.y, shape.radius || 0, 0, Math.PI * 2);
355
+ if (shape.fillColor) {
356
+ this._ctx.fillStyle = shape.fillColor;
357
+ this._ctx.fill();
358
+ }
359
+ this._ctx.stroke();
360
+ break;
361
+ case 'text':
362
+ this._ctx.fillStyle = shape.color || '#000000';
363
+ this._ctx.font = '14px sans-serif';
364
+ this._ctx.fillText(shape.text || '', shape.x, shape.y);
365
+ break;
366
+ }
367
+ }
368
+ _drawConnection(conn) {
369
+ if (!this._ctx)
370
+ return;
371
+ const fromShape = this.state.shapes.find(s => s.id === conn.from);
372
+ const toShape = this.state.shapes.find(s => s.id === conn.to);
373
+ if (!fromShape || !toShape)
374
+ return;
375
+ // Calculate center points
376
+ const fromX = fromShape.x + (fromShape.width || fromShape.radius || 0) / 2;
377
+ const fromY = fromShape.y + (fromShape.height || fromShape.radius || 0) / 2;
378
+ const toX = toShape.x + (toShape.width || toShape.radius || 0) / 2;
379
+ const toY = toShape.y + (toShape.height || toShape.radius || 0) / 2;
380
+ this._ctx.strokeStyle = conn.color || '#666666';
381
+ this._ctx.lineWidth = conn.strokeWidth || 1;
382
+ if (conn.dashed) {
383
+ this._ctx.setLineDash([5, 5]);
384
+ }
385
+ this._ctx.beginPath();
386
+ this._ctx.moveTo(fromX, fromY);
387
+ this._ctx.lineTo(toX, toY);
388
+ this._ctx.stroke();
389
+ if (conn.dashed) {
390
+ this._ctx.setLineDash([]);
391
+ }
392
+ }
393
+ /* ═════════════════════════════════════════════════════════════════
394
+ * RENDER
395
+ * ═════════════════════════════════════════════════════════════════ */
396
+ render(targetId) {
397
+ const container = this._setupContainer(targetId);
398
+ const { width, height, backgroundColor, border, radius, style, class: className } = this.state;
399
+ const wrapper = document.createElement('div');
400
+ wrapper.className = 'jux-pen';
401
+ wrapper.id = `${this._id}-wrapper`;
402
+ if (className)
403
+ wrapper.className += ` ${className}`;
404
+ if (style)
405
+ wrapper.setAttribute('style', style);
406
+ const canvas = document.createElement('canvas');
407
+ canvas.id = this._id;
408
+ canvas.className = 'jux-pen-canvas';
409
+ canvas.style.width = typeof width === 'number' ? `${width}px` : width;
410
+ canvas.style.height = typeof height === 'number' ? `${height}px` : height;
411
+ canvas.style.backgroundColor = backgroundColor;
412
+ canvas.style.border = border;
413
+ canvas.style.borderRadius = `${radius}px`;
414
+ canvas.style.display = 'block';
415
+ this._canvas = canvas;
416
+ this._ctx = canvas.getContext('2d');
417
+ // Set initial canvas size
418
+ requestAnimationFrame(() => {
419
+ this._updateCanvasSize();
420
+ });
421
+ // Handle window resize
422
+ window.addEventListener('resize', () => {
423
+ this._updateCanvasSize();
424
+ });
425
+ this._wireStandardEvents(wrapper);
426
+ this._wireAllSyncs();
427
+ wrapper.appendChild(canvas);
428
+ container.appendChild(wrapper);
429
+ return this;
430
+ }
431
+ /**
432
+ * Cleanup on destroy
433
+ */
434
+ destroy() {
435
+ if (this._animationFrame) {
436
+ cancelAnimationFrame(this._animationFrame);
437
+ }
438
+ this.remove();
439
+ }
440
+ }
441
+ export function pen(id, options = {}) {
442
+ return new Pen(id, options);
443
+ }