@elixpo/lixsketch 4.5.8

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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +169 -0
  3. package/fonts/fonts.css +29 -0
  4. package/fonts/lixCode.ttf +0 -0
  5. package/fonts/lixDefault.ttf +0 -0
  6. package/fonts/lixDocs.ttf +0 -0
  7. package/fonts/lixFancy.ttf +0 -0
  8. package/fonts/lixFont.woff2 +0 -0
  9. package/package.json +49 -0
  10. package/src/SketchEngine.js +473 -0
  11. package/src/core/AIRenderer.js +1390 -0
  12. package/src/core/CopyPaste.js +655 -0
  13. package/src/core/EraserTrail.js +234 -0
  14. package/src/core/EventDispatcher.js +371 -0
  15. package/src/core/GraphEngine.js +150 -0
  16. package/src/core/GraphMathParser.js +231 -0
  17. package/src/core/GraphRenderer.js +255 -0
  18. package/src/core/LayerOrder.js +91 -0
  19. package/src/core/LixScriptParser.js +1299 -0
  20. package/src/core/MermaidFlowchartRenderer.js +475 -0
  21. package/src/core/MermaidSequenceParser.js +197 -0
  22. package/src/core/MermaidSequenceRenderer.js +479 -0
  23. package/src/core/ResizeCode.js +175 -0
  24. package/src/core/ResizeShapes.js +318 -0
  25. package/src/core/SceneSerializer.js +778 -0
  26. package/src/core/Selection.js +1861 -0
  27. package/src/core/SnapGuides.js +273 -0
  28. package/src/core/UndoRedo.js +1358 -0
  29. package/src/core/ZoomPan.js +258 -0
  30. package/src/core/ai-system-prompt.js +663 -0
  31. package/src/index.js +69 -0
  32. package/src/shapes/Arrow.js +1979 -0
  33. package/src/shapes/Circle.js +751 -0
  34. package/src/shapes/CodeShape.js +244 -0
  35. package/src/shapes/Frame.js +1460 -0
  36. package/src/shapes/FreehandStroke.js +724 -0
  37. package/src/shapes/IconShape.js +265 -0
  38. package/src/shapes/ImageShape.js +270 -0
  39. package/src/shapes/Line.js +738 -0
  40. package/src/shapes/Rectangle.js +794 -0
  41. package/src/shapes/TextShape.js +225 -0
  42. package/src/tools/arrowTool.js +581 -0
  43. package/src/tools/circleTool.js +619 -0
  44. package/src/tools/codeTool.js +2103 -0
  45. package/src/tools/eraserTool.js +131 -0
  46. package/src/tools/frameTool.js +241 -0
  47. package/src/tools/freehandTool.js +620 -0
  48. package/src/tools/iconTool.js +1344 -0
  49. package/src/tools/imageTool.js +1323 -0
  50. package/src/tools/laserTool.js +317 -0
  51. package/src/tools/lineTool.js +502 -0
  52. package/src/tools/rectangleTool.js +544 -0
  53. package/src/tools/textTool.js +1823 -0
  54. package/src/utils/imageCompressor.js +107 -0
