@tldraw/editor 4.4.0-next.55b4db2171bd → 4.4.0-next.f181afb0ab39
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 +175 -11
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/components/LiveCollaborators.js +14 -24
- package/dist-cjs/lib/components/LiveCollaborators.js.map +2 -2
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +201 -0
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +7 -0
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +29 -14
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +3 -1
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +13 -1
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +2 -2
- package/dist-cjs/lib/config/TLUserPreferences.js +9 -3
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +4 -1
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +378 -89
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +2 -3
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +8 -3
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +29 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/hooks/usePeerIds.js +29 -0
- package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
- package/dist-cjs/lib/options.js +1 -0
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/utils/collaboratorState.js +42 -0
- package/dist-cjs/lib/utils/collaboratorState.js.map +7 -0
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +175 -11
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/components/LiveCollaborators.mjs +17 -24
- package/dist-esm/lib/components/LiveCollaborators.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +181 -0
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +7 -0
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +29 -14
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +3 -1
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +13 -1
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +2 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs +9 -3
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +4 -1
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +378 -89
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +2 -3
- package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +8 -3
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +29 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePeerIds.mjs +33 -1
- package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +1 -0
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/utils/collaboratorState.mjs +22 -0
- package/dist-esm/lib/utils/collaboratorState.mjs.map +7 -0
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +6 -0
- package/package.json +7 -7
- package/src/index.ts +2 -0
- package/src/lib/components/LiveCollaborators.tsx +26 -37
- package/src/lib/components/default-components/CanvasShapeIndicators.tsx +244 -0
- package/src/lib/components/default-components/DefaultCanvas.tsx +15 -1
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +6 -1
- package/src/lib/components/default-components/DefaultShapeIndicators.tsx +16 -1
- package/src/lib/config/TLUserPreferences.test.ts +1 -0
- package/src/lib/config/TLUserPreferences.ts +8 -0
- package/src/lib/editor/Editor.ts +10 -1
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.ts +491 -106
- package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +2 -3
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +24 -0
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +8 -0
- package/src/lib/editor/shapes/ShapeUtil.ts +44 -0
- package/src/lib/hooks/usePeerIds.ts +46 -1
- package/src/lib/options.ts +7 -0
- package/src/lib/utils/collaboratorState.ts +54 -0
- package/src/version.ts +3 -3
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +0 -621
|
@@ -27,13 +27,53 @@ class ScribbleManager {
|
|
|
27
27
|
constructor(editor) {
|
|
28
28
|
this.editor = editor;
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
sessions = /* @__PURE__ */ new Map();
|
|
31
|
+
// ==================== SESSION API ====================
|
|
32
|
+
/**
|
|
33
|
+
* Start a new session for grouping scribbles.
|
|
34
|
+
* Returns a session ID that can be used with other session methods.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Session configuration
|
|
37
|
+
* @returns Session ID
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
startSession(options = {}) {
|
|
41
|
+
const id = options.id ?? (0, import_utils.uniqueId)();
|
|
42
|
+
const session = {
|
|
34
43
|
id,
|
|
44
|
+
items: [],
|
|
45
|
+
state: "active",
|
|
46
|
+
options: {
|
|
47
|
+
selfConsume: options.selfConsume ?? true,
|
|
48
|
+
idleTimeoutMs: options.idleTimeoutMs ?? 0,
|
|
49
|
+
fadeMode: options.fadeMode ?? "individual",
|
|
50
|
+
fadeEasing: options.fadeEasing ?? (options.fadeMode === "grouped" ? "ease-in" : "linear"),
|
|
51
|
+
fadeDurationMs: options.fadeDurationMs ?? this.editor.options.laserFadeoutMs
|
|
52
|
+
},
|
|
53
|
+
fadeElapsed: 0,
|
|
54
|
+
totalPointsAtFadeStart: 0
|
|
55
|
+
};
|
|
56
|
+
this.sessions.set(id, session);
|
|
57
|
+
if (session.options.idleTimeoutMs > 0) {
|
|
58
|
+
this.resetIdleTimeout(session);
|
|
59
|
+
}
|
|
60
|
+
return id;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Add a scribble to a session.
|
|
64
|
+
*
|
|
65
|
+
* @param sessionId - The session ID
|
|
66
|
+
* @param scribble - Partial scribble properties
|
|
67
|
+
* @param scribbleId - Optional scribble ID
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
addScribbleToSession(sessionId, scribble, scribbleId = (0, import_utils.uniqueId)()) {
|
|
71
|
+
const session = this.sessions.get(sessionId);
|
|
72
|
+
if (!session) throw Error(`Session ${sessionId} not found`);
|
|
73
|
+
const item = {
|
|
74
|
+
id: scribbleId,
|
|
35
75
|
scribble: {
|
|
36
|
-
id,
|
|
76
|
+
id: scribbleId,
|
|
37
77
|
size: 20,
|
|
38
78
|
color: "accent",
|
|
39
79
|
opacity: 0.8,
|
|
@@ -49,43 +89,187 @@ class ScribbleManager {
|
|
|
49
89
|
prev: null,
|
|
50
90
|
next: null
|
|
51
91
|
};
|
|
52
|
-
|
|
92
|
+
session.items.push(item);
|
|
93
|
+
if (session.options.idleTimeoutMs > 0) {
|
|
94
|
+
this.resetIdleTimeout(session);
|
|
95
|
+
}
|
|
53
96
|
return item;
|
|
54
97
|
}
|
|
55
|
-
reset() {
|
|
56
|
-
this.editor.updateInstanceState({ scribbles: [] });
|
|
57
|
-
this.scribbleItems.clear();
|
|
58
|
-
}
|
|
59
98
|
/**
|
|
60
|
-
*
|
|
99
|
+
* Add a point to a scribble in a session.
|
|
61
100
|
*
|
|
101
|
+
* @param sessionId - The session ID
|
|
102
|
+
* @param scribbleId - The scribble ID
|
|
103
|
+
* @param x - X coordinate
|
|
104
|
+
* @param y - Y coordinate
|
|
105
|
+
* @param z - Z coordinate (pressure)
|
|
62
106
|
* @public
|
|
63
107
|
*/
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
if (!
|
|
67
|
-
item
|
|
68
|
-
item
|
|
108
|
+
addPointToSession(sessionId, scribbleId, x, y, z = 0.5) {
|
|
109
|
+
const session = this.sessions.get(sessionId);
|
|
110
|
+
if (!session) throw Error(`Session ${sessionId} not found`);
|
|
111
|
+
const item = session.items.find((i) => i.id === scribbleId);
|
|
112
|
+
if (!item) throw Error(`Scribble ${scribbleId} not found in session ${sessionId}`);
|
|
113
|
+
const point = { x, y, z };
|
|
114
|
+
if (!item.prev || import_Vec.Vec.Dist(item.prev, point) >= 1) {
|
|
115
|
+
item.next = point;
|
|
116
|
+
}
|
|
117
|
+
if (session.options.idleTimeoutMs > 0) {
|
|
118
|
+
this.resetIdleTimeout(session);
|
|
119
|
+
}
|
|
69
120
|
return item;
|
|
70
121
|
}
|
|
71
122
|
/**
|
|
72
|
-
*
|
|
123
|
+
* Extend a session, resetting its idle timeout.
|
|
73
124
|
*
|
|
74
|
-
* @param
|
|
75
|
-
* @
|
|
76
|
-
|
|
77
|
-
|
|
125
|
+
* @param sessionId - The session ID
|
|
126
|
+
* @public
|
|
127
|
+
*/
|
|
128
|
+
extendSession(sessionId) {
|
|
129
|
+
const session = this.sessions.get(sessionId);
|
|
130
|
+
if (!session) return;
|
|
131
|
+
if (session.options.idleTimeoutMs > 0) {
|
|
132
|
+
this.resetIdleTimeout(session);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Stop a session, triggering fade-out.
|
|
137
|
+
*
|
|
138
|
+
* @param sessionId - The session ID
|
|
139
|
+
* @public
|
|
140
|
+
*/
|
|
141
|
+
stopSession(sessionId) {
|
|
142
|
+
const session = this.sessions.get(sessionId);
|
|
143
|
+
if (!session || session.state !== "active") return;
|
|
144
|
+
this.clearIdleTimeout(session);
|
|
145
|
+
session.state = "stopping";
|
|
146
|
+
if (session.options.fadeMode === "grouped") {
|
|
147
|
+
session.totalPointsAtFadeStart = session.items.reduce(
|
|
148
|
+
(sum, item) => sum + item.scribble.points.length,
|
|
149
|
+
0
|
|
150
|
+
);
|
|
151
|
+
session.fadeElapsed = 0;
|
|
152
|
+
for (const item of session.items) {
|
|
153
|
+
item.scribble.state = "stopping";
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
for (const item of session.items) {
|
|
157
|
+
item.delayRemaining = Math.min(item.delayRemaining, 200);
|
|
158
|
+
item.scribble.state = "stopping";
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Clear all scribbles in a session immediately.
|
|
164
|
+
*
|
|
165
|
+
* @param sessionId - The session ID
|
|
166
|
+
* @public
|
|
167
|
+
*/
|
|
168
|
+
clearSession(sessionId) {
|
|
169
|
+
const session = this.sessions.get(sessionId);
|
|
170
|
+
if (!session) return;
|
|
171
|
+
this.clearIdleTimeout(session);
|
|
172
|
+
for (const item of session.items) {
|
|
173
|
+
item.scribble.points.length = 0;
|
|
174
|
+
}
|
|
175
|
+
session.state = "complete";
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check if a session is active.
|
|
179
|
+
*
|
|
180
|
+
* @param sessionId - The session ID
|
|
181
|
+
* @public
|
|
182
|
+
*/
|
|
183
|
+
isSessionActive(sessionId) {
|
|
184
|
+
const session = this.sessions.get(sessionId);
|
|
185
|
+
return session?.state === "active";
|
|
186
|
+
}
|
|
187
|
+
// ==================== SIMPLE API (for eraser, select, etc.) ====================
|
|
188
|
+
/**
|
|
189
|
+
* Add a scribble using the default self-consuming behavior.
|
|
190
|
+
* Creates an implicit session for the scribble.
|
|
191
|
+
*
|
|
192
|
+
* @param scribble - Partial scribble properties
|
|
193
|
+
* @param id - Optional scribble id
|
|
194
|
+
* @returns The created scribble item
|
|
195
|
+
* @public
|
|
196
|
+
*/
|
|
197
|
+
addScribble(scribble, id = (0, import_utils.uniqueId)()) {
|
|
198
|
+
const sessionId = this.startSession();
|
|
199
|
+
return this.addScribbleToSession(sessionId, scribble, id);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Add a point to a scribble. Searches all sessions.
|
|
203
|
+
*
|
|
204
|
+
* @param id - The scribble id
|
|
205
|
+
* @param x - X coordinate
|
|
206
|
+
* @param y - Y coordinate
|
|
207
|
+
* @param z - Z coordinate (pressure)
|
|
78
208
|
* @public
|
|
79
209
|
*/
|
|
80
210
|
addPoint(id, x, y, z = 0.5) {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
211
|
+
for (const session of this.sessions.values()) {
|
|
212
|
+
const item = session.items.find((i) => i.id === id);
|
|
213
|
+
if (item) {
|
|
214
|
+
const point = { x, y, z };
|
|
215
|
+
if (!item.prev || import_Vec.Vec.Dist(item.prev, point) >= 1) {
|
|
216
|
+
item.next = point;
|
|
217
|
+
}
|
|
218
|
+
if (session.options.idleTimeoutMs > 0) {
|
|
219
|
+
this.resetIdleTimeout(session);
|
|
220
|
+
}
|
|
221
|
+
return item;
|
|
222
|
+
}
|
|
87
223
|
}
|
|
88
|
-
|
|
224
|
+
throw Error(`Scribble with id ${id} not found`);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Mark a scribble as complete (done being drawn but not yet fading).
|
|
228
|
+
* Searches all sessions.
|
|
229
|
+
*
|
|
230
|
+
* @param id - The scribble id
|
|
231
|
+
* @public
|
|
232
|
+
*/
|
|
233
|
+
complete(id) {
|
|
234
|
+
for (const session of this.sessions.values()) {
|
|
235
|
+
const item = session.items.find((i) => i.id === id);
|
|
236
|
+
if (item) {
|
|
237
|
+
if (item.scribble.state === "starting" || item.scribble.state === "active") {
|
|
238
|
+
item.scribble.state = "complete";
|
|
239
|
+
}
|
|
240
|
+
return item;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
throw Error(`Scribble with id ${id} not found`);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Stop a scribble. Searches all sessions.
|
|
247
|
+
*
|
|
248
|
+
* @param id - The scribble id
|
|
249
|
+
* @public
|
|
250
|
+
*/
|
|
251
|
+
stop(id) {
|
|
252
|
+
for (const session of this.sessions.values()) {
|
|
253
|
+
const item = session.items.find((i) => i.id === id);
|
|
254
|
+
if (item) {
|
|
255
|
+
item.delayRemaining = Math.min(item.delayRemaining, 200);
|
|
256
|
+
item.scribble.state = "stopping";
|
|
257
|
+
return item;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
throw Error(`Scribble with id ${id} not found`);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Stop and remove all sessions.
|
|
264
|
+
*
|
|
265
|
+
* @public
|
|
266
|
+
*/
|
|
267
|
+
reset() {
|
|
268
|
+
for (const session of this.sessions.values()) {
|
|
269
|
+
this.clearIdleTimeout(session);
|
|
270
|
+
}
|
|
271
|
+
this.sessions.clear();
|
|
272
|
+
this.editor.updateInstanceState({ scribbles: [] });
|
|
89
273
|
}
|
|
90
274
|
/**
|
|
91
275
|
* Update on each animation frame.
|
|
@@ -94,77 +278,182 @@ class ScribbleManager {
|
|
|
94
278
|
* @public
|
|
95
279
|
*/
|
|
96
280
|
tick(elapsed) {
|
|
97
|
-
|
|
281
|
+
const currentScribbles = this.editor.getInstanceState().scribbles;
|
|
282
|
+
if (this.sessions.size === 0 && currentScribbles.length === 0) return;
|
|
98
283
|
this.editor.run(() => {
|
|
99
|
-
this.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (item.scribble.points.length > 8) {
|
|
107
|
-
item.scribble.state = "active";
|
|
108
|
-
}
|
|
109
|
-
return;
|
|
284
|
+
for (const session of this.sessions.values()) {
|
|
285
|
+
this.tickSession(session, elapsed);
|
|
286
|
+
}
|
|
287
|
+
for (const [id, session] of this.sessions) {
|
|
288
|
+
if (session.state === "complete") {
|
|
289
|
+
this.clearIdleTimeout(session);
|
|
290
|
+
this.sessions.delete(id);
|
|
110
291
|
}
|
|
111
|
-
|
|
112
|
-
|
|
292
|
+
}
|
|
293
|
+
const scribbles = [];
|
|
294
|
+
for (const session of this.sessions.values()) {
|
|
295
|
+
for (const item of session.items) {
|
|
296
|
+
if (item.scribble.points.length > 0) {
|
|
297
|
+
scribbles.push({
|
|
298
|
+
...item.scribble,
|
|
299
|
+
points: [...item.scribble.points]
|
|
300
|
+
});
|
|
301
|
+
}
|
|
113
302
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
303
|
+
}
|
|
304
|
+
this.editor.updateInstanceState({ scribbles });
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
// ==================== PRIVATE HELPERS ====================
|
|
308
|
+
resetIdleTimeout(session) {
|
|
309
|
+
this.clearIdleTimeout(session);
|
|
310
|
+
session.idleTimeoutHandle = this.editor.timers.setTimeout(() => {
|
|
311
|
+
this.stopSession(session.id);
|
|
312
|
+
}, session.options.idleTimeoutMs);
|
|
313
|
+
}
|
|
314
|
+
clearIdleTimeout(session) {
|
|
315
|
+
if (session.idleTimeoutHandle !== void 0) {
|
|
316
|
+
clearTimeout(session.idleTimeoutHandle);
|
|
317
|
+
session.idleTimeoutHandle = void 0;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
tickSession(session, elapsed) {
|
|
321
|
+
if (session.state === "complete") return;
|
|
322
|
+
if (session.state === "stopping" && session.options.fadeMode === "grouped") {
|
|
323
|
+
this.tickGroupedFade(session, elapsed);
|
|
324
|
+
} else {
|
|
325
|
+
this.tickSessionItems(session, elapsed);
|
|
326
|
+
}
|
|
327
|
+
const hasContent = session.items.some((item) => item.scribble.points.length > 0);
|
|
328
|
+
if (!hasContent && (session.state === "stopping" || session.items.length === 0)) {
|
|
329
|
+
session.state = "complete";
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
tickSessionItems(session, elapsed) {
|
|
333
|
+
for (const item of session.items) {
|
|
334
|
+
const shouldSelfConsume = session.options.selfConsume || session.state === "stopping" || item.scribble.state === "stopping";
|
|
335
|
+
if (shouldSelfConsume) {
|
|
336
|
+
this.tickSelfConsumingItem(item, elapsed);
|
|
337
|
+
} else {
|
|
338
|
+
this.tickPersistentItem(item);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
if (session.options.fadeMode === "individual") {
|
|
342
|
+
for (let i = session.items.length - 1; i >= 0; i--) {
|
|
343
|
+
if (session.items[i].scribble.points.length === 0) {
|
|
344
|
+
session.items.splice(i, 1);
|
|
117
345
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
tickPersistentItem(item) {
|
|
350
|
+
const { scribble } = item;
|
|
351
|
+
if (scribble.state === "starting") {
|
|
352
|
+
const { next, prev } = item;
|
|
353
|
+
if (next && next !== prev) {
|
|
354
|
+
item.prev = next;
|
|
355
|
+
scribble.points.push(next);
|
|
356
|
+
}
|
|
357
|
+
if (scribble.points.length > 8) {
|
|
358
|
+
scribble.state = "active";
|
|
359
|
+
}
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (scribble.state === "active") {
|
|
363
|
+
const { next, prev } = item;
|
|
364
|
+
if (next && next !== prev) {
|
|
365
|
+
item.prev = next;
|
|
366
|
+
scribble.points.push(next);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
tickSelfConsumingItem(item, elapsed) {
|
|
371
|
+
const { scribble } = item;
|
|
372
|
+
if (scribble.state === "starting") {
|
|
373
|
+
const { next: next2, prev: prev2 } = item;
|
|
374
|
+
if (next2 && next2 !== prev2) {
|
|
375
|
+
item.prev = next2;
|
|
376
|
+
scribble.points.push(next2);
|
|
377
|
+
}
|
|
378
|
+
if (scribble.points.length > 8) {
|
|
379
|
+
scribble.state = "active";
|
|
380
|
+
}
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (item.delayRemaining > 0) {
|
|
384
|
+
item.delayRemaining = Math.max(0, item.delayRemaining - elapsed);
|
|
385
|
+
}
|
|
386
|
+
item.timeoutMs += elapsed;
|
|
387
|
+
if (item.timeoutMs >= 16) {
|
|
388
|
+
item.timeoutMs = 0;
|
|
389
|
+
}
|
|
390
|
+
const { delayRemaining, timeoutMs, prev, next } = item;
|
|
391
|
+
switch (scribble.state) {
|
|
392
|
+
case "active": {
|
|
393
|
+
if (next && next !== prev) {
|
|
394
|
+
item.prev = next;
|
|
395
|
+
scribble.points.push(next);
|
|
396
|
+
if (delayRemaining === 0 && scribble.points.length > 8) {
|
|
397
|
+
scribble.points.shift();
|
|
398
|
+
}
|
|
399
|
+
} else {
|
|
400
|
+
if (timeoutMs === 0) {
|
|
401
|
+
if (scribble.points.length > 1) {
|
|
402
|
+
scribble.points.shift();
|
|
129
403
|
} else {
|
|
130
|
-
|
|
131
|
-
if (scribble.points.length > 1) {
|
|
132
|
-
scribble.points.shift();
|
|
133
|
-
} else {
|
|
134
|
-
item.delayRemaining = scribble.delay;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
404
|
+
item.delayRemaining = scribble.delay;
|
|
137
405
|
}
|
|
138
|
-
break;
|
|
139
406
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
scribble.size = Math.max(1, scribble.size * (1 - scribble.shrink));
|
|
149
|
-
}
|
|
150
|
-
scribble.points.shift();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
break;
|
|
407
|
+
}
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
case "stopping": {
|
|
411
|
+
if (delayRemaining === 0 && timeoutMs === 0) {
|
|
412
|
+
if (scribble.points.length <= 1) {
|
|
413
|
+
scribble.points.length = 0;
|
|
414
|
+
return;
|
|
154
415
|
}
|
|
155
|
-
|
|
156
|
-
|
|
416
|
+
if (scribble.shrink) {
|
|
417
|
+
scribble.size = Math.max(1, scribble.size * (1 - scribble.shrink));
|
|
157
418
|
}
|
|
419
|
+
scribble.points.shift();
|
|
158
420
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
case "paused": {
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
tickGroupedFade(session, elapsed) {
|
|
429
|
+
session.fadeElapsed += elapsed;
|
|
430
|
+
let remainingPoints = 0;
|
|
431
|
+
for (const item of session.items) {
|
|
432
|
+
remainingPoints += item.scribble.points.length;
|
|
433
|
+
}
|
|
434
|
+
if (remainingPoints === 0) return;
|
|
435
|
+
if (session.fadeElapsed >= session.options.fadeDurationMs) {
|
|
436
|
+
for (const item of session.items) {
|
|
437
|
+
item.scribble.points.length = 0;
|
|
438
|
+
}
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
const progress = session.fadeElapsed / session.options.fadeDurationMs;
|
|
442
|
+
const easedProgress = session.options.fadeEasing === "ease-in" ? progress * progress : progress;
|
|
443
|
+
const targetRemoved = Math.floor(easedProgress * session.totalPointsAtFadeStart);
|
|
444
|
+
const actuallyRemoved = session.totalPointsAtFadeStart - remainingPoints;
|
|
445
|
+
const pointsToRemove = Math.max(1, targetRemoved - actuallyRemoved);
|
|
446
|
+
let removed = 0;
|
|
447
|
+
let itemIndex = 0;
|
|
448
|
+
while (removed < pointsToRemove && itemIndex < session.items.length) {
|
|
449
|
+
const item = session.items[itemIndex];
|
|
450
|
+
if (item.scribble.points.length > 0) {
|
|
451
|
+
item.scribble.points.shift();
|
|
452
|
+
removed++;
|
|
453
|
+
} else {
|
|
454
|
+
itemIndex++;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
168
457
|
}
|
|
169
458
|
}
|
|
170
459
|
//# sourceMappingURL=ScribbleManager.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/managers/ScribbleManager/ScribbleManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { TLScribble, VecModel } from '@tldraw/tlschema'\nimport { uniqueId } from '@tldraw/utils'\nimport { Vec } from '../../../primitives/Vec'\nimport { Editor } from '../../Editor'\n\n/** @public */\nexport interface ScribbleItem {\n\tid: string\n\tscribble: TLScribble\n\ttimeoutMs: number\n\tdelayRemaining: number\n\tprev: null | VecModel\n\tnext: null | VecModel\n}\n\n/** @public */\nexport class ScribbleManager {\n\tscribbleItems = new Map<string, ScribbleItem>()\n\tstate = 'paused' as 'paused' | 'running'\n\n\tconstructor(private editor: Editor) {}\n\n\taddScribble(scribble: Partial<TLScribble>, id = uniqueId()) {\n\t\tconst item: ScribbleItem = {\n\t\t\tid,\n\t\t\tscribble: {\n\t\t\t\tid,\n\t\t\t\tsize: 20,\n\t\t\t\tcolor: 'accent',\n\t\t\t\topacity: 0.8,\n\t\t\t\tdelay: 0,\n\t\t\t\tpoints: [],\n\t\t\t\tshrink: 0.1,\n\t\t\t\ttaper: true,\n\t\t\t\t...scribble,\n\t\t\t\tstate: 'starting',\n\t\t\t},\n\t\t\ttimeoutMs: 0,\n\t\t\tdelayRemaining: scribble.delay ?? 0,\n\t\t\tprev: null,\n\t\t\tnext: null,\n\t\t}\n\t\tthis.scribbleItems.set(id, item)\n\t\treturn item\n\t}\n\n\treset() {\n\t\tthis.editor.updateInstanceState({ scribbles: [] })\n\t\tthis.scribbleItems.clear()\n\t}\n\n\t/**\n\t * Start stopping the scribble. The scribble won't be removed until its last point is cleared.\n\t *\n\t * @public\n\t */\n\tstop(id: ScribbleItem['id']) {\n\t\tconst item = this.scribbleItems.get(id)\n\t\tif (!item) throw Error(`Scribble with id ${id} not found`)\n\t\titem.delayRemaining = Math.min(item.delayRemaining, 200)\n\t\titem.scribble.state = 'stopping'\n\t\treturn item\n\t}\n\n\t/**\n\t * Set the scribble's next point.\n\t *\n\t * @param id - The id of the scribble to add a point to.\n\t * @param x - The x coordinate of the point.\n\t * @param y - The y coordinate of the point.\n\t * @param z - The z coordinate of the point.\n\t * @public\n\t */\n\taddPoint(id: ScribbleItem['id'], x: number, y: number, z = 0.5) {\n\t\tconst item = this.scribbleItems.get(id)\n\t\tif (!item) throw Error(`Scribble with id ${id} not found`)\n\t\tconst { prev } = item\n\t\tconst point = { x, y, z }\n\t\tif (!prev || Vec.Dist(prev, point) >= 1) {\n\t\t\titem.next = point\n\t\t}\n\t\treturn item\n\t}\n\n\t/**\n\t * Update on each animation frame.\n\t *\n\t * @param elapsed - The number of milliseconds since the last tick.\n\t * @public\n\t */\n\ttick(elapsed: number) {\n\t\tif (this.scribbleItems.size === 0) return\n\t\tthis.editor.run(() => {\n\t\t\tthis.scribbleItems.forEach((item) => {\n\t\t\t\t// let the item get at least eight points before\n\t\t\t\t// switching from starting to active\n\t\t\t\tif (item.scribble.state === 'starting') {\n\t\t\t\t\tconst { next, prev } = item\n\t\t\t\t\tif (next && next !== prev) {\n\t\t\t\t\t\titem.prev = next\n\t\t\t\t\t\titem.scribble.points.push(next)\n\t\t\t\t\t}\n\n\t\t\t\t\tif (item.scribble.points.length > 8) {\n\t\t\t\t\t\titem.scribble.state = 'active'\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (item.delayRemaining > 0) {\n\t\t\t\t\titem.delayRemaining = Math.max(0, item.delayRemaining - elapsed)\n\t\t\t\t}\n\n\t\t\t\titem.timeoutMs += elapsed\n\t\t\t\tif (item.timeoutMs >= 16) {\n\t\t\t\t\titem.timeoutMs = 0\n\t\t\t\t}\n\n\t\t\t\tconst { delayRemaining, timeoutMs, prev, next, scribble } = item\n\n\t\t\t\tswitch (scribble.state) {\n\t\t\t\t\tcase 'active': {\n\t\t\t\t\t\tif (next && next !== prev) {\n\t\t\t\t\t\t\titem.prev = next\n\t\t\t\t\t\t\tscribble.points.push(next)\n\n\t\t\t\t\t\t\t// If we've run out of delay, then shrink the scribble from the start\n\t\t\t\t\t\t\tif (delayRemaining === 0) {\n\t\t\t\t\t\t\t\tif (scribble.points.length > 8) {\n\t\t\t\t\t\t\t\t\tscribble.points.shift()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// While not moving, shrink the scribble from the start\n\t\t\t\t\t\t\tif (timeoutMs === 0) {\n\t\t\t\t\t\t\t\tif (scribble.points.length > 1) {\n\t\t\t\t\t\t\t\t\tscribble.points.shift()\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// Reset the item's delay\n\t\t\t\t\t\t\t\t\titem.delayRemaining = scribble.delay\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'stopping': {\n\t\t\t\t\t\tif (item.delayRemaining === 0) {\n\t\t\t\t\t\t\tif (timeoutMs === 0) {\n\t\t\t\t\t\t\t\t// If the scribble is down to one point, we're done!\n\t\t\t\t\t\t\t\tif (scribble.points.length === 1) {\n\t\t\t\t\t\t\t\t\tthis.scribbleItems.delete(item.id) // Remove the scribble\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (scribble.shrink) {\n\t\t\t\t\t\t\t\t\t// Drop the scribble's size as it shrinks\n\t\t\t\t\t\t\t\t\tscribble.size = Math.max(1, scribble.size * (1 - scribble.shrink))\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Drop the scribble's first point (its tail)\n\t\t\t\t\t\t\t\tscribble.points.shift()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'paused': {\n\t\t\t\t\t\t// Nothing to do while paused.\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// The object here will get frozen into the record, so we need to\n\t\t\t// create a copies of the parts that what we'll be mutating later.\n\t\t\tthis.editor.updateInstanceState({\n\t\t\t\tscribbles: Array.from(this.scribbleItems.values())\n\t\t\t\t\t.map(({ scribble }) => ({\n\t\t\t\t\t\t...scribble,\n\t\t\t\t\t\tpoints: [...scribble.points],\n\t\t\t\t\t}))\n\t\t\t\t\t.slice(-5), // limit to three as a minor sanity check\n\t\t\t})\n\t\t})\n\t}\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAyB;AACzB,iBAAoB;
|
|
4
|
+
"sourcesContent": ["import { TLScribble, VecModel } from '@tldraw/tlschema'\nimport { uniqueId } from '@tldraw/utils'\nimport { Vec } from '../../../primitives/Vec'\nimport { Editor } from '../../Editor'\n\n/** @public */\nexport interface ScribbleItem {\n\tid: string\n\tscribble: TLScribble\n\ttimeoutMs: number\n\tdelayRemaining: number\n\tprev: null | VecModel\n\tnext: null | VecModel\n}\n\n/** @public */\nexport interface ScribbleSessionOptions {\n\t/** Session id. Auto-generated if not provided. */\n\tid?: string\n\t/**\n\t * Whether scribbles self-consume (shrink from start) while drawing.\n\t * - true: scribbles eat their own tail as you draw (default, used for eraser/select)\n\t * - false: scribbles persist until session stops (used for laser)\n\t */\n\tselfConsume?: boolean\n\t/**\n\t * How long to wait after last activity before auto-stopping the session.\n\t * Only applies when selfConsume is false.\n\t */\n\tidleTimeoutMs?: number\n\t/**\n\t * How scribbles fade when stopping.\n\t * - 'individual': each scribble fades on its own (default)\n\t * - 'grouped': all scribbles fade together as one sequence\n\t */\n\tfadeMode?: 'individual' | 'grouped'\n\t/**\n\t * Easing for grouped fade.\n\t */\n\tfadeEasing?: 'linear' | 'ease-in'\n\t/**\n\t * Duration of the fade in milliseconds.\n\t */\n\tfadeDurationMs?: number\n}\n\n// Internal session state (not exported)\ninterface Session {\n\tid: string\n\titems: ScribbleItem[]\n\tstate: 'active' | 'stopping' | 'complete'\n\toptions: Required<Omit<ScribbleSessionOptions, 'id'>>\n\tidleTimeoutHandle?: number\n\tfadeElapsed: number\n\ttotalPointsAtFadeStart: number\n}\n\n/** @public */\nexport class ScribbleManager {\n\tprivate sessions = new Map<string, Session>()\n\n\tconstructor(private editor: Editor) {}\n\n\t// ==================== SESSION API ====================\n\n\t/**\n\t * Start a new session for grouping scribbles.\n\t * Returns a session ID that can be used with other session methods.\n\t *\n\t * @param options - Session configuration\n\t * @returns Session ID\n\t * @public\n\t */\n\tstartSession(options: ScribbleSessionOptions = {}): string {\n\t\tconst id = options.id ?? uniqueId()\n\t\tconst session: Session = {\n\t\t\tid,\n\t\t\titems: [],\n\t\t\tstate: 'active',\n\t\t\toptions: {\n\t\t\t\tselfConsume: options.selfConsume ?? true,\n\t\t\t\tidleTimeoutMs: options.idleTimeoutMs ?? 0,\n\t\t\t\tfadeMode: options.fadeMode ?? 'individual',\n\t\t\t\tfadeEasing: options.fadeEasing ?? (options.fadeMode === 'grouped' ? 'ease-in' : 'linear'),\n\t\t\t\tfadeDurationMs: options.fadeDurationMs ?? this.editor.options.laserFadeoutMs,\n\t\t\t},\n\t\t\tfadeElapsed: 0,\n\t\t\ttotalPointsAtFadeStart: 0,\n\t\t}\n\n\t\tthis.sessions.set(id, session)\n\n\t\t// Set up idle timeout if configured\n\t\tif (session.options.idleTimeoutMs > 0) {\n\t\t\tthis.resetIdleTimeout(session)\n\t\t}\n\n\t\treturn id\n\t}\n\n\t/**\n\t * Add a scribble to a session.\n\t *\n\t * @param sessionId - The session ID\n\t * @param scribble - Partial scribble properties\n\t * @param scribbleId - Optional scribble ID\n\t * @public\n\t */\n\taddScribbleToSession(\n\t\tsessionId: string,\n\t\tscribble: Partial<TLScribble>,\n\t\tscribbleId = uniqueId()\n\t): ScribbleItem {\n\t\tconst session = this.sessions.get(sessionId)\n\t\tif (!session) throw Error(`Session ${sessionId} not found`)\n\n\t\tconst item: ScribbleItem = {\n\t\t\tid: scribbleId,\n\t\t\tscribble: {\n\t\t\t\tid: scribbleId,\n\t\t\t\tsize: 20,\n\t\t\t\tcolor: 'accent',\n\t\t\t\topacity: 0.8,\n\t\t\t\tdelay: 0,\n\t\t\t\tpoints: [],\n\t\t\t\tshrink: 0.1,\n\t\t\t\ttaper: true,\n\t\t\t\t...scribble,\n\t\t\t\tstate: 'starting',\n\t\t\t},\n\t\t\ttimeoutMs: 0,\n\t\t\tdelayRemaining: scribble.delay ?? 0,\n\t\t\tprev: null,\n\t\t\tnext: null,\n\t\t}\n\n\t\tsession.items.push(item)\n\n\t\t// Reset idle timeout on activity\n\t\tif (session.options.idleTimeoutMs > 0) {\n\t\t\tthis.resetIdleTimeout(session)\n\t\t}\n\n\t\treturn item\n\t}\n\n\t/**\n\t * Add a point to a scribble in a session.\n\t *\n\t * @param sessionId - The session ID\n\t * @param scribbleId - The scribble ID\n\t * @param x - X coordinate\n\t * @param y - Y coordinate\n\t * @param z - Z coordinate (pressure)\n\t * @public\n\t */\n\taddPointToSession(\n\t\tsessionId: string,\n\t\tscribbleId: string,\n\t\tx: number,\n\t\ty: number,\n\t\tz = 0.5\n\t): ScribbleItem {\n\t\tconst session = this.sessions.get(sessionId)\n\t\tif (!session) throw Error(`Session ${sessionId} not found`)\n\n\t\tconst item = session.items.find((i) => i.id === scribbleId)\n\t\tif (!item) throw Error(`Scribble ${scribbleId} not found in session ${sessionId}`)\n\n\t\tconst point = { x, y, z }\n\t\tif (!item.prev || Vec.Dist(item.prev, point) >= 1) {\n\t\t\titem.next = point\n\t\t}\n\n\t\t// Reset idle timeout on activity\n\t\tif (session.options.idleTimeoutMs > 0) {\n\t\t\tthis.resetIdleTimeout(session)\n\t\t}\n\n\t\treturn item\n\t}\n\n\t/**\n\t * Extend a session, resetting its idle timeout.\n\t *\n\t * @param sessionId - The session ID\n\t * @public\n\t */\n\textendSession(sessionId: string): void {\n\t\tconst session = this.sessions.get(sessionId)\n\t\tif (!session) return\n\n\t\tif (session.options.idleTimeoutMs > 0) {\n\t\t\tthis.resetIdleTimeout(session)\n\t\t}\n\t}\n\n\t/**\n\t * Stop a session, triggering fade-out.\n\t *\n\t * @param sessionId - The session ID\n\t * @public\n\t */\n\tstopSession(sessionId: string): void {\n\t\tconst session = this.sessions.get(sessionId)\n\t\tif (!session || session.state !== 'active') return\n\n\t\tthis.clearIdleTimeout(session)\n\t\tsession.state = 'stopping'\n\n\t\tif (session.options.fadeMode === 'grouped') {\n\t\t\tsession.totalPointsAtFadeStart = session.items.reduce(\n\t\t\t\t(sum, item) => sum + item.scribble.points.length,\n\t\t\t\t0\n\t\t\t)\n\t\t\tsession.fadeElapsed = 0\n\t\t\tfor (const item of session.items) {\n\t\t\t\titem.scribble.state = 'stopping'\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const item of session.items) {\n\t\t\t\titem.delayRemaining = Math.min(item.delayRemaining, 200)\n\t\t\t\titem.scribble.state = 'stopping'\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Clear all scribbles in a session immediately.\n\t *\n\t * @param sessionId - The session ID\n\t * @public\n\t */\n\tclearSession(sessionId: string): void {\n\t\tconst session = this.sessions.get(sessionId)\n\t\tif (!session) return\n\n\t\tthis.clearIdleTimeout(session)\n\t\tfor (const item of session.items) {\n\t\t\titem.scribble.points.length = 0\n\t\t}\n\t\tsession.state = 'complete'\n\t}\n\n\t/**\n\t * Check if a session is active.\n\t *\n\t * @param sessionId - The session ID\n\t * @public\n\t */\n\tisSessionActive(sessionId: string): boolean {\n\t\tconst session = this.sessions.get(sessionId)\n\t\treturn session?.state === 'active'\n\t}\n\n\t// ==================== SIMPLE API (for eraser, select, etc.) ====================\n\n\t/**\n\t * Add a scribble using the default self-consuming behavior.\n\t * Creates an implicit session for the scribble.\n\t *\n\t * @param scribble - Partial scribble properties\n\t * @param id - Optional scribble id\n\t * @returns The created scribble item\n\t * @public\n\t */\n\taddScribble(scribble: Partial<TLScribble>, id = uniqueId()): ScribbleItem {\n\t\tconst sessionId = this.startSession()\n\t\treturn this.addScribbleToSession(sessionId, scribble, id)\n\t}\n\n\t/**\n\t * Add a point to a scribble. Searches all sessions.\n\t *\n\t * @param id - The scribble id\n\t * @param x - X coordinate\n\t * @param y - Y coordinate\n\t * @param z - Z coordinate (pressure)\n\t * @public\n\t */\n\taddPoint(id: string, x: number, y: number, z = 0.5): ScribbleItem {\n\t\tfor (const session of this.sessions.values()) {\n\t\t\tconst item = session.items.find((i) => i.id === id)\n\t\t\tif (item) {\n\t\t\t\tconst point = { x, y, z }\n\t\t\t\tif (!item.prev || Vec.Dist(item.prev, point) >= 1) {\n\t\t\t\t\titem.next = point\n\t\t\t\t}\n\t\t\t\tif (session.options.idleTimeoutMs > 0) {\n\t\t\t\t\tthis.resetIdleTimeout(session)\n\t\t\t\t}\n\t\t\t\treturn item\n\t\t\t}\n\t\t}\n\t\tthrow Error(`Scribble with id ${id} not found`)\n\t}\n\n\t/**\n\t * Mark a scribble as complete (done being drawn but not yet fading).\n\t * Searches all sessions.\n\t *\n\t * @param id - The scribble id\n\t * @public\n\t */\n\tcomplete(id: string): ScribbleItem {\n\t\tfor (const session of this.sessions.values()) {\n\t\t\tconst item = session.items.find((i) => i.id === id)\n\t\t\tif (item) {\n\t\t\t\tif (item.scribble.state === 'starting' || item.scribble.state === 'active') {\n\t\t\t\t\titem.scribble.state = 'complete'\n\t\t\t\t}\n\t\t\t\treturn item\n\t\t\t}\n\t\t}\n\t\tthrow Error(`Scribble with id ${id} not found`)\n\t}\n\n\t/**\n\t * Stop a scribble. Searches all sessions.\n\t *\n\t * @param id - The scribble id\n\t * @public\n\t */\n\tstop(id: string): ScribbleItem {\n\t\tfor (const session of this.sessions.values()) {\n\t\t\tconst item = session.items.find((i) => i.id === id)\n\t\t\tif (item) {\n\t\t\t\titem.delayRemaining = Math.min(item.delayRemaining, 200)\n\t\t\t\titem.scribble.state = 'stopping'\n\t\t\t\treturn item\n\t\t\t}\n\t\t}\n\t\tthrow Error(`Scribble with id ${id} not found`)\n\t}\n\n\t/**\n\t * Stop and remove all sessions.\n\t *\n\t * @public\n\t */\n\treset(): void {\n\t\tfor (const session of this.sessions.values()) {\n\t\t\tthis.clearIdleTimeout(session)\n\t\t}\n\t\tthis.sessions.clear()\n\t\tthis.editor.updateInstanceState({ scribbles: [] })\n\t}\n\n\t/**\n\t * Update on each animation frame.\n\t *\n\t * @param elapsed - The number of milliseconds since the last tick.\n\t * @public\n\t */\n\ttick(elapsed: number): void {\n\t\tconst currentScribbles = this.editor.getInstanceState().scribbles\n\t\tif (this.sessions.size === 0 && currentScribbles.length === 0) return\n\n\t\tthis.editor.run(() => {\n\t\t\t// Tick all sessions\n\t\t\tfor (const session of this.sessions.values()) {\n\t\t\t\tthis.tickSession(session, elapsed)\n\t\t\t}\n\n\t\t\t// Remove completed sessions\n\t\t\tfor (const [id, session] of this.sessions) {\n\t\t\t\tif (session.state === 'complete') {\n\t\t\t\t\tthis.clearIdleTimeout(session)\n\t\t\t\t\tthis.sessions.delete(id)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Collect scribbles from all sessions\n\t\t\tconst scribbles: TLScribble[] = []\n\t\t\tfor (const session of this.sessions.values()) {\n\t\t\t\tfor (const item of session.items) {\n\t\t\t\t\tif (item.scribble.points.length > 0) {\n\t\t\t\t\t\tscribbles.push({\n\t\t\t\t\t\t\t...item.scribble,\n\t\t\t\t\t\t\tpoints: [...item.scribble.points],\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.editor.updateInstanceState({ scribbles })\n\t\t})\n\t}\n\n\t// ==================== PRIVATE HELPERS ====================\n\n\tprivate resetIdleTimeout(session: Session): void {\n\t\tthis.clearIdleTimeout(session)\n\t\tsession.idleTimeoutHandle = this.editor.timers.setTimeout(() => {\n\t\t\tthis.stopSession(session.id)\n\t\t}, session.options.idleTimeoutMs)\n\t}\n\n\tprivate clearIdleTimeout(session: Session): void {\n\t\tif (session.idleTimeoutHandle !== undefined) {\n\t\t\tclearTimeout(session.idleTimeoutHandle)\n\t\t\tsession.idleTimeoutHandle = undefined\n\t\t}\n\t}\n\n\tprivate tickSession(session: Session, elapsed: number): void {\n\t\tif (session.state === 'complete') return\n\n\t\tif (session.state === 'stopping' && session.options.fadeMode === 'grouped') {\n\t\t\tthis.tickGroupedFade(session, elapsed)\n\t\t} else {\n\t\t\tthis.tickSessionItems(session, elapsed)\n\t\t}\n\n\t\t// Check if session is complete\n\t\tconst hasContent = session.items.some((item) => item.scribble.points.length > 0)\n\t\tif (!hasContent && (session.state === 'stopping' || session.items.length === 0)) {\n\t\t\tsession.state = 'complete'\n\t\t}\n\t}\n\n\tprivate tickSessionItems(session: Session, elapsed: number): void {\n\t\tfor (const item of session.items) {\n\t\t\tconst shouldSelfConsume =\n\t\t\t\tsession.options.selfConsume ||\n\t\t\t\tsession.state === 'stopping' ||\n\t\t\t\titem.scribble.state === 'stopping'\n\n\t\t\tif (shouldSelfConsume) {\n\t\t\t\tthis.tickSelfConsumingItem(item, elapsed)\n\t\t\t} else {\n\t\t\t\tthis.tickPersistentItem(item)\n\t\t\t}\n\t\t}\n\n\t\t// Remove completed items in individual fade mode\n\t\tif (session.options.fadeMode === 'individual') {\n\t\t\tfor (let i = session.items.length - 1; i >= 0; i--) {\n\t\t\t\tif (session.items[i].scribble.points.length === 0) {\n\t\t\t\t\tsession.items.splice(i, 1)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate tickPersistentItem(item: ScribbleItem): void {\n\t\tconst { scribble } = item\n\n\t\tif (scribble.state === 'starting') {\n\t\t\tconst { next, prev } = item\n\t\t\tif (next && next !== prev) {\n\t\t\t\titem.prev = next\n\t\t\t\tscribble.points.push(next)\n\t\t\t}\n\t\t\tif (scribble.points.length > 8) {\n\t\t\t\tscribble.state = 'active'\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (scribble.state === 'active') {\n\t\t\tconst { next, prev } = item\n\t\t\tif (next && next !== prev) {\n\t\t\t\titem.prev = next\n\t\t\t\tscribble.points.push(next)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate tickSelfConsumingItem(item: ScribbleItem, elapsed: number): void {\n\t\tconst { scribble } = item\n\n\t\tif (scribble.state === 'starting') {\n\t\t\tconst { next, prev } = item\n\t\t\tif (next && next !== prev) {\n\t\t\t\titem.prev = next\n\t\t\t\tscribble.points.push(next)\n\t\t\t}\n\t\t\tif (scribble.points.length > 8) {\n\t\t\t\tscribble.state = 'active'\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (item.delayRemaining > 0) {\n\t\t\titem.delayRemaining = Math.max(0, item.delayRemaining - elapsed)\n\t\t}\n\n\t\titem.timeoutMs += elapsed\n\t\tif (item.timeoutMs >= 16) {\n\t\t\titem.timeoutMs = 0\n\t\t}\n\n\t\tconst { delayRemaining, timeoutMs, prev, next } = item\n\n\t\tswitch (scribble.state) {\n\t\t\tcase 'active': {\n\t\t\t\tif (next && next !== prev) {\n\t\t\t\t\titem.prev = next\n\t\t\t\t\tscribble.points.push(next)\n\t\t\t\t\tif (delayRemaining === 0 && scribble.points.length > 8) {\n\t\t\t\t\t\tscribble.points.shift()\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (timeoutMs === 0) {\n\t\t\t\t\t\tif (scribble.points.length > 1) {\n\t\t\t\t\t\t\tscribble.points.shift()\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\titem.delayRemaining = scribble.delay\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'stopping': {\n\t\t\t\tif (delayRemaining === 0 && timeoutMs === 0) {\n\t\t\t\t\tif (scribble.points.length <= 1) {\n\t\t\t\t\t\tscribble.points.length = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (scribble.shrink) {\n\t\t\t\t\t\tscribble.size = Math.max(1, scribble.size * (1 - scribble.shrink))\n\t\t\t\t\t}\n\t\t\t\t\tscribble.points.shift()\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'paused': {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate tickGroupedFade(session: Session, elapsed: number): void {\n\t\tsession.fadeElapsed += elapsed\n\n\t\tlet remainingPoints = 0\n\t\tfor (const item of session.items) {\n\t\t\tremainingPoints += item.scribble.points.length\n\t\t}\n\n\t\tif (remainingPoints === 0) return\n\n\t\tif (session.fadeElapsed >= session.options.fadeDurationMs) {\n\t\t\tfor (const item of session.items) {\n\t\t\t\titem.scribble.points.length = 0\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst progress = session.fadeElapsed / session.options.fadeDurationMs\n\t\tconst easedProgress = session.options.fadeEasing === 'ease-in' ? progress * progress : progress\n\n\t\tconst targetRemoved = Math.floor(easedProgress * session.totalPointsAtFadeStart)\n\t\tconst actuallyRemoved = session.totalPointsAtFadeStart - remainingPoints\n\t\tconst pointsToRemove = Math.max(1, targetRemoved - actuallyRemoved)\n\n\t\tlet removed = 0\n\t\tlet itemIndex = 0\n\t\twhile (removed < pointsToRemove && itemIndex < session.items.length) {\n\t\t\tconst item = session.items[itemIndex]\n\t\t\tif (item.scribble.points.length > 0) {\n\t\t\t\titem.scribble.points.shift()\n\t\t\t\tremoved++\n\t\t\t} else {\n\t\t\t\titemIndex++\n\t\t\t}\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["next", "prev"]
|
|
7
7
|
}
|
|
@@ -94,17 +94,16 @@ class SpatialIndexManager {
|
|
|
94
94
|
processedShapeIds.add(shape.id);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
for (const [
|
|
97
|
+
for (const [, to] of (0, import_utils.objectMapValues)(changes.updated)) {
|
|
98
98
|
if (!(0, import_tlschema.isShape)(to)) continue;
|
|
99
99
|
processedShapeIds.add(to.id);
|
|
100
|
-
const wasOnPage = this.editor.getAncestorPageId(from) === this.lastPageId;
|
|
101
100
|
const isOnPage = this.editor.getAncestorPageId(to) === this.lastPageId;
|
|
102
101
|
if (isOnPage) {
|
|
103
102
|
const bounds = this.editor.getShapePageBounds(to.id);
|
|
104
103
|
if (bounds) {
|
|
105
104
|
this.rbush.upsert(to.id, bounds);
|
|
106
105
|
}
|
|
107
|
-
} else
|
|
106
|
+
} else {
|
|
108
107
|
this.rbush.remove(to.id);
|
|
109
108
|
}
|
|
110
109
|
}
|