@tldraw/driver 5.3.2 → 5.4.0-canary.02cd0bd3b597
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-cjs/index.d.ts +14 -18
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/Driver.js +61 -93
- package/dist-cjs/lib/Driver.js.map +2 -2
- package/dist-esm/index.d.mts +14 -18
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/Driver.mjs +61 -93
- package/dist-esm/lib/Driver.mjs.map +2 -2
- package/package.json +3 -3
- package/src/lib/Driver.ts +75 -115
package/dist-esm/index.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ import { SelectionHandle } from '@tldraw/editor';
|
|
|
4
4
|
import { TLArrowShape } from '@tldraw/editor';
|
|
5
5
|
import { TLContent } from '@tldraw/editor';
|
|
6
6
|
import { TLKeyboardEventInfo } from '@tldraw/editor';
|
|
7
|
-
import { TLPageId } from '@tldraw/
|
|
7
|
+
import { TLPageId } from '@tldraw/tlschema';
|
|
8
8
|
import { TLPinchEventInfo } from '@tldraw/editor';
|
|
9
9
|
import { TLPointerEventInfo } from '@tldraw/editor';
|
|
10
10
|
import { TLShape } from '@tldraw/editor';
|
|
@@ -25,12 +25,12 @@ export declare class Driver {
|
|
|
25
25
|
readonly editor: Editor;
|
|
26
26
|
/** The underlying Editor instance. */
|
|
27
27
|
private _cleanup;
|
|
28
|
+
private _lastCreatedShapes;
|
|
28
29
|
constructor(editor: Editor);
|
|
29
30
|
/** Remove all registered side-effect handlers. Call when this controller is no longer needed. */
|
|
30
31
|
dispose(): void;
|
|
31
32
|
/** Local clipboard content. Used by copy, cut, and paste. */
|
|
32
33
|
clipboard: null | TLContent;
|
|
33
|
-
private _lastCreatedShapes;
|
|
34
34
|
/**
|
|
35
35
|
* Get the last created shapes.
|
|
36
36
|
* @param count - The number of shapes to get.
|
|
@@ -89,6 +89,7 @@ export declare class Driver {
|
|
|
89
89
|
* @param shapeId - The shape ID to find arrows bound to.
|
|
90
90
|
*/
|
|
91
91
|
getArrowsBoundTo(shapeId: TLShapeId): TLArrowShape[];
|
|
92
|
+
private getModifierKeys;
|
|
92
93
|
/**
|
|
93
94
|
* Builds a TLPointerEventInfo object for input simulation.
|
|
94
95
|
* @param x - Screen x coordinate. Defaults to current pointer.
|
|
@@ -162,37 +163,38 @@ export declare class Driver {
|
|
|
162
163
|
* @param key - The key to press (e.g. 'a', 'Enter', 'Shift').
|
|
163
164
|
* @param options - Partial keyboard event overrides.
|
|
164
165
|
*/
|
|
165
|
-
keyPress(key: string, options?: Partial<Omit<TLKeyboardEventInfo,
|
|
166
|
+
keyPress(key: string, options?: Partial<Omit<TLKeyboardEventInfo, 'key'>>): this;
|
|
166
167
|
/**
|
|
167
168
|
* Dispatches a key down event for the given key.
|
|
168
169
|
* @param key - The key to press (e.g. 'a', 'Enter', 'Shift').
|
|
169
170
|
* @param options - Partial keyboard event overrides.
|
|
170
171
|
*/
|
|
171
|
-
keyDown(key: string, options?: Partial<Omit<TLKeyboardEventInfo,
|
|
172
|
+
keyDown(key: string, options?: Partial<Omit<TLKeyboardEventInfo, 'key'>>): this;
|
|
172
173
|
/**
|
|
173
174
|
* Dispatches a key repeat event for the given key.
|
|
174
175
|
* @param key - The key that is repeating (e.g. 'a', 'ArrowDown').
|
|
175
176
|
* @param options - Partial keyboard event overrides.
|
|
176
177
|
*/
|
|
177
|
-
keyRepeat(key: string, options?: Partial<Omit<TLKeyboardEventInfo,
|
|
178
|
+
keyRepeat(key: string, options?: Partial<Omit<TLKeyboardEventInfo, 'key'>>): this;
|
|
178
179
|
/**
|
|
179
180
|
* Dispatches a key up event for the given key.
|
|
180
181
|
* @param key - The key to release (e.g. 'a', 'Enter', 'Shift').
|
|
181
182
|
* @param options - Partial keyboard event overrides.
|
|
182
183
|
*/
|
|
183
|
-
keyUp(key: string, options?: Partial<Omit<TLKeyboardEventInfo,
|
|
184
|
+
keyUp(key: string, options?: Partial<Omit<TLKeyboardEventInfo, 'key'>>): this;
|
|
184
185
|
/**
|
|
185
186
|
* Dispatches a wheel event with the given delta values.
|
|
186
187
|
* @param dx - Horizontal scroll delta.
|
|
187
188
|
* @param dy - Vertical scroll delta.
|
|
188
189
|
* @param options - Partial wheel event overrides.
|
|
189
190
|
*/
|
|
190
|
-
wheel(dx: number, dy: number, options?: Partial<Omit<TLWheelEventInfo,
|
|
191
|
+
wheel(dx: number, dy: number, options?: Partial<Omit<TLWheelEventInfo, 'delta'>>): this;
|
|
191
192
|
/**
|
|
192
193
|
* Pans the camera by the given offset (in page coordinates). Does nothing if camera is locked.
|
|
193
194
|
* @param offset - The pan delta (x, y) in page coordinates.
|
|
194
195
|
*/
|
|
195
196
|
pan(offset: VecLike): this;
|
|
197
|
+
private pinch;
|
|
196
198
|
/**
|
|
197
199
|
* Dispatches a pinch start event.
|
|
198
200
|
* @param x - Screen x coordinate. Defaults to current pointer.
|
|
@@ -203,7 +205,7 @@ export declare class Driver {
|
|
|
203
205
|
* @param dz - Delta z for pinch.
|
|
204
206
|
* @param options - Partial pinch event overrides.
|
|
205
207
|
*/
|
|
206
|
-
pinchStart(x: number | undefined, y: number | undefined, z: number, dx: number, dy: number, dz: number, options?: Partial<Omit<TLPinchEventInfo,
|
|
208
|
+
pinchStart(x: number | undefined, y: number | undefined, z: number, dx: number, dy: number, dz: number, options?: Partial<Omit<TLPinchEventInfo, 'delta' | 'offset' | 'point'>>): this;
|
|
207
209
|
/**
|
|
208
210
|
* Dispatches a pinch move event (pinch_to).
|
|
209
211
|
* @param x - Screen x coordinate. Defaults to current pointer.
|
|
@@ -214,7 +216,7 @@ export declare class Driver {
|
|
|
214
216
|
* @param dz - Delta z for pinch.
|
|
215
217
|
* @param options - Partial pinch event overrides.
|
|
216
218
|
*/
|
|
217
|
-
pinchTo(x: number | undefined, y: number | undefined, z: number, dx: number, dy: number, dz: number, options?: Partial<Omit<TLPinchEventInfo,
|
|
219
|
+
pinchTo(x: number | undefined, y: number | undefined, z: number, dx: number, dy: number, dz: number, options?: Partial<Omit<TLPinchEventInfo, 'delta' | 'offset' | 'point'>>): this;
|
|
218
220
|
/**
|
|
219
221
|
* Dispatches a pinch end event.
|
|
220
222
|
* @param x - Screen x coordinate. Defaults to current pointer.
|
|
@@ -225,13 +227,7 @@ export declare class Driver {
|
|
|
225
227
|
* @param dz - Delta z for pinch.
|
|
226
228
|
* @param options - Partial pinch event overrides.
|
|
227
229
|
*/
|
|
228
|
-
pinchEnd(x: number | undefined, y: number | undefined, z: number, dx: number, dy: number, dz: number, options?: Partial<Omit<TLPinchEventInfo,
|
|
229
|
-
/**
|
|
230
|
-
* Converts a point from page coordinates to screen coordinates.
|
|
231
|
-
* Pointer events operate in screen space, so page-space points must be
|
|
232
|
-
* converted before being passed to pointerDown/Move/Up.
|
|
233
|
-
*/
|
|
234
|
-
private pageToScreen;
|
|
230
|
+
pinchEnd(x: number | undefined, y: number | undefined, z: number, dx: number, dy: number, dz: number, options?: Partial<Omit<TLPinchEventInfo, 'delta' | 'offset' | 'point'>>): this;
|
|
235
231
|
/**
|
|
236
232
|
* Simulates rotating the current selection by the given angle in radians via the rotation handle.
|
|
237
233
|
* @param angleRadians - Rotation angle in radians.
|
|
@@ -255,8 +251,8 @@ export declare class Driver {
|
|
|
255
251
|
* @param options - Partial pointer event overrides (e.g. altKey to scale from center).
|
|
256
252
|
*/
|
|
257
253
|
resizeSelection(scale: {
|
|
258
|
-
scaleX?: number
|
|
259
|
-
scaleY?: number
|
|
254
|
+
scaleX?: number;
|
|
255
|
+
scaleY?: number;
|
|
260
256
|
} | undefined, handle: SelectionHandle, options?: Partial<TLPointerEventInfo>): this;
|
|
261
257
|
}
|
|
262
258
|
|
package/dist-esm/index.mjs
CHANGED
package/dist-esm/lib/Driver.mjs
CHANGED
|
@@ -9,6 +9,18 @@ import {
|
|
|
9
9
|
rotateSelectionHandle,
|
|
10
10
|
tlenv
|
|
11
11
|
} from "@tldraw/editor";
|
|
12
|
+
const KEY_CODES = {
|
|
13
|
+
Shift: "ShiftLeft",
|
|
14
|
+
Alt: "AltLeft",
|
|
15
|
+
Control: "CtrlLeft",
|
|
16
|
+
Meta: "MetaLeft",
|
|
17
|
+
" ": "Space",
|
|
18
|
+
Enter: "Enter",
|
|
19
|
+
ArrowRight: "ArrowRight",
|
|
20
|
+
ArrowLeft: "ArrowLeft",
|
|
21
|
+
ArrowUp: "ArrowUp",
|
|
22
|
+
ArrowDown: "ArrowDown"
|
|
23
|
+
};
|
|
12
24
|
class Driver {
|
|
13
25
|
constructor(editor) {
|
|
14
26
|
this.editor = editor;
|
|
@@ -21,7 +33,8 @@ class Driver {
|
|
|
21
33
|
}
|
|
22
34
|
editor;
|
|
23
35
|
/** The underlying Editor instance. */
|
|
24
|
-
_cleanup
|
|
36
|
+
_cleanup;
|
|
37
|
+
_lastCreatedShapes = [];
|
|
25
38
|
/** Remove all registered side-effect handlers. Call when this controller is no longer needed. */
|
|
26
39
|
dispose() {
|
|
27
40
|
this._cleanup?.();
|
|
@@ -29,7 +42,6 @@ class Driver {
|
|
|
29
42
|
}
|
|
30
43
|
/** Local clipboard content. Used by copy, cut, and paste. */
|
|
31
44
|
clipboard = null;
|
|
32
|
-
_lastCreatedShapes = [];
|
|
33
45
|
/**
|
|
34
46
|
* Get the last created shapes.
|
|
35
47
|
* @param count - The number of shapes to get.
|
|
@@ -79,10 +91,7 @@ class Driver {
|
|
|
79
91
|
*/
|
|
80
92
|
cut(ids = this.editor.getSelectedShapeIds()) {
|
|
81
93
|
if (ids.length > 0) {
|
|
82
|
-
|
|
83
|
-
if (content) {
|
|
84
|
-
this.clipboard = content;
|
|
85
|
-
}
|
|
94
|
+
this.copy(ids);
|
|
86
95
|
this.editor.deleteShapes(ids);
|
|
87
96
|
}
|
|
88
97
|
return this;
|
|
@@ -130,10 +139,7 @@ class Driver {
|
|
|
130
139
|
*/
|
|
131
140
|
getPageRotationById(id) {
|
|
132
141
|
const pageTransform = this.editor.getShapePageTransform(id);
|
|
133
|
-
|
|
134
|
-
return Mat.Decompose(pageTransform).rotation;
|
|
135
|
-
}
|
|
136
|
-
return 0;
|
|
142
|
+
return pageTransform ? pageTransform.rotation() : 0;
|
|
137
143
|
}
|
|
138
144
|
/**
|
|
139
145
|
* Returns the rotation of a shape in page space, in radians.
|
|
@@ -151,6 +157,16 @@ class Driver {
|
|
|
151
157
|
return compact(Array.from(ids, (id) => this.editor.getShape(id)));
|
|
152
158
|
}
|
|
153
159
|
/* --------------- Event building --------------- */
|
|
160
|
+
getModifierKeys() {
|
|
161
|
+
const { inputs } = this.editor;
|
|
162
|
+
return {
|
|
163
|
+
shiftKey: inputs.getShiftKey(),
|
|
164
|
+
ctrlKey: inputs.getCtrlKey(),
|
|
165
|
+
altKey: inputs.getAltKey(),
|
|
166
|
+
metaKey: inputs.getMetaKey(),
|
|
167
|
+
accelKey: isAccelKey(inputs)
|
|
168
|
+
};
|
|
169
|
+
}
|
|
154
170
|
/**
|
|
155
171
|
* Builds a TLPointerEventInfo object for input simulation.
|
|
156
172
|
* @param x - Screen x coordinate. Defaults to current pointer.
|
|
@@ -168,10 +184,7 @@ class Driver {
|
|
|
168
184
|
name: "pointer_down",
|
|
169
185
|
type: "pointer",
|
|
170
186
|
pointerId: 1,
|
|
171
|
-
|
|
172
|
-
ctrlKey: this.editor.inputs.getCtrlKey(),
|
|
173
|
-
altKey: this.editor.inputs.getAltKey(),
|
|
174
|
-
metaKey: this.editor.inputs.getMetaKey(),
|
|
187
|
+
...this.getModifierKeys(),
|
|
175
188
|
accelKey: isAccelKey({ ...this.editor.inputs.toJson(), ...modifiers }),
|
|
176
189
|
point: { x, y, z: null },
|
|
177
190
|
button: 0,
|
|
@@ -201,9 +214,9 @@ class Driver {
|
|
|
201
214
|
};
|
|
202
215
|
return {
|
|
203
216
|
...flags,
|
|
204
|
-
accelKey: flags.accelKey ?? (
|
|
217
|
+
accelKey: flags.accelKey ?? isAccelKey(flags),
|
|
205
218
|
name,
|
|
206
|
-
code: key
|
|
219
|
+
code: KEY_CODES[key] ?? "Key" + key[0].toUpperCase() + key.slice(1),
|
|
207
220
|
type: "keyboard",
|
|
208
221
|
key
|
|
209
222
|
};
|
|
@@ -306,8 +319,7 @@ class Driver {
|
|
|
306
319
|
* @param modifiers - Override shift, ctrl, or alt key state.
|
|
307
320
|
*/
|
|
308
321
|
doubleClick(x = this.editor.inputs.getCurrentScreenPoint().x, y = this.editor.inputs.getCurrentScreenPoint().y, options, modifiers) {
|
|
309
|
-
this.
|
|
310
|
-
this.pointerUp(x, y, options, modifiers);
|
|
322
|
+
this.click(x, y, options, modifiers);
|
|
311
323
|
this.editor.dispatch({
|
|
312
324
|
...this.getPointerEventInfo(x, y, options, modifiers),
|
|
313
325
|
type: "click",
|
|
@@ -339,7 +351,7 @@ class Driver {
|
|
|
339
351
|
* @param options - Partial keyboard event overrides.
|
|
340
352
|
*/
|
|
341
353
|
keyDown(key, options = {}) {
|
|
342
|
-
this.editor.dispatch(
|
|
354
|
+
this.editor.dispatch(this.getKeyboardEventInfo(key, "key_down", options));
|
|
343
355
|
this.forceTick();
|
|
344
356
|
return this;
|
|
345
357
|
}
|
|
@@ -349,7 +361,7 @@ class Driver {
|
|
|
349
361
|
* @param options - Partial keyboard event overrides.
|
|
350
362
|
*/
|
|
351
363
|
keyRepeat(key, options = {}) {
|
|
352
|
-
this.editor.dispatch(
|
|
364
|
+
this.editor.dispatch(this.getKeyboardEventInfo(key, "key_repeat", options));
|
|
353
365
|
this.forceTick();
|
|
354
366
|
return this;
|
|
355
367
|
}
|
|
@@ -359,15 +371,15 @@ class Driver {
|
|
|
359
371
|
* @param options - Partial keyboard event overrides.
|
|
360
372
|
*/
|
|
361
373
|
keyUp(key, options = {}) {
|
|
362
|
-
this.editor.dispatch(
|
|
363
|
-
|
|
374
|
+
this.editor.dispatch(
|
|
375
|
+
this.getKeyboardEventInfo(key, "key_up", {
|
|
364
376
|
shiftKey: this.editor.inputs.getShiftKey() && key !== "Shift",
|
|
365
377
|
ctrlKey: this.editor.inputs.getCtrlKey() && !(key === "Control" || key === "Meta"),
|
|
366
378
|
altKey: this.editor.inputs.getAltKey() && key !== "Alt",
|
|
367
379
|
metaKey: this.editor.inputs.getMetaKey() && key !== "Meta",
|
|
368
380
|
...options
|
|
369
381
|
})
|
|
370
|
-
|
|
382
|
+
);
|
|
371
383
|
this.forceTick();
|
|
372
384
|
return this;
|
|
373
385
|
}
|
|
@@ -383,11 +395,7 @@ class Driver {
|
|
|
383
395
|
type: "wheel",
|
|
384
396
|
name: "wheel",
|
|
385
397
|
point: new Vec(currentScreenPoint.x, currentScreenPoint.y),
|
|
386
|
-
|
|
387
|
-
ctrlKey: this.editor.inputs.getCtrlKey(),
|
|
388
|
-
altKey: this.editor.inputs.getAltKey(),
|
|
389
|
-
metaKey: this.editor.inputs.getMetaKey(),
|
|
390
|
-
accelKey: isAccelKey(this.editor.inputs),
|
|
398
|
+
...this.getModifierKeys(),
|
|
391
399
|
...options,
|
|
392
400
|
delta: { x: dx, y: dy }
|
|
393
401
|
});
|
|
@@ -408,6 +416,16 @@ class Driver {
|
|
|
408
416
|
);
|
|
409
417
|
return this;
|
|
410
418
|
}
|
|
419
|
+
pinch(name, x, y, z, dx, dy, dz, options) {
|
|
420
|
+
this.editor.dispatch({
|
|
421
|
+
type: "pinch",
|
|
422
|
+
name,
|
|
423
|
+
...this.getModifierKeys(),
|
|
424
|
+
...options,
|
|
425
|
+
point: { x, y, z },
|
|
426
|
+
delta: { x: dx, y: dy, z: dz }
|
|
427
|
+
});
|
|
428
|
+
}
|
|
411
429
|
/**
|
|
412
430
|
* Dispatches a pinch start event.
|
|
413
431
|
* @param x - Screen x coordinate. Defaults to current pointer.
|
|
@@ -419,18 +437,7 @@ class Driver {
|
|
|
419
437
|
* @param options - Partial pinch event overrides.
|
|
420
438
|
*/
|
|
421
439
|
pinchStart(x = this.editor.inputs.getCurrentScreenPoint().x, y = this.editor.inputs.getCurrentScreenPoint().y, z, dx, dy, dz, options = {}) {
|
|
422
|
-
this.
|
|
423
|
-
type: "pinch",
|
|
424
|
-
name: "pinch_start",
|
|
425
|
-
shiftKey: this.editor.inputs.getShiftKey(),
|
|
426
|
-
ctrlKey: this.editor.inputs.getCtrlKey(),
|
|
427
|
-
altKey: this.editor.inputs.getAltKey(),
|
|
428
|
-
metaKey: this.editor.inputs.getMetaKey(),
|
|
429
|
-
accelKey: isAccelKey(this.editor.inputs),
|
|
430
|
-
...options,
|
|
431
|
-
point: { x, y, z },
|
|
432
|
-
delta: { x: dx, y: dy, z: dz }
|
|
433
|
-
});
|
|
440
|
+
this.pinch("pinch_start", x, y, z, dx, dy, dz, options);
|
|
434
441
|
this.forceTick();
|
|
435
442
|
return this;
|
|
436
443
|
}
|
|
@@ -445,18 +452,7 @@ class Driver {
|
|
|
445
452
|
* @param options - Partial pinch event overrides.
|
|
446
453
|
*/
|
|
447
454
|
pinchTo(x = this.editor.inputs.getCurrentScreenPoint().x, y = this.editor.inputs.getCurrentScreenPoint().y, z, dx, dy, dz, options = {}) {
|
|
448
|
-
this.
|
|
449
|
-
type: "pinch",
|
|
450
|
-
name: "pinch",
|
|
451
|
-
shiftKey: this.editor.inputs.getShiftKey(),
|
|
452
|
-
ctrlKey: this.editor.inputs.getCtrlKey(),
|
|
453
|
-
altKey: this.editor.inputs.getAltKey(),
|
|
454
|
-
metaKey: this.editor.inputs.getMetaKey(),
|
|
455
|
-
accelKey: isAccelKey(this.editor.inputs),
|
|
456
|
-
...options,
|
|
457
|
-
point: { x, y, z },
|
|
458
|
-
delta: { x: dx, y: dy, z: dz }
|
|
459
|
-
});
|
|
455
|
+
this.pinch("pinch", x, y, z, dx, dy, dz, options);
|
|
460
456
|
return this;
|
|
461
457
|
}
|
|
462
458
|
/**
|
|
@@ -470,30 +466,11 @@ class Driver {
|
|
|
470
466
|
* @param options - Partial pinch event overrides.
|
|
471
467
|
*/
|
|
472
468
|
pinchEnd(x = this.editor.inputs.getCurrentScreenPoint().x, y = this.editor.inputs.getCurrentScreenPoint().y, z, dx, dy, dz, options = {}) {
|
|
473
|
-
this.
|
|
474
|
-
type: "pinch",
|
|
475
|
-
name: "pinch_end",
|
|
476
|
-
shiftKey: this.editor.inputs.getShiftKey(),
|
|
477
|
-
ctrlKey: this.editor.inputs.getCtrlKey(),
|
|
478
|
-
altKey: this.editor.inputs.getAltKey(),
|
|
479
|
-
metaKey: this.editor.inputs.getMetaKey(),
|
|
480
|
-
accelKey: isAccelKey(this.editor.inputs),
|
|
481
|
-
...options,
|
|
482
|
-
point: { x, y, z },
|
|
483
|
-
delta: { x: dx, y: dy, z: dz }
|
|
484
|
-
});
|
|
469
|
+
this.pinch("pinch_end", x, y, z, dx, dy, dz, options);
|
|
485
470
|
this.forceTick();
|
|
486
471
|
return this;
|
|
487
472
|
}
|
|
488
473
|
/* --------------- Interaction helpers --------------- */
|
|
489
|
-
/**
|
|
490
|
-
* Converts a point from page coordinates to screen coordinates.
|
|
491
|
-
* Pointer events operate in screen space, so page-space points must be
|
|
492
|
-
* converted before being passed to pointerDown/Move/Up.
|
|
493
|
-
*/
|
|
494
|
-
pageToScreen(point) {
|
|
495
|
-
return this.editor.pageToScreen(point);
|
|
496
|
-
}
|
|
497
474
|
/**
|
|
498
475
|
* Simulates rotating the current selection by the given angle in radians via the rotation handle.
|
|
499
476
|
* @param angleRadians - Rotation angle in radians.
|
|
@@ -505,13 +482,11 @@ class Driver {
|
|
|
505
482
|
throw new Error("No selection");
|
|
506
483
|
}
|
|
507
484
|
this.editor.setCurrentTool("select");
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
this.editor.getSelectionRotation()
|
|
511
|
-
);
|
|
485
|
+
const bounds = this.editor.getSelectionRotatedPageBounds();
|
|
486
|
+
const handlePoint = bounds.getHandlePoint(ROTATE_CORNER_TO_SELECTION_CORNER[handle]).clone().rotWith(bounds.point, this.editor.getSelectionRotation());
|
|
512
487
|
const targetHandlePoint = Vec.RotWith(handlePoint, this.getSelectionPageCenter(), angleRadians);
|
|
513
|
-
const screenHandle = this.pageToScreen(handlePoint);
|
|
514
|
-
const screenTarget = this.pageToScreen(targetHandlePoint);
|
|
488
|
+
const screenHandle = this.editor.pageToScreen(handlePoint);
|
|
489
|
+
const screenTarget = this.editor.pageToScreen(targetHandlePoint);
|
|
515
490
|
this.pointerDown(screenHandle.x, screenHandle.y, { target: "selection", handle });
|
|
516
491
|
this.pointerMove(screenTarget.x, screenTarget.y, { shiftKey });
|
|
517
492
|
this.pointerUp();
|
|
@@ -529,17 +504,17 @@ class Driver {
|
|
|
529
504
|
}
|
|
530
505
|
this.editor.setCurrentTool("select");
|
|
531
506
|
const center = this.getSelectionPageCenter();
|
|
532
|
-
const screenCenter = this.pageToScreen(center);
|
|
507
|
+
const screenCenter = this.editor.pageToScreen(center);
|
|
533
508
|
this.pointerDown(screenCenter.x, screenCenter.y, this.editor.getSelectedShapeIds()[0]);
|
|
534
509
|
const numSteps = 10;
|
|
535
510
|
for (let i = 1; i < numSteps; i++) {
|
|
536
|
-
const p = this.pageToScreen({
|
|
511
|
+
const p = this.editor.pageToScreen({
|
|
537
512
|
x: center.x + i * dx / numSteps,
|
|
538
513
|
y: center.y + i * dy / numSteps
|
|
539
514
|
});
|
|
540
515
|
this.pointerMove(p.x, p.y, options);
|
|
541
516
|
}
|
|
542
|
-
const endScreen = this.pageToScreen({ x: center.x + dx, y: center.y + dy });
|
|
517
|
+
const endScreen = this.editor.pageToScreen({ x: center.x + dx, y: center.y + dy });
|
|
543
518
|
this.pointerUp(endScreen.x, endScreen.y, options);
|
|
544
519
|
return this;
|
|
545
520
|
}
|
|
@@ -556,6 +531,7 @@ class Driver {
|
|
|
556
531
|
}
|
|
557
532
|
this.editor.setCurrentTool("select");
|
|
558
533
|
const bounds = this.editor.getSelectionRotatedPageBounds();
|
|
534
|
+
const rotation = this.editor.getSelectionRotation();
|
|
559
535
|
const preRotationHandlePoint = bounds.getHandlePoint(handle);
|
|
560
536
|
const preRotationScaleOriginPoint = options?.altKey ? bounds.center : bounds.getHandlePoint(rotateSelectionHandle(handle, Math.PI));
|
|
561
537
|
const preRotationTargetHandlePoint = Vec.Add(
|
|
@@ -565,18 +541,10 @@ class Driver {
|
|
|
565
541
|
}),
|
|
566
542
|
preRotationScaleOriginPoint
|
|
567
543
|
);
|
|
568
|
-
const handlePoint = Vec.RotWith(
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
);
|
|
573
|
-
const targetHandlePoint = Vec.RotWith(
|
|
574
|
-
preRotationTargetHandlePoint,
|
|
575
|
-
bounds.point,
|
|
576
|
-
this.editor.getSelectionRotation()
|
|
577
|
-
);
|
|
578
|
-
const screenHandle = this.pageToScreen(handlePoint);
|
|
579
|
-
const screenTarget = this.pageToScreen(targetHandlePoint);
|
|
544
|
+
const handlePoint = Vec.RotWith(preRotationHandlePoint, bounds.point, rotation);
|
|
545
|
+
const targetHandlePoint = Vec.RotWith(preRotationTargetHandlePoint, bounds.point, rotation);
|
|
546
|
+
const screenHandle = this.editor.pageToScreen(handlePoint);
|
|
547
|
+
const screenTarget = this.editor.pageToScreen(targetHandlePoint);
|
|
580
548
|
this.pointerDown(screenHandle.x, screenHandle.y, { target: "selection", handle }, options);
|
|
581
549
|
this.pointerMove(screenTarget.x, screenTarget.y, options);
|
|
582
550
|
this.pointerUp(screenTarget.x, screenTarget.y, options);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/Driver.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tEditor,\n\tMat,\n\tPageRecordType,\n\tROTATE_CORNER_TO_SELECTION_CORNER,\n\tRotateCorner,\n\tSelectionHandle,\n\tTLArrowShape,\n\tTLContent,\n\tTLKeyboardEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLShape,\n\tTLShapeId,\n\tTLWheelEventInfo,\n\tVec,\n\tVecLike,\n\tcompact,\n\tcreateShapeId,\n\tisAccelKey,\n\trotateSelectionHandle,\n\ttlenv,\n} from '@tldraw/editor'\n\n/** Options for pointer events. Either partial pointer event info or a shape ID to target. @public */\nexport type PointerEventInit = Partial<TLPointerEventInfo> | TLShapeId\n\n/** Modifier keys for events. @public */\nexport type EventModifiers = Partial<Pick<TLPointerEventInfo, 'shiftKey' | 'ctrlKey' | 'altKey'>>\n\n/**\n * Driver wraps an Editor instance and provides an imperative API for driving it\n * programmatically. Useful for scripting, automation, REPL usage, and testing.\n *\n * All methods use only public Editor APIs and return `this` for fluent chaining.\n *\n * @public\n */\nexport class Driver {\n\t/** The underlying Editor instance. */\n\tprivate _cleanup: (() => void) | null = null\n\n\tconstructor(public readonly editor: Editor) {\n\t\tthis._cleanup = this.editor.sideEffects.registerAfterCreateHandler('shape', (record) => {\n\t\t\tthis._lastCreatedShapes.push(record)\n\t\t\tif (this._lastCreatedShapes.length > 1000) {\n\t\t\t\tthis._lastCreatedShapes = this._lastCreatedShapes.slice(-500)\n\t\t\t}\n\t\t})\n\t}\n\n\t/** Remove all registered side-effect handlers. Call when this controller is no longer needed. */\n\tdispose() {\n\t\tthis._cleanup?.()\n\t\tthis._cleanup = null\n\t}\n\n\t/** Local clipboard content. Used by copy, cut, and paste. */\n\tclipboard: TLContent | null = null\n\n\tprivate _lastCreatedShapes: TLShape[] = []\n\n\t/**\n\t * Get the last created shapes.\n\t * @param count - The number of shapes to get.\n\t */\n\tgetLastCreatedShapes(count = 1) {\n\t\treturn this._lastCreatedShapes.slice(-count).map((s) => this.editor.getShape(s)!)\n\t}\n\n\t/**\n\t * Get the last created shape.\n\t */\n\tgetLastCreatedShape<T extends TLShape>() {\n\t\tconst lastShape = this._lastCreatedShapes[this._lastCreatedShapes.length - 1] as T\n\t\treturn this.editor.getShape<T>(lastShape)!\n\t}\n\n\t/* ---------------------- IDs ---------------------- */\n\n\t/**\n\t * Creates a shape ID from a string.\n\t * @param id - The string to convert to a shape ID.\n\t */\n\tcreateShapeID(id: string) {\n\t\treturn createShapeId(id)\n\t}\n\n\t/**\n\t * Creates a page ID from a string.\n\t * @param id - The string to convert to a page ID.\n\t */\n\tcreatePageID(id: string) {\n\t\treturn PageRecordType.createId(id)\n\t}\n\n\t/* ------------------- Clipboard ------------------- */\n\n\t/**\n\t * Copies the given shapes to the controller clipboard. Defaults to the current selection.\n\t * @param ids - Shape IDs to copy. Defaults to the current selection.\n\t */\n\tcopy(ids = this.editor.getSelectedShapeIds()) {\n\t\tif (ids.length > 0) {\n\t\t\tconst content = this.editor.getContentFromCurrentPage(ids)\n\t\t\tif (content) {\n\t\t\t\tthis.clipboard = content\n\t\t\t}\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Cuts the given shapes (copy to clipboard, then delete). Defaults to the current selection.\n\t * @param ids - Shape IDs to cut. Defaults to the current selection.\n\t */\n\tcut(ids = this.editor.getSelectedShapeIds()) {\n\t\tif (ids.length > 0) {\n\t\t\tconst content = this.editor.getContentFromCurrentPage(ids)\n\t\t\tif (content) {\n\t\t\t\tthis.clipboard = content\n\t\t\t}\n\t\t\tthis.editor.deleteShapes(ids)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Pastes content from the controller clipboard. If shift is held, uses current pointer. Otherwise uses the given point.\n\t * @param point - Page coordinates for paste location. If omitted and shift is not held, placement may vary.\n\t */\n\tpaste(point?: VecLike) {\n\t\tif (this.clipboard !== null) {\n\t\t\tconst p = this.editor.inputs.getShiftKey() ? this.editor.inputs.getCurrentPagePoint() : point\n\n\t\t\tthis.editor.markHistoryStoppingPoint('pasting')\n\t\t\tthis.editor.putContentOntoCurrentPage(this.clipboard, {\n\t\t\t\tpoint: p,\n\t\t\t\tselect: true,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/* ------------------- Queries ------------------- */\n\n\t/** Returns the center of the viewport in page coordinates. */\n\tgetViewportPageCenter() {\n\t\treturn this.editor.getViewportPageBounds().center\n\t}\n\n\t/** Returns the center of the current selection in page coordinates, or null if nothing is selected. */\n\tgetSelectionPageCenter() {\n\t\tconst selectionRotation = this.editor.getSelectionRotation()\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()\n\t\tif (!selectionBounds) return null\n\t\treturn Vec.RotWith(selectionBounds.center, selectionBounds.point, selectionRotation)\n\t}\n\n\t/**\n\t * Returns the center of a shape in page coordinates, or null if the shape has no page transform.\n\t * @param shape - The shape to get the center of.\n\t */\n\tgetPageCenter(shape: TLShape) {\n\t\tconst pageTransform = this.editor.getShapePageTransform(shape.id)\n\t\tif (!pageTransform) return null\n\t\tconst center = this.editor.getShapeGeometry(shape).bounds.center\n\t\treturn Mat.applyToPoint(pageTransform, center)\n\t}\n\n\t/**\n\t * Returns the rotation of a shape in page space by ID, in radians.\n\t * @param id - The shape ID.\n\t */\n\tgetPageRotationById(id: TLShapeId): number {\n\t\tconst pageTransform = this.editor.getShapePageTransform(id)\n\t\tif (pageTransform) {\n\t\t\treturn Mat.Decompose(pageTransform).rotation\n\t\t}\n\t\treturn 0\n\t}\n\n\t/**\n\t * Returns the rotation of a shape in page space, in radians.\n\t * @param shape - The shape to get the rotation of.\n\t */\n\tgetPageRotation(shape: TLShape) {\n\t\treturn this.getPageRotationById(shape.id)\n\t}\n\n\t/**\n\t * Returns all arrow shapes bound to the given shape.\n\t * @param shapeId - The shape ID to find arrows bound to.\n\t */\n\tgetArrowsBoundTo(shapeId: TLShapeId) {\n\t\tconst ids = new Set(this.editor.getBindingsToShape(shapeId, 'arrow').map((b) => b.fromId))\n\t\treturn compact(Array.from(ids, (id) => this.editor.getShape<TLArrowShape>(id)))\n\t}\n\n\t/* --------------- Event building --------------- */\n\n\t/**\n\t * Builds a TLPointerEventInfo object for input simulation.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tprivate getPointerEventInfo(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t): TLPointerEventInfo {\n\t\tif (typeof options === 'string') {\n\t\t\toptions = { target: 'shape', shape: this.editor.getShape(options) }\n\t\t} else if (options === undefined) {\n\t\t\toptions = { target: 'canvas' }\n\t\t}\n\t\tconst info = {\n\t\t\tname: 'pointer_down',\n\t\t\ttype: 'pointer',\n\t\t\tpointerId: 1,\n\t\t\tshiftKey: this.editor.inputs.getShiftKey(),\n\t\t\tctrlKey: this.editor.inputs.getCtrlKey(),\n\t\t\taltKey: this.editor.inputs.getAltKey(),\n\t\t\tmetaKey: this.editor.inputs.getMetaKey(),\n\t\t\taccelKey: isAccelKey({ ...this.editor.inputs.toJson(), ...modifiers }),\n\t\t\tpoint: { x, y, z: null },\n\t\t\tbutton: 0,\n\t\t\tisPen: false,\n\t\t\t...options,\n\t\t\t...modifiers,\n\t\t} as TLPointerEventInfo\n\n\t\t// In simulated input, a pen is assumed to be a direct-display pen (which auto-enables pen\n\t\t// mode) unless a test explicitly opts out with `isPenDirect: false`.\n\t\tif (info.isPenDirect === undefined) info.isPenDirect = info.isPen\n\n\t\tif (tlenv.isDarwin && info.button === 0 && info.ctrlKey && !info.metaKey) {\n\t\t\tinfo.button = 2\n\t\t}\n\n\t\treturn info\n\t}\n\n\t/**\n\t * Builds a TLKeyboardEventInfo object for input simulation.\n\t * @param key - The key being pressed.\n\t * @param name - The event name (key_down, key_up, key_repeat).\n\t * @param options - Partial event info overrides.\n\t */\n\tprivate getKeyboardEventInfo(\n\t\tkey: string,\n\t\tname: TLKeyboardEventInfo['name'],\n\t\toptions = {} as Partial<Omit<TLKeyboardEventInfo, 'point'>>\n\t): TLKeyboardEventInfo {\n\t\t// Like a real DOM keyboard event, the flags reflect every modifier currently held \u2014 not\n\t\t// just the key being pressed. We OR in the editor's current modifier state so that, e.g.,\n\t\t// pressing Shift while Control is held still reports ctrlKey: true. (keyUp passes explicit\n\t\t// flag overrides for its release semantics, so those win over these defaults.)\n\t\tconst flags = {\n\t\t\tshiftKey: key === 'Shift' || this.editor.inputs.getShiftKey(),\n\t\t\tctrlKey: key === 'Control' || key === 'Meta' || this.editor.inputs.getCtrlKey(),\n\t\t\taltKey: key === 'Alt' || this.editor.inputs.getAltKey(),\n\t\t\tmetaKey: key === 'Meta' || this.editor.inputs.getMetaKey(),\n\t\t\t...options,\n\t\t}\n\t\treturn {\n\t\t\t...flags,\n\t\t\taccelKey: flags.accelKey ?? (tlenv.isDarwin ? flags.metaKey : flags.ctrlKey || flags.metaKey),\n\t\t\tname,\n\t\t\tcode:\n\t\t\t\tkey === 'Shift'\n\t\t\t\t\t? 'ShiftLeft'\n\t\t\t\t\t: key === 'Alt'\n\t\t\t\t\t\t? 'AltLeft'\n\t\t\t\t\t\t: key === 'Control'\n\t\t\t\t\t\t\t? 'CtrlLeft'\n\t\t\t\t\t\t\t: key === 'Meta'\n\t\t\t\t\t\t\t\t? 'MetaLeft'\n\t\t\t\t\t\t\t\t: key === ' '\n\t\t\t\t\t\t\t\t\t? 'Space'\n\t\t\t\t\t\t\t\t\t: key === 'Enter' ||\n\t\t\t\t\t\t\t\t\t\t key === 'ArrowRight' ||\n\t\t\t\t\t\t\t\t\t\t key === 'ArrowLeft' ||\n\t\t\t\t\t\t\t\t\t\t key === 'ArrowUp' ||\n\t\t\t\t\t\t\t\t\t\t key === 'ArrowDown'\n\t\t\t\t\t\t\t\t\t\t? key\n\t\t\t\t\t\t\t\t\t\t: 'Key' + key[0].toUpperCase() + key.slice(1),\n\t\t\ttype: 'keyboard',\n\t\t\tkey,\n\t\t}\n\t}\n\n\t/* --------------- Input events --------------- */\n\n\t/**\n\t * Emits tick events to advance the editor by the given number of frames (default 1).\n\t * @param count - Number of tick events to emit. Defaults to 1.\n\t */\n\tforceTick(count = 1) {\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tthis.editor.emit('tick', 16)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pointer move event at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tpointerMove(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_move',\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pointer down event at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tpointerDown(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_down',\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pointer up event at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tpointerUp(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_up',\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pointer down followed by pointer up at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tclick(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.pointerDown(x, y, options, modifiers)\n\t\tthis.pointerUp(x, y, options, modifiers)\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a right-click (button 2) down and up at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\trightClick(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_down',\n\t\t\tbutton: 2,\n\t\t})\n\t\tthis.forceTick()\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_up',\n\t\t\tbutton: 2,\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a double-click sequence at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tdoubleClick(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.pointerDown(x, y, options, modifiers)\n\t\tthis.pointerUp(x, y, options, modifiers)\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\ttype: 'click',\n\t\t\tname: 'double_click',\n\t\t\tphase: 'down',\n\t\t})\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\ttype: 'click',\n\t\t\tname: 'double_click',\n\t\t\tphase: 'up',\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a key down followed by key up for the given key.\n\t * @param key - The key to press (e.g. 'a', 'Enter', 'Shift').\n\t * @param options - Partial keyboard event overrides.\n\t */\n\tkeyPress(key: string, options = {} as Partial<Omit<TLKeyboardEventInfo, 'key'>>) {\n\t\tthis.keyDown(key, options)\n\t\tthis.keyUp(key, options)\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a key down event for the given key.\n\t * @param key - The key to press (e.g. 'a', 'Enter', 'Shift').\n\t * @param options - Partial keyboard event overrides.\n\t */\n\tkeyDown(key: string, options = {} as Partial<Omit<TLKeyboardEventInfo, 'key'>>) {\n\t\tthis.editor.dispatch({ ...this.getKeyboardEventInfo(key, 'key_down', options) })\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a key repeat event for the given key.\n\t * @param key - The key that is repeating (e.g. 'a', 'ArrowDown').\n\t * @param options - Partial keyboard event overrides.\n\t */\n\tkeyRepeat(key: string, options = {} as Partial<Omit<TLKeyboardEventInfo, 'key'>>) {\n\t\tthis.editor.dispatch({ ...this.getKeyboardEventInfo(key, 'key_repeat', options) })\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a key up event for the given key.\n\t * @param key - The key to release (e.g. 'a', 'Enter', 'Shift').\n\t * @param options - Partial keyboard event overrides.\n\t */\n\tkeyUp(key: string, options = {} as Partial<Omit<TLKeyboardEventInfo, 'key'>>) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getKeyboardEventInfo(key, 'key_up', {\n\t\t\t\tshiftKey: this.editor.inputs.getShiftKey() && key !== 'Shift',\n\t\t\t\tctrlKey: this.editor.inputs.getCtrlKey() && !(key === 'Control' || key === 'Meta'),\n\t\t\t\taltKey: this.editor.inputs.getAltKey() && key !== 'Alt',\n\t\t\t\tmetaKey: this.editor.inputs.getMetaKey() && key !== 'Meta',\n\t\t\t\t...options,\n\t\t\t}),\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a wheel event with the given delta values.\n\t * @param dx - Horizontal scroll delta.\n\t * @param dy - Vertical scroll delta.\n\t * @param options - Partial wheel event overrides.\n\t */\n\twheel(dx: number, dy: number, options = {} as Partial<Omit<TLWheelEventInfo, 'delta'>>) {\n\t\tconst currentScreenPoint = this.editor.inputs.getCurrentScreenPoint()\n\t\tthis.editor.dispatch({\n\t\t\ttype: 'wheel',\n\t\t\tname: 'wheel',\n\t\t\tpoint: new Vec(currentScreenPoint.x, currentScreenPoint.y),\n\t\t\tshiftKey: this.editor.inputs.getShiftKey(),\n\t\t\tctrlKey: this.editor.inputs.getCtrlKey(),\n\t\t\taltKey: this.editor.inputs.getAltKey(),\n\t\t\tmetaKey: this.editor.inputs.getMetaKey(),\n\t\t\taccelKey: isAccelKey(this.editor.inputs),\n\t\t\t...options,\n\t\t\tdelta: { x: dx, y: dy },\n\t\t})\n\t\tthis.forceTick(2)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pans the camera by the given offset (in page coordinates). Does nothing if camera is locked.\n\t * @param offset - The pan delta (x, y) in page coordinates.\n\t */\n\tpan(offset: VecLike) {\n\t\tconst { isLocked, panSpeed } = this.editor.getCameraOptions()\n\t\tif (isLocked) return this\n\t\tconst { x: cx, y: cy, z: cz } = this.editor.getCamera()\n\t\tthis.editor.setCamera(\n\t\t\tnew Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),\n\t\t\t{ immediate: true }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pinch start event.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param z - Pinch scale/factor.\n\t * @param dx - Delta x for pinch.\n\t * @param dy - Delta y for pinch.\n\t * @param dz - Delta z for pinch.\n\t * @param options - Partial pinch event overrides.\n\t */\n\tpinchStart(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\tz: number,\n\t\tdx: number,\n\t\tdy: number,\n\t\tdz: number,\n\t\toptions = {} as Partial<Omit<TLPinchEventInfo, 'point' | 'delta' | 'offset'>>\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\ttype: 'pinch',\n\t\t\tname: 'pinch_start',\n\t\t\tshiftKey: this.editor.inputs.getShiftKey(),\n\t\t\tctrlKey: this.editor.inputs.getCtrlKey(),\n\t\t\taltKey: this.editor.inputs.getAltKey(),\n\t\t\tmetaKey: this.editor.inputs.getMetaKey(),\n\t\t\taccelKey: isAccelKey(this.editor.inputs),\n\t\t\t...options,\n\t\t\tpoint: { x, y, z },\n\t\t\tdelta: { x: dx, y: dy, z: dz },\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pinch move event (pinch_to).\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param z - Pinch scale/factor.\n\t * @param dx - Delta x for pinch.\n\t * @param dy - Delta y for pinch.\n\t * @param dz - Delta z for pinch.\n\t * @param options - Partial pinch event overrides.\n\t */\n\tpinchTo(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\tz: number,\n\t\tdx: number,\n\t\tdy: number,\n\t\tdz: number,\n\t\toptions = {} as Partial<Omit<TLPinchEventInfo, 'point' | 'delta' | 'offset'>>\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\ttype: 'pinch',\n\t\t\tname: 'pinch',\n\t\t\tshiftKey: this.editor.inputs.getShiftKey(),\n\t\t\tctrlKey: this.editor.inputs.getCtrlKey(),\n\t\t\taltKey: this.editor.inputs.getAltKey(),\n\t\t\tmetaKey: this.editor.inputs.getMetaKey(),\n\t\t\taccelKey: isAccelKey(this.editor.inputs),\n\t\t\t...options,\n\t\t\tpoint: { x, y, z },\n\t\t\tdelta: { x: dx, y: dy, z: dz },\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pinch end event.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param z - Pinch scale/factor.\n\t * @param dx - Delta x for pinch.\n\t * @param dy - Delta y for pinch.\n\t * @param dz - Delta z for pinch.\n\t * @param options - Partial pinch event overrides.\n\t */\n\tpinchEnd(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\tz: number,\n\t\tdx: number,\n\t\tdy: number,\n\t\tdz: number,\n\t\toptions = {} as Partial<Omit<TLPinchEventInfo, 'point' | 'delta' | 'offset'>>\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\ttype: 'pinch',\n\t\t\tname: 'pinch_end',\n\t\t\tshiftKey: this.editor.inputs.getShiftKey(),\n\t\t\tctrlKey: this.editor.inputs.getCtrlKey(),\n\t\t\taltKey: this.editor.inputs.getAltKey(),\n\t\t\tmetaKey: this.editor.inputs.getMetaKey(),\n\t\t\taccelKey: isAccelKey(this.editor.inputs),\n\t\t\t...options,\n\t\t\tpoint: { x, y, z },\n\t\t\tdelta: { x: dx, y: dy, z: dz },\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/* --------------- Interaction helpers --------------- */\n\n\t/**\n\t * Converts a point from page coordinates to screen coordinates.\n\t * Pointer events operate in screen space, so page-space points must be\n\t * converted before being passed to pointerDown/Move/Up.\n\t */\n\tprivate pageToScreen(point: VecLike) {\n\t\treturn this.editor.pageToScreen(point)\n\t}\n\n\t/**\n\t * Simulates rotating the current selection by the given angle in radians via the rotation handle.\n\t * @param angleRadians - Rotation angle in radians.\n\t * @param options - Optional handle and shiftKey. handle defaults to 'top_left_rotate'.\n\t */\n\trotateSelection(\n\t\tangleRadians: number,\n\t\toptions: { handle?: RotateCorner; shiftKey?: boolean } = {}\n\t) {\n\t\tconst { handle = 'top_left_rotate', shiftKey = false } = options\n\t\tif (this.editor.getSelectedShapeIds().length === 0) {\n\t\t\tthrow new Error('No selection')\n\t\t}\n\n\t\tthis.editor.setCurrentTool('select')\n\n\t\tconst handlePoint = this.editor\n\t\t\t.getSelectionRotatedPageBounds()!\n\t\t\t.getHandlePoint(ROTATE_CORNER_TO_SELECTION_CORNER[handle])\n\t\t\t.clone()\n\t\t\t.rotWith(\n\t\t\t\tthis.editor.getSelectionRotatedPageBounds()!.point,\n\t\t\t\tthis.editor.getSelectionRotation()\n\t\t\t)\n\n\t\tconst targetHandlePoint = Vec.RotWith(handlePoint, this.getSelectionPageCenter()!, angleRadians)\n\n\t\tconst screenHandle = this.pageToScreen(handlePoint)\n\t\tconst screenTarget = this.pageToScreen(targetHandlePoint)\n\n\t\tthis.pointerDown(screenHandle.x, screenHandle.y, { target: 'selection', handle })\n\t\tthis.pointerMove(screenTarget.x, screenTarget.y, { shiftKey })\n\t\tthis.pointerUp()\n\t\treturn this\n\t}\n\n\t/**\n\t * Simulates translating the current selection by the given delta in page coordinates.\n\t * @param dx - Horizontal delta in page coordinates.\n\t * @param dy - Vertical delta in page coordinates.\n\t * @param options - Partial pointer event overrides (e.g. altKey for center-based scaling).\n\t */\n\ttranslateSelection(dx: number, dy: number, options?: Partial<TLPointerEventInfo>) {\n\t\tif (this.editor.getSelectedShapeIds().length === 0) {\n\t\t\tthrow new Error('No selection')\n\t\t}\n\t\tthis.editor.setCurrentTool('select')\n\n\t\tconst center = this.getSelectionPageCenter()!\n\t\tconst screenCenter = this.pageToScreen(center)\n\n\t\tthis.pointerDown(screenCenter.x, screenCenter.y, this.editor.getSelectedShapeIds()[0])\n\t\tconst numSteps = 10\n\t\tfor (let i = 1; i < numSteps; i++) {\n\t\t\tconst p = this.pageToScreen({\n\t\t\t\tx: center.x + (i * dx) / numSteps,\n\t\t\t\ty: center.y + (i * dy) / numSteps,\n\t\t\t})\n\t\t\tthis.pointerMove(p.x, p.y, options)\n\t\t}\n\t\tconst endScreen = this.pageToScreen({ x: center.x + dx, y: center.y + dy })\n\t\tthis.pointerUp(endScreen.x, endScreen.y, options)\n\t\treturn this\n\t}\n\n\t/**\n\t * Simulates resizing the current selection via the given handle, with optional scale factors.\n\t * @param scale - Scale factors for x and y. Defaults to `\\{ scaleX: 1, scaleY: 1 \\}`.\n\t * @param handle - The selection handle to drag (e.g. 'top', 'bottom_right').\n\t * @param options - Partial pointer event overrides (e.g. altKey to scale from center).\n\t */\n\tresizeSelection(\n\t\tscale: { scaleX?: number; scaleY?: number } = {},\n\t\thandle: SelectionHandle,\n\t\toptions?: Partial<TLPointerEventInfo>\n\t) {\n\t\tconst { scaleX = 1, scaleY = 1 } = scale\n\t\tif (this.editor.getSelectedShapeIds().length === 0) {\n\t\t\tthrow new Error('No selection')\n\t\t}\n\t\tthis.editor.setCurrentTool('select')\n\t\tconst bounds = this.editor.getSelectionRotatedPageBounds()!\n\t\tconst preRotationHandlePoint = bounds.getHandlePoint(handle)\n\n\t\tconst preRotationScaleOriginPoint = options?.altKey\n\t\t\t? bounds.center\n\t\t\t: bounds.getHandlePoint(rotateSelectionHandle(handle, Math.PI))\n\n\t\tconst preRotationTargetHandlePoint = Vec.Add(\n\t\t\tVec.Sub(preRotationHandlePoint, preRotationScaleOriginPoint).mulV({\n\t\t\t\tx: scaleX,\n\t\t\t\ty: scaleY,\n\t\t\t}),\n\t\t\tpreRotationScaleOriginPoint\n\t\t)\n\n\t\tconst handlePoint = Vec.RotWith(\n\t\t\tpreRotationHandlePoint,\n\t\t\tbounds.point,\n\t\t\tthis.editor.getSelectionRotation()\n\t\t)\n\t\tconst targetHandlePoint = Vec.RotWith(\n\t\t\tpreRotationTargetHandlePoint,\n\t\t\tbounds.point,\n\t\t\tthis.editor.getSelectionRotation()\n\t\t)\n\n\t\tconst screenHandle = this.pageToScreen(handlePoint)\n\t\tconst screenTarget = this.pageToScreen(targetHandlePoint)\n\n\t\tthis.pointerDown(screenHandle.x, screenHandle.y, { target: 'selection', handle }, options)\n\t\tthis.pointerMove(screenTarget.x, screenTarget.y, options)\n\t\tthis.pointerUp(screenTarget.x, screenTarget.y, options)\n\t\treturn this\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n\tEditor,\n\tMat,\n\tPageRecordType,\n\tROTATE_CORNER_TO_SELECTION_CORNER,\n\tRotateCorner,\n\tSelectionHandle,\n\tTLArrowShape,\n\tTLContent,\n\tTLKeyboardEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLShape,\n\tTLShapeId,\n\tTLWheelEventInfo,\n\tVec,\n\tVecLike,\n\tcompact,\n\tcreateShapeId,\n\tisAccelKey,\n\trotateSelectionHandle,\n\ttlenv,\n} from '@tldraw/editor'\n\n/** Options for pointer events. Either partial pointer event info or a shape ID to target. @public */\nexport type PointerEventInit = Partial<TLPointerEventInfo> | TLShapeId\n\n/** Modifier keys for events. @public */\nexport type EventModifiers = Partial<Pick<TLPointerEventInfo, 'shiftKey' | 'ctrlKey' | 'altKey'>>\n\nconst KEY_CODES: Record<string, string> = {\n\tShift: 'ShiftLeft',\n\tAlt: 'AltLeft',\n\tControl: 'CtrlLeft',\n\tMeta: 'MetaLeft',\n\t' ': 'Space',\n\tEnter: 'Enter',\n\tArrowRight: 'ArrowRight',\n\tArrowLeft: 'ArrowLeft',\n\tArrowUp: 'ArrowUp',\n\tArrowDown: 'ArrowDown',\n}\n\n/**\n * Driver wraps an Editor instance and provides an imperative API for driving it\n * programmatically. Useful for scripting, automation, REPL usage, and testing.\n *\n * All methods use only public Editor APIs and return `this` for fluent chaining.\n *\n * @public\n */\nexport class Driver {\n\t/** The underlying Editor instance. */\n\tprivate _cleanup: (() => void) | null\n\tprivate _lastCreatedShapes: TLShape[] = []\n\n\tconstructor(public readonly editor: Editor) {\n\t\tthis._cleanup = this.editor.sideEffects.registerAfterCreateHandler('shape', (record) => {\n\t\t\tthis._lastCreatedShapes.push(record)\n\t\t\tif (this._lastCreatedShapes.length > 1000) {\n\t\t\t\tthis._lastCreatedShapes = this._lastCreatedShapes.slice(-500)\n\t\t\t}\n\t\t})\n\t}\n\n\t/** Remove all registered side-effect handlers. Call when this controller is no longer needed. */\n\tdispose() {\n\t\tthis._cleanup?.()\n\t\tthis._cleanup = null\n\t}\n\n\t/** Local clipboard content. Used by copy, cut, and paste. */\n\tclipboard: TLContent | null = null\n\n\t/**\n\t * Get the last created shapes.\n\t * @param count - The number of shapes to get.\n\t */\n\tgetLastCreatedShapes(count = 1) {\n\t\treturn this._lastCreatedShapes.slice(-count).map((s) => this.editor.getShape(s)!)\n\t}\n\n\t/**\n\t * Get the last created shape.\n\t */\n\tgetLastCreatedShape<T extends TLShape>() {\n\t\tconst lastShape = this._lastCreatedShapes[this._lastCreatedShapes.length - 1] as T\n\t\treturn this.editor.getShape<T>(lastShape)!\n\t}\n\n\t/* ---------------------- IDs ---------------------- */\n\n\t/**\n\t * Creates a shape ID from a string.\n\t * @param id - The string to convert to a shape ID.\n\t */\n\tcreateShapeID(id: string) {\n\t\treturn createShapeId(id)\n\t}\n\n\t/**\n\t * Creates a page ID from a string.\n\t * @param id - The string to convert to a page ID.\n\t */\n\tcreatePageID(id: string) {\n\t\treturn PageRecordType.createId(id)\n\t}\n\n\t/* ------------------- Clipboard ------------------- */\n\n\t/**\n\t * Copies the given shapes to the controller clipboard. Defaults to the current selection.\n\t * @param ids - Shape IDs to copy. Defaults to the current selection.\n\t */\n\tcopy(ids = this.editor.getSelectedShapeIds()) {\n\t\tif (ids.length > 0) {\n\t\t\tconst content = this.editor.getContentFromCurrentPage(ids)\n\t\t\tif (content) {\n\t\t\t\tthis.clipboard = content\n\t\t\t}\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Cuts the given shapes (copy to clipboard, then delete). Defaults to the current selection.\n\t * @param ids - Shape IDs to cut. Defaults to the current selection.\n\t */\n\tcut(ids = this.editor.getSelectedShapeIds()) {\n\t\tif (ids.length > 0) {\n\t\t\tthis.copy(ids)\n\t\t\tthis.editor.deleteShapes(ids)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Pastes content from the controller clipboard. If shift is held, uses current pointer. Otherwise uses the given point.\n\t * @param point - Page coordinates for paste location. If omitted and shift is not held, placement may vary.\n\t */\n\tpaste(point?: VecLike) {\n\t\tif (this.clipboard !== null) {\n\t\t\tconst p = this.editor.inputs.getShiftKey() ? this.editor.inputs.getCurrentPagePoint() : point\n\n\t\t\tthis.editor.markHistoryStoppingPoint('pasting')\n\t\t\tthis.editor.putContentOntoCurrentPage(this.clipboard, {\n\t\t\t\tpoint: p,\n\t\t\t\tselect: true,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/* ------------------- Queries ------------------- */\n\n\t/** Returns the center of the viewport in page coordinates. */\n\tgetViewportPageCenter() {\n\t\treturn this.editor.getViewportPageBounds().center\n\t}\n\n\t/** Returns the center of the current selection in page coordinates, or null if nothing is selected. */\n\tgetSelectionPageCenter() {\n\t\tconst selectionRotation = this.editor.getSelectionRotation()\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()\n\t\tif (!selectionBounds) return null\n\t\treturn Vec.RotWith(selectionBounds.center, selectionBounds.point, selectionRotation)\n\t}\n\n\t/**\n\t * Returns the center of a shape in page coordinates, or null if the shape has no page transform.\n\t * @param shape - The shape to get the center of.\n\t */\n\tgetPageCenter(shape: TLShape) {\n\t\tconst pageTransform = this.editor.getShapePageTransform(shape.id)\n\t\tif (!pageTransform) return null\n\t\tconst center = this.editor.getShapeGeometry(shape).bounds.center\n\t\treturn Mat.applyToPoint(pageTransform, center)\n\t}\n\n\t/**\n\t * Returns the rotation of a shape in page space by ID, in radians.\n\t * @param id - The shape ID.\n\t */\n\tgetPageRotationById(id: TLShapeId): number {\n\t\tconst pageTransform = this.editor.getShapePageTransform(id)\n\t\treturn pageTransform ? pageTransform.rotation() : 0\n\t}\n\n\t/**\n\t * Returns the rotation of a shape in page space, in radians.\n\t * @param shape - The shape to get the rotation of.\n\t */\n\tgetPageRotation(shape: TLShape) {\n\t\treturn this.getPageRotationById(shape.id)\n\t}\n\n\t/**\n\t * Returns all arrow shapes bound to the given shape.\n\t * @param shapeId - The shape ID to find arrows bound to.\n\t */\n\tgetArrowsBoundTo(shapeId: TLShapeId) {\n\t\tconst ids = new Set(this.editor.getBindingsToShape(shapeId, 'arrow').map((b) => b.fromId))\n\t\treturn compact(Array.from(ids, (id) => this.editor.getShape<TLArrowShape>(id)))\n\t}\n\n\t/* --------------- Event building --------------- */\n\n\tprivate getModifierKeys() {\n\t\tconst { inputs } = this.editor\n\t\treturn {\n\t\t\tshiftKey: inputs.getShiftKey(),\n\t\t\tctrlKey: inputs.getCtrlKey(),\n\t\t\taltKey: inputs.getAltKey(),\n\t\t\tmetaKey: inputs.getMetaKey(),\n\t\t\taccelKey: isAccelKey(inputs),\n\t\t}\n\t}\n\n\t/**\n\t * Builds a TLPointerEventInfo object for input simulation.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tprivate getPointerEventInfo(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t): TLPointerEventInfo {\n\t\tif (typeof options === 'string') {\n\t\t\toptions = { target: 'shape', shape: this.editor.getShape(options) }\n\t\t} else if (options === undefined) {\n\t\t\toptions = { target: 'canvas' }\n\t\t}\n\t\tconst info = {\n\t\t\tname: 'pointer_down',\n\t\t\ttype: 'pointer',\n\t\t\tpointerId: 1,\n\t\t\t...this.getModifierKeys(),\n\t\t\taccelKey: isAccelKey({ ...this.editor.inputs.toJson(), ...modifiers }),\n\t\t\tpoint: { x, y, z: null },\n\t\t\tbutton: 0,\n\t\t\tisPen: false,\n\t\t\t...options,\n\t\t\t...modifiers,\n\t\t} as TLPointerEventInfo\n\n\t\t// In simulated input, a pen is assumed to be a direct-display pen (which auto-enables pen\n\t\t// mode) unless a test explicitly opts out with `isPenDirect: false`.\n\t\tif (info.isPenDirect === undefined) info.isPenDirect = info.isPen\n\n\t\tif (tlenv.isDarwin && info.button === 0 && info.ctrlKey && !info.metaKey) {\n\t\t\tinfo.button = 2\n\t\t}\n\n\t\treturn info\n\t}\n\n\t/**\n\t * Builds a TLKeyboardEventInfo object for input simulation.\n\t * @param key - The key being pressed.\n\t * @param name - The event name (key_down, key_up, key_repeat).\n\t * @param options - Partial event info overrides.\n\t */\n\tprivate getKeyboardEventInfo(\n\t\tkey: string,\n\t\tname: TLKeyboardEventInfo['name'],\n\t\toptions = {} as Partial<Omit<TLKeyboardEventInfo, 'point'>>\n\t): TLKeyboardEventInfo {\n\t\t// Like a real DOM keyboard event, the flags reflect every modifier currently held \u2014 not\n\t\t// just the key being pressed. We OR in the editor's current modifier state so that, e.g.,\n\t\t// pressing Shift while Control is held still reports ctrlKey: true. (keyUp passes explicit\n\t\t// flag overrides for its release semantics, so those win over these defaults.)\n\t\tconst flags = {\n\t\t\tshiftKey: key === 'Shift' || this.editor.inputs.getShiftKey(),\n\t\t\tctrlKey: key === 'Control' || key === 'Meta' || this.editor.inputs.getCtrlKey(),\n\t\t\taltKey: key === 'Alt' || this.editor.inputs.getAltKey(),\n\t\t\tmetaKey: key === 'Meta' || this.editor.inputs.getMetaKey(),\n\t\t\t...options,\n\t\t}\n\t\treturn {\n\t\t\t...flags,\n\t\t\taccelKey: flags.accelKey ?? isAccelKey(flags),\n\t\t\tname,\n\t\t\tcode: KEY_CODES[key] ?? 'Key' + key[0].toUpperCase() + key.slice(1),\n\t\t\ttype: 'keyboard',\n\t\t\tkey,\n\t\t}\n\t}\n\n\t/* --------------- Input events --------------- */\n\n\t/**\n\t * Emits tick events to advance the editor by the given number of frames (default 1).\n\t * @param count - Number of tick events to emit. Defaults to 1.\n\t */\n\tforceTick(count = 1) {\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tthis.editor.emit('tick', 16)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pointer move event at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tpointerMove(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_move',\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pointer down event at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tpointerDown(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_down',\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pointer up event at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tpointerUp(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_up',\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pointer down followed by pointer up at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tclick(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.pointerDown(x, y, options, modifiers)\n\t\tthis.pointerUp(x, y, options, modifiers)\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a right-click (button 2) down and up at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\trightClick(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_down',\n\t\t\tbutton: 2,\n\t\t})\n\t\tthis.forceTick()\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\tname: 'pointer_up',\n\t\t\tbutton: 2,\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a double-click sequence at the given screen coordinates.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param options - Target shape/selection or partial event info.\n\t * @param modifiers - Override shift, ctrl, or alt key state.\n\t */\n\tdoubleClick(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\toptions?: PointerEventInit,\n\t\tmodifiers?: EventModifiers\n\t) {\n\t\tthis.click(x, y, options, modifiers)\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\ttype: 'click',\n\t\t\tname: 'double_click',\n\t\t\tphase: 'down',\n\t\t})\n\t\tthis.editor.dispatch({\n\t\t\t...this.getPointerEventInfo(x, y, options, modifiers),\n\t\t\ttype: 'click',\n\t\t\tname: 'double_click',\n\t\t\tphase: 'up',\n\t\t})\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a key down followed by key up for the given key.\n\t * @param key - The key to press (e.g. 'a', 'Enter', 'Shift').\n\t * @param options - Partial keyboard event overrides.\n\t */\n\tkeyPress(key: string, options = {} as Partial<Omit<TLKeyboardEventInfo, 'key'>>) {\n\t\tthis.keyDown(key, options)\n\t\tthis.keyUp(key, options)\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a key down event for the given key.\n\t * @param key - The key to press (e.g. 'a', 'Enter', 'Shift').\n\t * @param options - Partial keyboard event overrides.\n\t */\n\tkeyDown(key: string, options = {} as Partial<Omit<TLKeyboardEventInfo, 'key'>>) {\n\t\tthis.editor.dispatch(this.getKeyboardEventInfo(key, 'key_down', options))\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a key repeat event for the given key.\n\t * @param key - The key that is repeating (e.g. 'a', 'ArrowDown').\n\t * @param options - Partial keyboard event overrides.\n\t */\n\tkeyRepeat(key: string, options = {} as Partial<Omit<TLKeyboardEventInfo, 'key'>>) {\n\t\tthis.editor.dispatch(this.getKeyboardEventInfo(key, 'key_repeat', options))\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a key up event for the given key.\n\t * @param key - The key to release (e.g. 'a', 'Enter', 'Shift').\n\t * @param options - Partial keyboard event overrides.\n\t */\n\tkeyUp(key: string, options = {} as Partial<Omit<TLKeyboardEventInfo, 'key'>>) {\n\t\tthis.editor.dispatch(\n\t\t\tthis.getKeyboardEventInfo(key, 'key_up', {\n\t\t\t\tshiftKey: this.editor.inputs.getShiftKey() && key !== 'Shift',\n\t\t\t\tctrlKey: this.editor.inputs.getCtrlKey() && !(key === 'Control' || key === 'Meta'),\n\t\t\t\taltKey: this.editor.inputs.getAltKey() && key !== 'Alt',\n\t\t\t\tmetaKey: this.editor.inputs.getMetaKey() && key !== 'Meta',\n\t\t\t\t...options,\n\t\t\t})\n\t\t)\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a wheel event with the given delta values.\n\t * @param dx - Horizontal scroll delta.\n\t * @param dy - Vertical scroll delta.\n\t * @param options - Partial wheel event overrides.\n\t */\n\twheel(dx: number, dy: number, options = {} as Partial<Omit<TLWheelEventInfo, 'delta'>>) {\n\t\tconst currentScreenPoint = this.editor.inputs.getCurrentScreenPoint()\n\t\tthis.editor.dispatch({\n\t\t\ttype: 'wheel',\n\t\t\tname: 'wheel',\n\t\t\tpoint: new Vec(currentScreenPoint.x, currentScreenPoint.y),\n\t\t\t...this.getModifierKeys(),\n\t\t\t...options,\n\t\t\tdelta: { x: dx, y: dy },\n\t\t})\n\t\tthis.forceTick(2)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pans the camera by the given offset (in page coordinates). Does nothing if camera is locked.\n\t * @param offset - The pan delta (x, y) in page coordinates.\n\t */\n\tpan(offset: VecLike) {\n\t\tconst { isLocked, panSpeed } = this.editor.getCameraOptions()\n\t\tif (isLocked) return this\n\t\tconst { x: cx, y: cy, z: cz } = this.editor.getCamera()\n\t\tthis.editor.setCamera(\n\t\t\tnew Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),\n\t\t\t{ immediate: true }\n\t\t)\n\t\treturn this\n\t}\n\n\tprivate pinch(\n\t\tname: TLPinchEventInfo['name'],\n\t\tx: number,\n\t\ty: number,\n\t\tz: number,\n\t\tdx: number,\n\t\tdy: number,\n\t\tdz: number,\n\t\toptions: Partial<Omit<TLPinchEventInfo, 'point' | 'delta' | 'offset'>>\n\t) {\n\t\tthis.editor.dispatch({\n\t\t\ttype: 'pinch',\n\t\t\tname,\n\t\t\t...this.getModifierKeys(),\n\t\t\t...options,\n\t\t\tpoint: { x, y, z },\n\t\t\tdelta: { x: dx, y: dy, z: dz },\n\t\t})\n\t}\n\n\t/**\n\t * Dispatches a pinch start event.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param z - Pinch scale/factor.\n\t * @param dx - Delta x for pinch.\n\t * @param dy - Delta y for pinch.\n\t * @param dz - Delta z for pinch.\n\t * @param options - Partial pinch event overrides.\n\t */\n\tpinchStart(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\tz: number,\n\t\tdx: number,\n\t\tdy: number,\n\t\tdz: number,\n\t\toptions = {} as Partial<Omit<TLPinchEventInfo, 'point' | 'delta' | 'offset'>>\n\t) {\n\t\tthis.pinch('pinch_start', x, y, z, dx, dy, dz, options)\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pinch move event (pinch_to).\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param z - Pinch scale/factor.\n\t * @param dx - Delta x for pinch.\n\t * @param dy - Delta y for pinch.\n\t * @param dz - Delta z for pinch.\n\t * @param options - Partial pinch event overrides.\n\t */\n\tpinchTo(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\tz: number,\n\t\tdx: number,\n\t\tdy: number,\n\t\tdz: number,\n\t\toptions = {} as Partial<Omit<TLPinchEventInfo, 'point' | 'delta' | 'offset'>>\n\t) {\n\t\tthis.pinch('pinch', x, y, z, dx, dy, dz, options)\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatches a pinch end event.\n\t * @param x - Screen x coordinate. Defaults to current pointer.\n\t * @param y - Screen y coordinate. Defaults to current pointer.\n\t * @param z - Pinch scale/factor.\n\t * @param dx - Delta x for pinch.\n\t * @param dy - Delta y for pinch.\n\t * @param dz - Delta z for pinch.\n\t * @param options - Partial pinch event overrides.\n\t */\n\tpinchEnd(\n\t\tx = this.editor.inputs.getCurrentScreenPoint().x,\n\t\ty = this.editor.inputs.getCurrentScreenPoint().y,\n\t\tz: number,\n\t\tdx: number,\n\t\tdy: number,\n\t\tdz: number,\n\t\toptions = {} as Partial<Omit<TLPinchEventInfo, 'point' | 'delta' | 'offset'>>\n\t) {\n\t\tthis.pinch('pinch_end', x, y, z, dx, dy, dz, options)\n\t\tthis.forceTick()\n\t\treturn this\n\t}\n\n\t/* --------------- Interaction helpers --------------- */\n\n\t/**\n\t * Simulates rotating the current selection by the given angle in radians via the rotation handle.\n\t * @param angleRadians - Rotation angle in radians.\n\t * @param options - Optional handle and shiftKey. handle defaults to 'top_left_rotate'.\n\t */\n\trotateSelection(\n\t\tangleRadians: number,\n\t\toptions: { handle?: RotateCorner; shiftKey?: boolean } = {}\n\t) {\n\t\tconst { handle = 'top_left_rotate', shiftKey = false } = options\n\t\tif (this.editor.getSelectedShapeIds().length === 0) {\n\t\t\tthrow new Error('No selection')\n\t\t}\n\n\t\tthis.editor.setCurrentTool('select')\n\n\t\tconst bounds = this.editor.getSelectionRotatedPageBounds()!\n\t\tconst handlePoint = bounds\n\t\t\t.getHandlePoint(ROTATE_CORNER_TO_SELECTION_CORNER[handle])\n\t\t\t.clone()\n\t\t\t.rotWith(bounds.point, this.editor.getSelectionRotation())\n\n\t\tconst targetHandlePoint = Vec.RotWith(handlePoint, this.getSelectionPageCenter()!, angleRadians)\n\n\t\tconst screenHandle = this.editor.pageToScreen(handlePoint)\n\t\tconst screenTarget = this.editor.pageToScreen(targetHandlePoint)\n\n\t\tthis.pointerDown(screenHandle.x, screenHandle.y, { target: 'selection', handle })\n\t\tthis.pointerMove(screenTarget.x, screenTarget.y, { shiftKey })\n\t\tthis.pointerUp()\n\t\treturn this\n\t}\n\n\t/**\n\t * Simulates translating the current selection by the given delta in page coordinates.\n\t * @param dx - Horizontal delta in page coordinates.\n\t * @param dy - Vertical delta in page coordinates.\n\t * @param options - Partial pointer event overrides (e.g. altKey for center-based scaling).\n\t */\n\ttranslateSelection(dx: number, dy: number, options?: Partial<TLPointerEventInfo>) {\n\t\tif (this.editor.getSelectedShapeIds().length === 0) {\n\t\t\tthrow new Error('No selection')\n\t\t}\n\t\tthis.editor.setCurrentTool('select')\n\n\t\tconst center = this.getSelectionPageCenter()!\n\t\tconst screenCenter = this.editor.pageToScreen(center)\n\n\t\tthis.pointerDown(screenCenter.x, screenCenter.y, this.editor.getSelectedShapeIds()[0])\n\t\tconst numSteps = 10\n\t\tfor (let i = 1; i < numSteps; i++) {\n\t\t\tconst p = this.editor.pageToScreen({\n\t\t\t\tx: center.x + (i * dx) / numSteps,\n\t\t\t\ty: center.y + (i * dy) / numSteps,\n\t\t\t})\n\t\t\tthis.pointerMove(p.x, p.y, options)\n\t\t}\n\t\tconst endScreen = this.editor.pageToScreen({ x: center.x + dx, y: center.y + dy })\n\t\tthis.pointerUp(endScreen.x, endScreen.y, options)\n\t\treturn this\n\t}\n\n\t/**\n\t * Simulates resizing the current selection via the given handle, with optional scale factors.\n\t * @param scale - Scale factors for x and y. Defaults to `\\{ scaleX: 1, scaleY: 1 \\}`.\n\t * @param handle - The selection handle to drag (e.g. 'top', 'bottom_right').\n\t * @param options - Partial pointer event overrides (e.g. altKey to scale from center).\n\t */\n\tresizeSelection(\n\t\tscale: { scaleX?: number; scaleY?: number } = {},\n\t\thandle: SelectionHandle,\n\t\toptions?: Partial<TLPointerEventInfo>\n\t) {\n\t\tconst { scaleX = 1, scaleY = 1 } = scale\n\t\tif (this.editor.getSelectedShapeIds().length === 0) {\n\t\t\tthrow new Error('No selection')\n\t\t}\n\t\tthis.editor.setCurrentTool('select')\n\t\tconst bounds = this.editor.getSelectionRotatedPageBounds()!\n\t\tconst rotation = this.editor.getSelectionRotation()\n\t\tconst preRotationHandlePoint = bounds.getHandlePoint(handle)\n\n\t\tconst preRotationScaleOriginPoint = options?.altKey\n\t\t\t? bounds.center\n\t\t\t: bounds.getHandlePoint(rotateSelectionHandle(handle, Math.PI))\n\n\t\tconst preRotationTargetHandlePoint = Vec.Add(\n\t\t\tVec.Sub(preRotationHandlePoint, preRotationScaleOriginPoint).mulV({\n\t\t\t\tx: scaleX,\n\t\t\t\ty: scaleY,\n\t\t\t}),\n\t\t\tpreRotationScaleOriginPoint\n\t\t)\n\n\t\tconst handlePoint = Vec.RotWith(preRotationHandlePoint, bounds.point, rotation)\n\t\tconst targetHandlePoint = Vec.RotWith(preRotationTargetHandlePoint, bounds.point, rotation)\n\n\t\tconst screenHandle = this.editor.pageToScreen(handlePoint)\n\t\tconst screenTarget = this.editor.pageToScreen(targetHandlePoint)\n\n\t\tthis.pointerDown(screenHandle.x, screenHandle.y, { target: 'selection', handle }, options)\n\t\tthis.pointerMove(screenTarget.x, screenTarget.y, options)\n\t\tthis.pointerUp(screenTarget.x, screenTarget.y, options)\n\t\treturn this\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/driver",
|
|
3
3
|
"description": "Imperative API for driving the tldraw editor programmatically.",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.4.0-canary.02cd0bd3b597",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"lint": "yarn run -T tsx ../../internal/scripts/lint.ts"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@tldraw/editor": "5.
|
|
46
|
-
"@tldraw/utils": "5.
|
|
45
|
+
"@tldraw/editor": "5.4.0-canary.02cd0bd3b597",
|
|
46
|
+
"@tldraw/utils": "5.4.0-canary.02cd0bd3b597"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"lazyrepo": "0.0.0-alpha.27",
|