@@ -0,0 +1,502 @@
1
+ /* eslint-disable */
2
+ // Line tool event handlers - extracted from lineTool.js
3
+ import { pushCreateAction, pushDeleteAction, pushOptionsChangeAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';
4
+ import { updateAttachedArrows as updateArrowsForShape, cleanupAttachments } from './arrowTool.js';
5
+ import { calculateSnap, clearSnapGuides } from '../core/SnapGuides.js';
6
+
7
+ let isDrawingLine = false;
8
+ let currentLine = null;
9
+ let lineStartX = 0;
10
+ let lineStartY = 0;
11
+ let currentLineGroup = null;
12
+ let lineColor = "#fff";
13
+ let lineStrokeWidth = 3;
14
+ let lineStrokeStyle = "solid";
15
+ let lineEdgeType = 1;
16
+ let lineSktetchRate = 3;
17
+
18
+ let isDraggingLine = false;
19
+ let dragOldPosLine = null;
20
+ let copiedShapeData = null;
21
+ let draggedShapeInitialFrameLine = null;
22
+ let hoveredFrameLine = null;
23
+
24
+ let startX, startY;
25
+
26
+ let lineColorOptions = document.querySelectorAll(".lineColor > span");
27
+ let lineThicknessOptions = document.querySelectorAll(".lineThicknessSpan");
28
+ let lineOutlineOptions = document.querySelectorAll(".lineStyleSpan");
29
+ let lineSlopeOptions = document.querySelectorAll(".lineSlopeSpan");
30
+ let lineEdgeOptions = document.querySelectorAll(".lineEdgeSpan");
31
+
32
+
33
+ function getSVGCoordsFromMouse(e) {
34
+ const viewBox = svg.viewBox.baseVal;
35
+ const rect = svg.getBoundingClientRect();
36
+ const mouseX = e.clientX - rect.left;
37
+ const mouseY = e.clientY - rect.top;
38
+ const svgX = viewBox.x + (mouseX / rect.width) * viewBox.width;
39
+ const svgY = viewBox.y + (mouseY / rect.height) * viewBox.height;
40
+ return { x: svgX, y: svgY };
41
+ }
42
+
43
+ // Add delete functionality
44
+ function deleteCurrentShape() {
45
+ if (currentShape && currentShape.shapeName === 'line') {
46
+ const idx = shapes.indexOf(currentShape);
47
+ if (idx !== -1) shapes.splice(idx, 1);
48
+ if (currentShape.group.parentNode) {
49
+ currentShape.group.parentNode.removeChild(currentShape.group);
50
+ }
51
+ pushDeleteAction(currentShape);
52
+ currentShape = null;
53
+ disableAllSideBars();
54
+ }
55
+ }
56
+
57
+ document.addEventListener('keydown', (e) => {
58
+ if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'line') {
59
+ deleteCurrentShape();
60
+ }
61
+ });
62
+
63
+ const handleMouseDown = (e) => {
64
+ if (!isLineToolActive && !isSelectionToolActive) return;
65
+
66
+ const { x, y } = getSVGCoordsFromMouse(e);
67
+
68
+ if (isLineToolActive) {
69
+ isDrawingLine = true;
70
+ currentLine = new Line(
71
+ { x, y },
72
+ { x, y },
73
+ {
74
+ stroke: lineColor,
75
+ strokeWidth: lineStrokeWidth,
76
+ roughness: lineSktetchRate,
77
+ bowing: lineEdgeType,
78
+ strokeDasharray: lineStrokeStyle === "dashed" ? "5,5" : (lineStrokeStyle === "dotted" ? "2,12" : "")
79
+ }
80
+ );
81
+ currentLine.isBeingDrawn = true;
82
+ shapes.push(currentLine);
83
+ currentShape = currentLine;
84
+ } else if (isSelectionToolActive) {
85
+ let clickedOnShape = false;
86
+
87
+ // Check if clicking on current selected line
88
+ if (currentShape && currentShape.shapeName === 'line' && currentShape.isSelected) {
89
+ const anchorInfo = currentShape.isNearAnchor(x, y);
90
+
91
+ if (anchorInfo && anchorInfo.type === 'anchor') {
92
+ clickedOnShape = true;
93
+ // Start anchor drag
94
+ dragOldPosLine = {
95
+ startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },
96
+ endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },
97
+ controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,
98
+ isCurved: currentShape.isCurved,
99
+ parentFrame: currentShape.parentFrame
100
+ };
101
+
102
+ const anchorIndex = anchorInfo.index;
103
+
104
+ const onPointerMove = (event) => {
105
+ const { x: newX, y: newY } = getSVGCoordsFromMouse(event);
106
+ currentShape.updatePosition(anchorIndex, newX, newY);
107
+ };
108
+
109
+ const onPointerUp = () => {
110
+ if (dragOldPosLine) {
111
+ const newPos = {
112
+ startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },
113
+ endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },
114
+ controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,
115
+ isCurved: currentShape.isCurved,
116
+ parentFrame: currentShape.parentFrame
117
+ };
118
+ pushTransformAction(currentShape, dragOldPosLine, newPos);
119
+ dragOldPosLine = null;
120
+ }
121
+ svg.removeEventListener('pointermove', onPointerMove);
122
+ svg.removeEventListener('pointerup', onPointerUp);
123
+ };
124
+
125
+ svg.addEventListener('pointermove', onPointerMove);
126
+ svg.addEventListener('pointerup', onPointerUp);
127
+
128
+ // Prevent default to stop any other drag behavior
129
+ e.preventDefault();
130
+ e.stopPropagation();
131
+
132
+ } else if (currentShape.contains(x, y)) {
133
+ // Dragging the line itself (not anchors)
134
+ isDraggingLine = true;
135
+ dragOldPosLine = {
136
+ startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },
137
+ endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },
138
+ controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,
139
+ isCurved: currentShape.isCurved,
140
+ parentFrame: currentShape.parentFrame
141
+ };
142
+
143
+ // Store initial frame state
144
+ draggedShapeInitialFrameLine = currentShape.parentFrame || null;
145
+
146
+ // Temporarily remove from frame clipping if dragging
147
+ if (currentShape.parentFrame) {
148
+ currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);
149
+ }
150
+
151
+ startX = x;
152
+ startY = y;
153
+ clickedOnShape = true;
154
+ }
155
+ }
156
+
157
+ // If not clicking on selected shape, check for other shapes
158
+ if (!clickedOnShape) {
159
+ let shapeToSelect = null;
160
+ for (let i = shapes.length - 1; i >= 0; i--) {
161
+ const shape = shapes[i];
162
+ if (shape instanceof Line && shape.contains(x, y)) {
163
+ shapeToSelect = shape;
164
+ break;
165
+ }
166
+ }
167
+
168
+ if (currentShape && currentShape !== shapeToSelect) {
169
+ currentShape.removeSelection();
170
+ currentShape = null;
171
+ }
172
+
173
+ if (shapeToSelect) {
174
+ currentShape = shapeToSelect;
175
+ currentShape.selectLine();
176
+ clickedOnShape = true;
177
+ }
178
+ }
179
+
180
+ if (!clickedOnShape && currentShape) {
181
+ currentShape.removeSelection();
182
+ currentShape = null;
183
+ }
184
+ }
185
+ };
186
+ // Update clone function to remove rotation property
187
+ function cloneLineData(line) {
188
+ return {
189
+ startPoint: { x: line.startPoint.x, y: line.startPoint.y },
190
+ endPoint: { x: line.endPoint.x, y: line.endPoint.y },
191
+ controlPoint: line.controlPoint ? { x: line.controlPoint.x, y: line.controlPoint.y } : null,
192
+ isCurved: line.isCurved || false,
193
+ parentFrame: line.parentFrame,
194
+ options: cloneOptions(line.options)
195
+ };
196
+ }
197
+
198
+ const handleMouseMove = (e) => {
199
+ const { x, y } = getSVGCoordsFromMouse(e);
200
+
201
+ // Keep lastMousePos in screen coordinates for other functions
202
+ const svgRect = svg.getBoundingClientRect();
203
+ lastMousePos = {
204
+ x: e.clientX - svgRect.left,
205
+ y: e.clientY - svgRect.top
206
+ };
207
+
208
+ if (isDrawingLine && currentLine) {
209
+ let endX = x, endY = y;
210
+ if (e.shiftKey) {
211
+ const dx = x - currentLine.startPoint.x;
212
+ const dy = y - currentLine.startPoint.y;
213
+ const angle = Math.atan2(dy, dx);
214
+ const snapAngle = Math.round(angle / (Math.PI / 4)) * (Math.PI / 4);
215
+ const dist = Math.sqrt(dx * dx + dy * dy);
216
+ endX = currentLine.startPoint.x + dist * Math.cos(snapAngle);
217
+ endY = currentLine.startPoint.y + dist * Math.sin(snapAngle);
218
+ }
219
+ currentLine.endPoint = { x: endX, y: endY };
220
+ currentLine.draw();
221
+
222
+ // Check for frame containment while drawing (but don't apply clipping yet)
223
+ shapes.forEach(frame => {
224
+ if (frame.shapeName === 'frame') {
225
+ if (frame.isShapeInFrame(currentLine)) {
226
+ frame.highlightFrame();
227
+ hoveredFrameLine = frame;
228
+ } else if (hoveredFrameLine === frame) {
229
+ frame.removeHighlight();
230
+ hoveredFrameLine = null;
231
+ }
232
+ }
233
+ });
234
+ } else if (isDraggingLine && currentShape && currentShape.isSelected) {
235
+ const dx = x - startX;
236
+ const dy = y - startY;
237
+ currentShape.move(dx, dy);
238
+ startX = x;
239
+ startY = y;
240
+
241
+ // Snap guides
242
+ if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {
243
+ const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);
244
+ if (snap.dx || snap.dy) {
245
+ currentShape.move(snap.dx, snap.dy);
246
+ }
247
+ } else {
248
+ clearSnapGuides();
249
+ }
250
+ }
251
+ };
252
+
253
+ const handleMouseUp = (e) => {
254
+ if (isDrawingLine) {
255
+ isDrawingLine = false;
256
+
257
+ // Check if line is too small
258
+ const dx = currentLine.endPoint.x - currentLine.startPoint.x;
259
+ const dy = currentLine.endPoint.y - currentLine.startPoint.y;
260
+ const lengthSq = dx * dx + dy * dy;
261
+
262
+ if (lengthSq < (5 / currentZoom) ** 2) {
263
+ shapes.pop();
264
+ if (currentLine.group.parentNode) {
265
+ currentLine.group.parentNode.removeChild(currentLine.group);
266
+ }
267
+ currentLine = null;
268
+ currentShape = null;
269
+ } else {
270
+ // Finalize: apply roughness now that drawing is done
271
+ currentLine.isBeingDrawn = false;
272
+ currentLine.draw();
273
+
274
+ // Push create action for undo/redo
275
+ pushCreateAction(currentLine);
276
+
277
+ // Check for frame containment and track attachment
278
+ const finalFrame = hoveredFrameLine;
279
+ if (finalFrame) {
280
+ finalFrame.addShapeToFrame(currentLine);
281
+ // Track the attachment for undo
282
+ pushFrameAttachmentAction(finalFrame, currentLine, 'attach', null);
283
+ }
284
+
285
+ // Auto-select the drawn line and switch to selection tool
286
+ const drawnLine = currentLine;
287
+ if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });
288
+ currentShape = drawnLine;
289
+ drawnLine.selectLine();
290
+ }
291
+
292
+ // Clear frame highlighting
293
+ if (hoveredFrameLine) {
294
+ hoveredFrameLine.removeHighlight();
295
+ hoveredFrameLine = null;
296
+ }
297
+
298
+ currentLine = null;
299
+ }
300
+
301
+ if (isDraggingLine && dragOldPosLine && currentShape) {
302
+ const newPos = {
303
+ startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },
304
+ endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },
305
+ controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,
306
+ parentFrame: currentShape.parentFrame
307
+ };
308
+ const oldPos = {
309
+ ...dragOldPosLine,
310
+ parentFrame: draggedShapeInitialFrameLine
311
+ };
312
+
313
+ const stateChanged = dragOldPosLine.startPoint.x !== newPos.startPoint.x ||
314
+ dragOldPosLine.startPoint.y !== newPos.startPoint.y ||
315
+ dragOldPosLine.endPoint.x !== newPos.endPoint.x ||
316
+ dragOldPosLine.endPoint.y !== newPos.endPoint.y;
317
+
318
+ const frameChanged = oldPos.parentFrame !== newPos.parentFrame;
319
+
320
+ if (stateChanged || frameChanged) {
321
+ pushTransformAction(currentShape, oldPos, newPos);
322
+ }
323
+
324
+ // Handle frame containment changes after drag
325
+ if (isDraggingLine) {
326
+ const finalFrame = hoveredFrameLine;
327
+
328
+ // If shape moved to a different frame
329
+ if (draggedShapeInitialFrameLine !== finalFrame) {
330
+ // Remove from initial frame
331
+ if (draggedShapeInitialFrameLine) {
332
+ draggedShapeInitialFrameLine.removeShapeFromFrame(currentShape);
333
+ }
334
+
335
+ // Add to new frame
336
+ if (finalFrame) {
337
+ finalFrame.addShapeToFrame(currentShape);
338
+ }
339
+
340
+ // Track the frame change for undo
341
+ if (frameChanged) {
342
+ pushFrameAttachmentAction(finalFrame || draggedShapeInitialFrameLine, currentShape,
343
+ finalFrame ? 'attach' : 'detach', draggedShapeInitialFrameLine);
344
+ }
345
+ } else if (draggedShapeInitialFrameLine) {
346
+ // Shape stayed in same frame, restore clipping
347
+ draggedShapeInitialFrameLine.restoreToFrame(currentShape);
348
+ }
349
+ }
350
+
351
+ dragOldPosLine = null;
352
+ draggedShapeInitialFrameLine = null;
353
+ }
354
+
355
+ // Clear frame highlighting
356
+ if (hoveredFrameLine) {
357
+ hoveredFrameLine.removeHighlight();
358
+ hoveredFrameLine = null;
359
+ }
360
+
361
+ clearSnapGuides();
362
+ isDraggingLine = false;
363
+ };
364
+
365
+ // --- Event Handlers ---
366
+
367
+ // --- Style Option Event Listeners ---
368
+ lineColorOptions.forEach((span) => {
369
+ span.addEventListener("click", (event) => {
370
+ event.stopPropagation();
371
+ lineColorOptions.forEach((el) => el.classList.remove("selected"));
372
+ span.classList.add("selected");
373
+
374
+ if (currentShape instanceof Line && currentShape.isSelected) {
375
+ const oldOptions = {...currentShape.options};
376
+ currentShape.options.stroke = span.getAttribute("data-id");
377
+ currentShape.draw();
378
+ pushOptionsChangeAction(currentShape, oldOptions);
379
+ } else {
380
+ lineColor = span.getAttribute("data-id");
381
+ }
382
+ });
383
+ });
384
+
385
+ lineThicknessOptions.forEach((span) => {
386
+ span.addEventListener("click", (event) => {
387
+ event.stopPropagation();
388
+ lineThicknessOptions.forEach((el) => el.classList.remove("selected"));
389
+ span.classList.add("selected");
390
+
391
+ if (currentShape instanceof Line && currentShape.isSelected) {
392
+ const oldOptions = {...currentShape.options};
393
+ currentShape.options.strokeWidth = parseInt(span.getAttribute("data-id"));
394
+ currentShape.draw();
395
+ pushOptionsChangeAction(currentShape, oldOptions);
396
+ } else {
397
+ lineStrokeWidth = parseInt(span.getAttribute("data-id"));
398
+ }
399
+ });
400
+ });
401
+
402
+ lineOutlineOptions.forEach((span) => {
403
+ span.addEventListener("click", (event) => {
404
+ event.stopPropagation();
405
+ lineOutlineOptions.forEach((el) => el.classList.remove("selected"));
406
+ span.classList.add("selected");
407
+
408
+ if (currentShape instanceof Line && currentShape.isSelected) {
409
+ const oldOptions = {...currentShape.options};
410
+ const style = span.getAttribute("data-id");
411
+ currentShape.options.strokeDasharray =
412
+ style === "dashed" ? "5,5" :
413
+ (style === "dotted" ? "2,12" : "");
414
+ currentShape.draw();
415
+ pushOptionsChangeAction(currentShape, oldOptions);
416
+ } else {
417
+ lineStrokeStyle = span.getAttribute("data-id");
418
+ }
419
+ });
420
+ });
421
+
422
+ lineSlopeOptions.forEach((span) => {
423
+ span.addEventListener("click", (event) => {
424
+ event.stopPropagation();
425
+ lineSlopeOptions.forEach((el) => el.classList.remove("selected"));
426
+ span.classList.add("selected");
427
+
428
+ if (currentShape instanceof Line && currentShape.isSelected) {
429
+ const oldOptions = {...currentShape.options};
430
+ currentShape.options.roughness = parseFloat(span.getAttribute("data-id"));
431
+ currentShape.draw();
432
+ pushOptionsChangeAction(currentShape, oldOptions);
433
+ } else {
434
+ lineSktetchRate = parseFloat(span.getAttribute("data-id"));
435
+ }
436
+ });
437
+ });
438
+
439
+ lineEdgeOptions.forEach((span) => {
440
+ span.addEventListener("click", (event) => {
441
+ event.stopPropagation();
442
+ lineEdgeOptions.forEach((el) => el.classList.remove("selected"));
443
+ span.classList.add("selected");
444
+
445
+ if (currentShape instanceof Line && currentShape.isSelected) {
446
+ const oldOptions = {...currentShape.options};
447
+ currentShape.options.bowing = parseFloat(span.getAttribute("data-id"));
448
+ currentShape.draw();
449
+ pushOptionsChangeAction(currentShape, oldOptions);
450
+ } else {
451
+ lineEdgeType = parseFloat(span.getAttribute("data-id"));
452
+ }
453
+ });
454
+ });
455
+
456
+ // Add copy/paste functionality
457
+ function cloneOptions(options) {
458
+ return JSON.parse(JSON.stringify(options));
459
+ }
460
+
461
+ window.Line = Line;
462
+
463
+ // Bridge line tool settings to React sidebar
464
+ window.lineToolSettings = {
465
+ get strokeColor() { return lineColor; },
466
+ set strokeColor(v) { lineColor = v; },
467
+ get strokeWidth() { return lineStrokeWidth; },
468
+ set strokeWidth(v) { lineStrokeWidth = v; },
469
+ get strokeStyle() { return lineStrokeStyle; },
470
+ set strokeStyle(v) { lineStrokeStyle = v; },
471
+ get sloppiness() { return lineSktetchRate; },
472
+ set sloppiness(v) { lineSktetchRate = v; },
473
+ get edge() { return lineEdgeType; },
474
+ set edge(v) { lineEdgeType = v; },
475
+ };
476
+ window.updateSelectedLineStyle = function(changes) {
477
+ if (currentShape instanceof Line && currentShape.isSelected) {
478
+ const oldOptions = {...currentShape.options};
479
+ if (changes.stroke !== undefined) { lineColor = changes.stroke; currentShape.options.stroke = changes.stroke; }
480
+ if (changes.strokeWidth !== undefined) { lineStrokeWidth = changes.strokeWidth; currentShape.options.strokeWidth = changes.strokeWidth; }
481
+ if (changes.strokeStyle !== undefined) {
482
+ lineStrokeStyle = changes.strokeStyle;
483
+ currentShape.options.strokeDasharray = changes.strokeStyle === "dashed" ? "5,5" : (changes.strokeStyle === "dotted" ? "2,12" : "");
484
+ }
485
+ if (changes.sloppiness !== undefined) { lineSktetchRate = changes.sloppiness; currentShape.options.roughness = changes.sloppiness; }
486
+ if (changes.edge !== undefined) { lineEdgeType = changes.edge; currentShape.options.bowing = changes.edge; }
487
+ currentShape.draw();
488
+ pushOptionsChangeAction(currentShape, oldOptions);
489
+ } else {
490
+ if (changes.stroke !== undefined) lineColor = changes.stroke;
491
+ if (changes.strokeWidth !== undefined) lineStrokeWidth = changes.strokeWidth;
492
+ if (changes.strokeStyle !== undefined) lineStrokeStyle = changes.strokeStyle;
493
+ if (changes.sloppiness !== undefined) lineSktetchRate = changes.sloppiness;
494
+ if (changes.edge !== undefined) lineEdgeType = changes.edge;
495
+ }
496
+ };
497
+
498
+ export {
499
+ handleMouseDown as handleMouseDownLine,
500
+ handleMouseMove as handleMouseMoveLine,
501
+ handleMouseUp as handleMouseUpLine,
502
+ };