@tsdraw/core 0.8.0 → 0.8.2

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 CHANGED
@@ -603,6 +603,7 @@ var ToolManager = class {
603
603
  getCurrentState() {
604
604
  return this.currentState;
605
605
  }
606
+ // Transition between states within the same tool (ex. pen_idle -> pen_drawing)
606
607
  transition(stateId, info) {
607
608
  const next = this.states.get(stateId);
608
609
  if (!next) return;
@@ -1129,6 +1130,7 @@ var GeometricDrawingState = class extends StateNode {
1129
1130
  });
1130
1131
  this.currentShapeId = nextShapeId;
1131
1132
  }
1133
+ // Shift key switches between constrained and unconstrained bounds
1132
1134
  onPointerMove() {
1133
1135
  const activeShape = this.getActiveShape();
1134
1136
  if (!activeShape) return;
@@ -1162,6 +1164,9 @@ var GeometricDrawingState = class extends StateNode {
1162
1164
  onKeyUp() {
1163
1165
  this.onPointerMove();
1164
1166
  }
1167
+ // If user dragged, use the drag extents for the final shape
1168
+ // If they just clicked without dragging, use default-sized shape
1169
+ // If they dragged just a bit (most likely a click), remove the shape and go back to idle
1165
1170
  completeShape() {
1166
1171
  const activeShape = this.getActiveShape();
1167
1172
  const config = this.getConfig();
@@ -1171,7 +1176,15 @@ var GeometricDrawingState = class extends StateNode {
1171
1176
  }
1172
1177
  const originPoint = this.editor.input.getOriginPagePoint();
1173
1178
  const cursorPoint = this.editor.input.getCurrentPagePoint();
1174
- const finalizedBounds = this.editor.input.getIsDragging() ? this.editor.input.getShiftKey() ? config.buildConstrainedBounds(originPoint.x, originPoint.y, cursorPoint.x, cursorPoint.y) : config.buildUnconstrainedBounds(originPoint.x, originPoint.y, cursorPoint.x, cursorPoint.y) : config.buildDefaultBounds(originPoint.x, originPoint.y);
1179
+ const dx = cursorPoint.x - originPoint.x;
1180
+ const dy = cursorPoint.y - originPoint.y;
1181
+ const draggedFarEnough = dx * dx + dy * dy > this.editor.options.dragDistanceSquared;
1182
+ if (!draggedFarEnough) {
1183
+ this.removeCurrentShape();
1184
+ this.ctx.transition(config.idleStateId, this.startedAt);
1185
+ return;
1186
+ }
1187
+ const finalizedBounds = this.editor.input.getShiftKey() ? config.buildConstrainedBounds(originPoint.x, originPoint.y, cursorPoint.x, cursorPoint.y) : config.buildUnconstrainedBounds(originPoint.x, originPoint.y, cursorPoint.x, cursorPoint.y);
1175
1188
  this.editor.store.updateShape(activeShape.id, {
1176
1189
  x: finalizedBounds.x,
1177
1190
  y: finalizedBounds.y,
@@ -1201,10 +1214,6 @@ var GeometricDrawingState = class extends StateNode {
1201
1214
 
1202
1215
  // src/tools/geometric/geometricShapeHelpers.ts
1203
1216
  var MIN_SIDE_LENGTH = 1;
1204
- var DEFAULT_RECTANGLE_WIDTH = 180;
1205
- var DEFAULT_RECTANGLE_HEIGHT = 120;
1206
- var DEFAULT_ELLIPSE_WIDTH = 180;
1207
- var DEFAULT_ELLIPSE_HEIGHT = 120;
1208
1217
  function toSizedBounds(anchorX, anchorY, cursorX, cursorY, forceEqualSides) {
1209
1218
  const rawDeltaX = cursorX - anchorX;
1210
1219
  const rawDeltaY = cursorY - anchorY;
@@ -1229,16 +1238,6 @@ function buildSquareBounds(anchorX, anchorY, cursorX, cursorY) {
1229
1238
  function buildRectangleBounds(anchorX, anchorY, cursorX, cursorY) {
1230
1239
  return toSizedBounds(anchorX, anchorY, cursorX, cursorY, false);
1231
1240
  }
1232
- function buildDefaultCenteredRectangleBounds(centerX, centerY) {
1233
- const halfWidth = DEFAULT_RECTANGLE_WIDTH / 2;
1234
- const halfHeight = DEFAULT_RECTANGLE_HEIGHT / 2;
1235
- return {
1236
- x: centerX - halfWidth,
1237
- y: centerY - halfHeight,
1238
- width: DEFAULT_RECTANGLE_WIDTH,
1239
- height: DEFAULT_RECTANGLE_HEIGHT
1240
- };
1241
- }
1242
1241
  function buildRectangleSegments(width, height) {
1243
1242
  const topLeft = { x: 0, y: 0, z: 0.5 };
1244
1243
  const topRight = { x: width, y: 0, z: 0.5 };
@@ -1257,16 +1256,6 @@ function buildCircleBounds(anchorX, anchorY, cursorX, cursorY) {
1257
1256
  function buildEllipseBounds(anchorX, anchorY, cursorX, cursorY) {
1258
1257
  return toSizedBounds(anchorX, anchorY, cursorX, cursorY, false);
1259
1258
  }
1260
- function buildDefaultCenteredEllipseBounds(centerX, centerY) {
1261
- const halfWidth = DEFAULT_ELLIPSE_WIDTH / 2;
1262
- const halfHeight = DEFAULT_ELLIPSE_HEIGHT / 2;
1263
- return {
1264
- x: centerX - halfWidth,
1265
- y: centerY - halfHeight,
1266
- width: DEFAULT_ELLIPSE_WIDTH,
1267
- height: DEFAULT_ELLIPSE_HEIGHT
1268
- };
1269
- }
1270
1259
  function buildEllipseSegments(width, height) {
1271
1260
  const centerX = width / 2;
1272
1261
  const centerY = height / 2;
@@ -1294,7 +1283,6 @@ var SquareDrawingState = class extends GeometricDrawingState {
1294
1283
  idleStateId: "square_idle",
1295
1284
  buildConstrainedBounds: buildSquareBounds,
1296
1285
  buildUnconstrainedBounds: buildRectangleBounds,
1297
- buildDefaultBounds: buildDefaultCenteredRectangleBounds,
1298
1286
  buildSegments: buildRectangleSegments
1299
1287
  };
1300
1288
  }
@@ -1316,7 +1304,6 @@ var CircleDrawingState = class extends GeometricDrawingState {
1316
1304
  idleStateId: "circle_idle",
1317
1305
  buildConstrainedBounds: buildCircleBounds,
1318
1306
  buildUnconstrainedBounds: buildEllipseBounds,
1319
- buildDefaultBounds: buildDefaultCenteredEllipseBounds,
1320
1307
  buildSegments: buildEllipseSegments
1321
1308
  };
1322
1309
  }
@@ -1482,6 +1469,8 @@ var EraserErasingState = class extends StateNode {
1482
1469
  onCancel() {
1483
1470
  this.ctx.transition("eraser_idle");
1484
1471
  }
1472
+ // On every pointer move, test the line from previous pointer position to current one against nearby shapes
1473
+ // Only select shapes whose bounding box overlaps the sweep area to avoid testing all shapes
1485
1474
  sweep() {
1486
1475
  const zoom = this.editor.getZoomLevel();
1487
1476
  const tolerance = ERASER_MARGIN / zoom;
@@ -1500,6 +1489,7 @@ var EraserErasingState = class extends StateNode {
1500
1489
  this._marked = [...hitIds];
1501
1490
  this.editor.setErasingShapes(this._marked);
1502
1491
  }
1492
+ // Delete marked shapes and reset, then go back to idle
1503
1493
  finish() {
1504
1494
  const ids = this.editor.getErasingShapeIds();
1505
1495
  if (ids.length > 0) {