@myoc/excalidraw 0.19.511 → 0.19.512

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/dev/{chunk-WGF6T3RR.js → chunk-OBLRXIUK.js} +72 -16
  3. package/dist/dev/chunk-OBLRXIUK.js.map +7 -0
  4. package/dist/dev/{chunk-G3MPOS33.js → chunk-QHLG4OQL.js} +2 -2
  5. package/dist/dev/data/{image-UBAFGYUH.js → image-R7FQP7SA.js} +3 -3
  6. package/dist/dev/index.js +230 -224
  7. package/dist/dev/index.js.map +4 -4
  8. package/dist/dev/subset-shared.chunk.js +1 -1
  9. package/dist/dev/subset-worker.chunk.js +1 -1
  10. package/dist/prod/chunk-5JM5RIGS.js +4 -0
  11. package/dist/prod/{chunk-L47KOK35.js → chunk-KVNPEVSY.js} +1 -1
  12. package/dist/prod/data/image-HP6HSTQ2.js +1 -0
  13. package/dist/prod/index.js +14 -14
  14. package/dist/prod/subset-shared.chunk.js +1 -1
  15. package/dist/prod/subset-worker.chunk.js +1 -1
  16. package/dist/types/common/src/constants.d.ts +1 -0
  17. package/dist/types/excalidraw/{animated-trail.d.ts → animatedTrail.d.ts} +4 -3
  18. package/dist/types/excalidraw/components/App.d.ts +1 -3
  19. package/dist/types/excalidraw/components/SVGLayer.d.ts +1 -1
  20. package/dist/types/excalidraw/eraser/index.d.ts +2 -3
  21. package/dist/types/excalidraw/{laser-trails.d.ts → laserTrails.d.ts} +5 -7
  22. package/dist/types/excalidraw/lasso/index.d.ts +2 -3
  23. package/dist/types/excalidraw/renderer/animation.d.ts +4 -1
  24. package/dist/types/excalidraw/types.d.ts +9 -0
  25. package/dist/types/math/src/point.d.ts +1 -0
  26. package/package.json +4 -4
  27. package/dist/dev/chunk-WGF6T3RR.js.map +0 -7
  28. package/dist/prod/chunk-FDFMDTNR.js +0 -4
  29. package/dist/prod/data/image-TSPDSW4O.js +0 -1
  30. package/dist/types/excalidraw/animation-frame-handler.d.ts +0 -16
  31. /package/dist/dev/{chunk-G3MPOS33.js.map → chunk-QHLG4OQL.js.map} +0 -0
  32. /package/dist/dev/data/{image-UBAFGYUH.js.map → image-R7FQP7SA.js.map} +0 -0
package/dist/dev/index.js CHANGED
@@ -57,10 +57,10 @@ import {
57
57
  saveAsJSON,
58
58
  serializeAsJSON,
59
59
  strokeRectWithRotation_simple
60
- } from "./chunk-WGF6T3RR.js";
60
+ } from "./chunk-OBLRXIUK.js";
61
61
  import {
62
62
  define_import_meta_env_default
63
- } from "./chunk-G3MPOS33.js";
63
+ } from "./chunk-QHLG4OQL.js";
64
64
  import {
65
65
  en_default
66
66
  } from "./chunk-ZGRXNVW4.js";
@@ -81,7 +81,11 @@ import React42, {
81
81
  useRef as useRef31,
82
82
  useState as useState33
83
83
  } from "react";
84
- import { DEFAULT_UI_OPTIONS, isShallowEqual as isShallowEqual9 } from "@excalidraw/common";
84
+ import {
85
+ DEFAULT_IMAGE_OPTIONS,
86
+ DEFAULT_UI_OPTIONS,
87
+ isShallowEqual as isShallowEqual9
88
+ } from "@excalidraw/common";
85
89
 
86
90
  // components/App.tsx
87
91
  import clsx57 from "clsx";
@@ -112,7 +116,6 @@ import {
112
116
  APP_NAME,
113
117
  CURSOR_TYPE as CURSOR_TYPE4,
114
118
  DEFAULT_TRANSFORM_HANDLE_SPACING as DEFAULT_TRANSFORM_HANDLE_SPACING3,
115
- DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,
116
119
  DEFAULT_VERTICAL_ALIGN,
117
120
  DRAGGING_THRESHOLD as DRAGGING_THRESHOLD3,
118
121
  ELEMENT_SHIFT_TRANSLATE_AMOUNT,
@@ -122,7 +125,6 @@ import {
122
125
  IMAGE_MIME_TYPES as IMAGE_MIME_TYPES2,
123
126
  IMAGE_RENDER_TIMEOUT,
124
127
  LINE_CONFIRM_THRESHOLD as LINE_CONFIRM_THRESHOLD2,
125
- MAX_ALLOWED_FILE_BYTES,
126
128
  MIME_TYPES as MIME_TYPES7,
127
129
  MQ_RIGHT_SIDEBAR_MIN_WIDTH,
128
130
  POINTER_BUTTON as POINTER_BUTTON2,
@@ -9609,7 +9611,7 @@ var exportCanvas = async (type, elements, appState, files, {
9609
9611
  let blob = canvasToBlob(tempCanvas);
9610
9612
  if (appState.exportEmbedScene) {
9611
9613
  blob = blob.then(
9612
- (blob2) => import("./data/image-UBAFGYUH.js").then(
9614
+ (blob2) => import("./data/image-R7FQP7SA.js").then(
9613
9615
  ({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
9614
9616
  blob: blob2,
9615
9617
  metadata: serializeAsJSON(elements, appState, files, "local")
@@ -15012,64 +15014,6 @@ var ActionManager = class {
15012
15014
  }
15013
15015
  };
15014
15016
 
15015
- // animation-frame-handler.ts
15016
- var AnimationFrameHandler = class {
15017
- constructor() {
15018
- __publicField(this, "targets", /* @__PURE__ */ new WeakMap());
15019
- __publicField(this, "rafIds", /* @__PURE__ */ new WeakMap());
15020
- }
15021
- register(key, callback) {
15022
- this.targets.set(key, { callback, stopped: true });
15023
- }
15024
- start(key) {
15025
- const target = this.targets.get(key);
15026
- if (!target) {
15027
- return;
15028
- }
15029
- if (this.rafIds.has(key)) {
15030
- return;
15031
- }
15032
- this.targets.set(key, { ...target, stopped: false });
15033
- this.scheduleFrame(key);
15034
- }
15035
- stop(key) {
15036
- const target = this.targets.get(key);
15037
- if (target && !target.stopped) {
15038
- this.targets.set(key, { ...target, stopped: true });
15039
- }
15040
- this.cancelFrame(key);
15041
- }
15042
- constructFrame(key) {
15043
- return (timestamp) => {
15044
- const target = this.targets.get(key);
15045
- if (!target) {
15046
- return;
15047
- }
15048
- const shouldAbort = this.onFrame(target, timestamp);
15049
- if (!target.stopped && !shouldAbort) {
15050
- this.scheduleFrame(key);
15051
- } else {
15052
- this.cancelFrame(key);
15053
- }
15054
- };
15055
- }
15056
- scheduleFrame(key) {
15057
- const rafId = requestAnimationFrame(this.constructFrame(key));
15058
- this.rafIds.set(key, rafId);
15059
- }
15060
- cancelFrame(key) {
15061
- if (this.rafIds.has(key)) {
15062
- const rafId = this.rafIds.get(key);
15063
- cancelAnimationFrame(rafId);
15064
- }
15065
- this.rafIds.delete(key);
15066
- }
15067
- onFrame(target, timestamp) {
15068
- const shouldAbort = target.callback(timestamp);
15069
- return shouldAbort ?? false;
15070
- }
15071
- };
15072
-
15073
15017
  // gesture.ts
15074
15018
  var getCenter = (pointers) => {
15075
15019
  const allCoords = Array.from(pointers.values());
@@ -16256,19 +16200,149 @@ var ElementCanvasButtons = ({
16256
16200
  );
16257
16201
  };
16258
16202
 
16259
- // laser-trails.ts
16203
+ // laserTrails.ts
16260
16204
  import { DEFAULT_LASER_COLOR, easeOut } from "@excalidraw/common";
16261
16205
 
16262
- // animated-trail.ts
16206
+ // animatedTrail.ts
16263
16207
  import { LaserPointer } from "@excalidraw/laser-pointer";
16264
16208
  import {
16265
16209
  SVG_NS,
16266
16210
  getSvgPathFromStroke as getSvgPathFromStroke2,
16267
16211
  sceneCoordsToViewportCoords as sceneCoordsToViewportCoords3
16268
16212
  } from "@excalidraw/common";
16269
- var AnimatedTrail = class {
16270
- constructor(animationFrameHandler, app, options) {
16271
- this.animationFrameHandler = animationFrameHandler;
16213
+
16214
+ // reactUtils.ts
16215
+ import { version as ReactVersion } from "react";
16216
+ import { unstable_batchedUpdates } from "react-dom";
16217
+ import { throttleRAF } from "@excalidraw/common";
16218
+ var withBatchedUpdates = (func) => (event) => {
16219
+ unstable_batchedUpdates(func, event);
16220
+ };
16221
+ var withBatchedUpdatesThrottled = (func) => {
16222
+ return throttleRAF((event) => {
16223
+ unstable_batchedUpdates(func, event);
16224
+ });
16225
+ };
16226
+ var isRenderThrottlingEnabled = (() => {
16227
+ let IS_REACT_18_AND_UP;
16228
+ try {
16229
+ const version = ReactVersion.split(".");
16230
+ IS_REACT_18_AND_UP = Number(version[0]) > 17;
16231
+ } catch {
16232
+ IS_REACT_18_AND_UP = false;
16233
+ }
16234
+ let hasWarned = false;
16235
+ return () => {
16236
+ if (window.EXCALIDRAW_THROTTLE_RENDER === true) {
16237
+ if (!IS_REACT_18_AND_UP) {
16238
+ if (!hasWarned) {
16239
+ hasWarned = true;
16240
+ console.warn(
16241
+ "Excalidraw: render throttling is disabled on React versions < 18."
16242
+ );
16243
+ }
16244
+ return false;
16245
+ }
16246
+ return true;
16247
+ }
16248
+ return false;
16249
+ };
16250
+ })();
16251
+
16252
+ // renderer/animation.ts
16253
+ var _AnimationController = class _AnimationController {
16254
+ static start(key, animation) {
16255
+ if (_AnimationController.animations.has(key)) {
16256
+ return;
16257
+ }
16258
+ const initialState = animation({
16259
+ deltaTime: 0,
16260
+ state: void 0
16261
+ });
16262
+ if (initialState) {
16263
+ _AnimationController.animations.set(key, {
16264
+ animation,
16265
+ lastTime: 0,
16266
+ state: initialState
16267
+ });
16268
+ _AnimationController.scheduleNextFrame();
16269
+ }
16270
+ }
16271
+ static scheduleNextFrame() {
16272
+ if (_AnimationController.scheduledFrame) {
16273
+ return;
16274
+ }
16275
+ if (isRenderThrottlingEnabled()) {
16276
+ _AnimationController.scheduledFrame = {
16277
+ id: requestAnimationFrame(_AnimationController.tick),
16278
+ type: "raf"
16279
+ };
16280
+ } else {
16281
+ _AnimationController.scheduledFrame = {
16282
+ id: setTimeout(_AnimationController.tick, 0),
16283
+ type: "timeout"
16284
+ };
16285
+ }
16286
+ }
16287
+ static cancelScheduledFrame() {
16288
+ if (!_AnimationController.scheduledFrame) {
16289
+ return;
16290
+ }
16291
+ if (_AnimationController.scheduledFrame.type === "raf") {
16292
+ cancelAnimationFrame(_AnimationController.scheduledFrame.id);
16293
+ } else {
16294
+ clearTimeout(_AnimationController.scheduledFrame.id);
16295
+ }
16296
+ _AnimationController.scheduledFrame = null;
16297
+ }
16298
+ static cancelScheduledFrameIfIdle() {
16299
+ if (_AnimationController.animations.size > 0) {
16300
+ return false;
16301
+ }
16302
+ _AnimationController.cancelScheduledFrame();
16303
+ return true;
16304
+ }
16305
+ static tick() {
16306
+ _AnimationController.scheduledFrame = null;
16307
+ if (_AnimationController.animations.size > 0) {
16308
+ for (const [key, animation] of _AnimationController.animations) {
16309
+ const now = performance.now();
16310
+ const deltaTime = animation.lastTime === 0 ? 0 : now - animation.lastTime;
16311
+ const state = animation.animation({
16312
+ deltaTime,
16313
+ state: animation.state
16314
+ });
16315
+ if (!state) {
16316
+ _AnimationController.animations.delete(key);
16317
+ if (_AnimationController.cancelScheduledFrameIfIdle()) {
16318
+ return;
16319
+ }
16320
+ } else {
16321
+ animation.lastTime = now;
16322
+ animation.state = state;
16323
+ }
16324
+ }
16325
+ if (_AnimationController.cancelScheduledFrameIfIdle()) {
16326
+ return;
16327
+ }
16328
+ _AnimationController.scheduleNextFrame();
16329
+ }
16330
+ }
16331
+ static running(key) {
16332
+ return _AnimationController.animations.has(key);
16333
+ }
16334
+ static cancel(key) {
16335
+ _AnimationController.animations.delete(key);
16336
+ _AnimationController.cancelScheduledFrameIfIdle();
16337
+ }
16338
+ };
16339
+ __publicField(_AnimationController, "scheduledFrame", null);
16340
+ __publicField(_AnimationController, "animations", /* @__PURE__ */ new Map());
16341
+ var AnimationController = _AnimationController;
16342
+
16343
+ // animatedTrail.ts
16344
+ var _AnimatedTrail = class _AnimatedTrail {
16345
+ constructor(app, options) {
16272
16346
  this.app = app;
16273
16347
  this.options = options;
16274
16348
  __publicField(this, "currentTrail");
@@ -16276,7 +16350,8 @@ var AnimatedTrail = class {
16276
16350
  __publicField(this, "container");
16277
16351
  __publicField(this, "trailElement");
16278
16352
  __publicField(this, "trailAnimation");
16279
- this.animationFrameHandler.register(this, this.onFrame.bind(this));
16353
+ __publicField(this, "key");
16354
+ this.key = `animated-trail-${_AnimatedTrail.counter++}`;
16280
16355
  this.trailElement = document.createElementNS(SVG_NS, "path");
16281
16356
  if (this.options.animateTrail) {
16282
16357
  this.trailAnimation = document.createElementNS(SVG_NS, "animate");
@@ -16299,6 +16374,13 @@ var AnimatedTrail = class {
16299
16374
  }
16300
16375
  return false;
16301
16376
  }
16377
+ cleanup() {
16378
+ this.pastTrails = [];
16379
+ this.currentTrail = void 0;
16380
+ if (this.trailElement.parentNode === this.container) {
16381
+ this.container?.removeChild(this.trailElement);
16382
+ }
16383
+ }
16302
16384
  start(container) {
16303
16385
  if (container) {
16304
16386
  this.container = container;
@@ -16306,13 +16388,20 @@ var AnimatedTrail = class {
16306
16388
  if (this.trailElement.parentNode !== this.container && this.container) {
16307
16389
  this.container.appendChild(this.trailElement);
16308
16390
  }
16309
- this.animationFrameHandler.start(this);
16391
+ if (!AnimationController.running(this.key)) {
16392
+ AnimationController.start(this.key, () => {
16393
+ const needsNext = this.onFrame();
16394
+ if (needsNext) {
16395
+ return { keep: true };
16396
+ }
16397
+ this.cleanup();
16398
+ return null;
16399
+ });
16400
+ }
16310
16401
  }
16311
16402
  stop() {
16312
- this.animationFrameHandler.stop(this);
16313
- if (this.trailElement.parentNode === this.container) {
16314
- this.container?.removeChild(this.trailElement);
16315
- }
16403
+ AnimationController.cancel(this.key);
16404
+ this.cleanup();
16316
16405
  }
16317
16406
  startPath(x, y) {
16318
16407
  this.currentTrail = new LaserPointer(this.options);
@@ -16358,11 +16447,12 @@ var AnimatedTrail = class {
16358
16447
  const currentPath = this.drawTrail(this.currentTrail, this.app.state);
16359
16448
  paths.push(currentPath);
16360
16449
  }
16361
- this.pastTrails = this.pastTrails.filter((trail) => {
16362
- return trail.getStrokeOutline().length !== 0;
16363
- });
16450
+ this.pastTrails = this.pastTrails.filter(
16451
+ (t2) => t2.getStrokeOutline(t2.options.size / this.app.state.zoom.value).length !== 0
16452
+ );
16364
16453
  if (paths.length === 0) {
16365
- this.stop();
16454
+ this.trailElement.setAttribute("d", "");
16455
+ return false;
16366
16456
  }
16367
16457
  const svgPaths = paths.join(" ").trim();
16368
16458
  this.trailElement.setAttribute("d", svgPaths);
@@ -16381,6 +16471,7 @@ var AnimatedTrail = class {
16381
16471
  (this.options.fill ?? (() => "black"))(this)
16382
16472
  );
16383
16473
  }
16474
+ return true;
16384
16475
  }
16385
16476
  drawTrail(trail, state) {
16386
16477
  const _stroke = trail.getStrokeOutline(trail.options.size / state.zoom.value).map(([x, y]) => {
@@ -16394,17 +16485,17 @@ var AnimatedTrail = class {
16394
16485
  return getSvgPathFromStroke2(stroke, true);
16395
16486
  }
16396
16487
  };
16488
+ __publicField(_AnimatedTrail, "counter", 0);
16489
+ var AnimatedTrail = _AnimatedTrail;
16397
16490
 
16398
- // laser-trails.ts
16491
+ // laserTrails.ts
16399
16492
  var LaserTrails = class {
16400
- constructor(animationFrameHandler, app) {
16401
- this.animationFrameHandler = animationFrameHandler;
16493
+ constructor(app) {
16402
16494
  this.app = app;
16403
16495
  __publicField(this, "localTrail");
16404
16496
  __publicField(this, "collabTrails", /* @__PURE__ */ new Map());
16405
16497
  __publicField(this, "container");
16406
- this.animationFrameHandler.register(this, this.onFrame.bind(this));
16407
- this.localTrail = new AnimatedTrail(animationFrameHandler, app, {
16498
+ this.localTrail = new AnimatedTrail(app, {
16408
16499
  ...this.getTrailOptions(),
16409
16500
  fill: () => DEFAULT_LASER_COLOR
16410
16501
  });
@@ -16436,93 +16527,63 @@ var LaserTrails = class {
16436
16527
  }
16437
16528
  start(container) {
16438
16529
  this.container = container;
16439
- this.animationFrameHandler.start(this);
16440
16530
  this.localTrail.start(container);
16441
16531
  }
16442
16532
  stop() {
16443
- this.animationFrameHandler.stop(this);
16444
16533
  this.localTrail.stop();
16534
+ this.stopCollabTrails();
16535
+ this.container = void 0;
16445
16536
  }
16446
- onFrame() {
16447
- this.updateCollabTrails();
16537
+ stopCollabTrails(collaborators) {
16538
+ for (const [key, trail] of this.collabTrails) {
16539
+ const collaborator = collaborators?.get(key);
16540
+ if (!collaborator) {
16541
+ trail.stop();
16542
+ this.collabTrails.delete(key);
16543
+ }
16544
+ }
16448
16545
  }
16449
- updateCollabTrails() {
16450
- if (!this.container || this.app.state.collaborators.size === 0) {
16546
+ updateCollabTrails(collaborators) {
16547
+ this.stopCollabTrails(collaborators);
16548
+ if (!this.container || collaborators.size === 0) {
16451
16549
  return;
16452
16550
  }
16453
- for (const [key, collaborator] of this.app.state.collaborators.entries()) {
16454
- let trail;
16455
- if (!this.collabTrails.has(key)) {
16456
- trail = new AnimatedTrail(this.animationFrameHandler, this.app, {
16551
+ for (const [key, collaborator] of collaborators.entries()) {
16552
+ if (collaborator.isCurrentUser) {
16553
+ continue;
16554
+ }
16555
+ let trail = this.collabTrails.get(key);
16556
+ if (!trail) {
16557
+ trail = new AnimatedTrail(this.app, {
16457
16558
  ...this.getTrailOptions(),
16458
16559
  fill: () => collaborator.pointer?.laserColor || getClientColor(key, collaborator)
16459
16560
  });
16460
16561
  trail.start(this.container);
16461
16562
  this.collabTrails.set(key, trail);
16462
- } else {
16463
- trail = this.collabTrails.get(key);
16464
16563
  }
16465
16564
  if (collaborator.pointer && collaborator.pointer.tool === "laser") {
16466
- if (collaborator.button === "down" && !trail.hasCurrentTrail) {
16565
+ const buttonDown = collaborator.button === "down";
16566
+ const buttonUp = collaborator.button === "up";
16567
+ const hasTrail = trail.hasCurrentTrail;
16568
+ if (buttonDown && !hasTrail) {
16467
16569
  trail.startPath(collaborator.pointer.x, collaborator.pointer.y);
16468
16570
  }
16469
- if (collaborator.button === "down" && trail.hasCurrentTrail && !trail.hasLastPoint(collaborator.pointer.x, collaborator.pointer.y)) {
16571
+ const lastPointOriginal = !trail.hasLastPoint(
16572
+ collaborator.pointer.x,
16573
+ collaborator.pointer.y
16574
+ );
16575
+ if (buttonDown && lastPointOriginal) {
16470
16576
  trail.addPointToPath(collaborator.pointer.x, collaborator.pointer.y);
16471
16577
  }
16472
- if (collaborator.button === "up" && trail.hasCurrentTrail) {
16578
+ if (buttonUp && hasTrail) {
16473
16579
  trail.addPointToPath(collaborator.pointer.x, collaborator.pointer.y);
16474
16580
  trail.endPath();
16475
16581
  }
16476
16582
  }
16477
16583
  }
16478
- for (const key of this.collabTrails.keys()) {
16479
- if (!this.app.state.collaborators.has(key)) {
16480
- const trail = this.collabTrails.get(key);
16481
- trail.stop();
16482
- this.collabTrails.delete(key);
16483
- }
16484
- }
16485
16584
  }
16486
16585
  };
16487
16586
 
16488
- // reactUtils.ts
16489
- import { version as ReactVersion } from "react";
16490
- import { unstable_batchedUpdates } from "react-dom";
16491
- import { throttleRAF } from "@excalidraw/common";
16492
- var withBatchedUpdates = (func) => (event) => {
16493
- unstable_batchedUpdates(func, event);
16494
- };
16495
- var withBatchedUpdatesThrottled = (func) => {
16496
- return throttleRAF((event) => {
16497
- unstable_batchedUpdates(func, event);
16498
- });
16499
- };
16500
- var isRenderThrottlingEnabled = (() => {
16501
- let IS_REACT_18_AND_UP;
16502
- try {
16503
- const version = ReactVersion.split(".");
16504
- IS_REACT_18_AND_UP = Number(version[0]) > 17;
16505
- } catch {
16506
- IS_REACT_18_AND_UP = false;
16507
- }
16508
- let hasWarned = false;
16509
- return () => {
16510
- if (window.EXCALIDRAW_THROTTLE_RENDER === true) {
16511
- if (!IS_REACT_18_AND_UP) {
16512
- if (!hasWarned) {
16513
- hasWarned = true;
16514
- console.warn(
16515
- "Excalidraw: render throttling is disabled on React versions < 18."
16516
- );
16517
- }
16518
- return false;
16519
- }
16520
- return true;
16521
- }
16522
- return false;
16523
- };
16524
- })();
16525
-
16526
16587
  // textAutoResizeHandle.ts
16527
16588
  import { DEFAULT_TRANSFORM_HANDLE_SPACING } from "@excalidraw/common";
16528
16589
  import {
@@ -17481,8 +17542,8 @@ var intersectionTest = (lassoPath, element, elementsMap) => {
17481
17542
 
17482
17543
  // lasso/index.ts
17483
17544
  var LassoTrail = class extends AnimatedTrail {
17484
- constructor(animationFrameHandler, app) {
17485
- super(animationFrameHandler, app, {
17545
+ constructor(app) {
17546
+ super(app, {
17486
17547
  animateTrail: true,
17487
17548
  streamline: 0.4,
17488
17549
  sizeMapping: (c) => {
@@ -17688,8 +17749,8 @@ import { shouldTestInside as shouldTestInside2 } from "@excalidraw/element";
17688
17749
  import { hasBoundTextElement as hasBoundTextElement4, isBoundToContainer as isBoundToContainer8 } from "@excalidraw/element";
17689
17750
  import { getBoundTextElementId as getBoundTextElementId2 } from "@excalidraw/element";
17690
17751
  var EraserTrail = class extends AnimatedTrail {
17691
- constructor(animationFrameHandler, app) {
17692
- super(animationFrameHandler, app, {
17752
+ constructor(app) {
17753
+ super(app, {
17693
17754
  streamline: 0.2,
17694
17755
  size: 5,
17695
17756
  keepHead: true,
@@ -30943,67 +31004,6 @@ var renderInteractiveScene = (renderConfig) => {
30943
31004
  return ret;
30944
31005
  };
30945
31006
 
30946
- // renderer/animation.ts
30947
- var _AnimationController = class _AnimationController {
30948
- static start(key, animation) {
30949
- const initialState = animation({
30950
- deltaTime: 0,
30951
- state: void 0
30952
- });
30953
- if (initialState) {
30954
- _AnimationController.animations.set(key, {
30955
- animation,
30956
- lastTime: 0,
30957
- state: initialState
30958
- });
30959
- if (!_AnimationController.isRunning) {
30960
- _AnimationController.isRunning = true;
30961
- if (isRenderThrottlingEnabled()) {
30962
- requestAnimationFrame(_AnimationController.tick);
30963
- } else {
30964
- setTimeout(_AnimationController.tick, 0);
30965
- }
30966
- }
30967
- }
30968
- }
30969
- static tick() {
30970
- if (_AnimationController.animations.size > 0) {
30971
- for (const [key, animation] of _AnimationController.animations) {
30972
- const now = performance.now();
30973
- const deltaTime = animation.lastTime === 0 ? 0 : now - animation.lastTime;
30974
- const state = animation.animation({
30975
- deltaTime,
30976
- state: animation.state
30977
- });
30978
- if (!state) {
30979
- _AnimationController.animations.delete(key);
30980
- if (_AnimationController.animations.size === 0) {
30981
- _AnimationController.isRunning = false;
30982
- return;
30983
- }
30984
- } else {
30985
- animation.lastTime = now;
30986
- animation.state = state;
30987
- }
30988
- }
30989
- if (isRenderThrottlingEnabled()) {
30990
- requestAnimationFrame(_AnimationController.tick);
30991
- } else {
30992
- setTimeout(_AnimationController.tick, 0);
30993
- }
30994
- }
30995
- }
30996
- static running(key) {
30997
- return _AnimationController.animations.has(key);
30998
- }
30999
- static cancel(key) {
31000
- _AnimationController.animations.delete(key);
31001
- }
31002
- };
31003
- __publicField(_AnimationController, "isRunning", false);
31004
- __publicField(_AnimationController, "animations", /* @__PURE__ */ new Map());
31005
- var AnimationController = _AnimationController;
31006
-
31007
31007
  // components/canvases/InteractiveCanvas.tsx
31008
31008
  import { jsx as jsx133 } from "react/jsx-runtime";
31009
31009
  var INTERACTIVE_SCENE_ANIMATION_KEY = "animateInteractiveScene";
@@ -31698,10 +31698,9 @@ var App = class _App extends React40.Component {
31698
31698
  /** previous frame pointer coords */
31699
31699
  __publicField(this, "previousPointerMoveCoords", null);
31700
31700
  __publicField(this, "lastViewportPosition", { x: 0, y: 0 });
31701
- __publicField(this, "animationFrameHandler", new AnimationFrameHandler());
31702
- __publicField(this, "laserTrails", new LaserTrails(this.animationFrameHandler, this));
31703
- __publicField(this, "eraserTrail", new EraserTrail(this.animationFrameHandler, this));
31704
- __publicField(this, "lassoTrail", new LassoTrail(this.animationFrameHandler, this));
31701
+ __publicField(this, "laserTrails", new LaserTrails(this));
31702
+ __publicField(this, "eraserTrail", new EraserTrail(this));
31703
+ __publicField(this, "lassoTrail", new LassoTrail(this));
31705
31704
  __publicField(this, "onChangeEmitter", new Emitter2());
31706
31705
  __publicField(this, "onPointerDownEmitter", new Emitter2());
31707
31706
  __publicField(this, "onPointerUpEmitter", new Emitter2());
@@ -32902,6 +32901,7 @@ var App = class _App extends React40.Component {
32902
32901
  this.scene.replaceAllElements(elements);
32903
32902
  }
32904
32903
  if (collaborators) {
32904
+ this.laserTrails.updateCollabTrails(collaborators);
32905
32905
  this.setState({ collaborators });
32906
32906
  }
32907
32907
  }
@@ -36022,9 +36022,10 @@ var App = class _App extends React40.Component {
36022
36022
  throw new Error(t("errors.svgImageInsertError"));
36023
36023
  }
36024
36024
  } else if (fileNeedsResizing) {
36025
+ const { maxWidthOrHeight } = this.props.imageOptions;
36025
36026
  try {
36026
36027
  imageFile = await this.props.compressImageFile(imageFile, {
36027
- maxWidthOrHeight: DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT
36028
+ maxWidthOrHeight
36028
36029
  });
36029
36030
  console.info("Excalidraw: image resized");
36030
36031
  } catch (error) {
@@ -36034,10 +36035,11 @@ var App = class _App extends React40.Component {
36034
36035
  );
36035
36036
  }
36036
36037
  }
36037
- if (imageFile.size > MAX_ALLOWED_FILE_BYTES) {
36038
+ const { maxFileSizeBytes } = this.props.imageOptions;
36039
+ if (imageFile.size > maxFileSizeBytes) {
36038
36040
  throw new Error(
36039
36041
  t("errors.fileTooBig", {
36040
- maxSize: `${Math.trunc(MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`
36042
+ maxSize: `${Math.trunc(maxFileSizeBytes / 1024 / 1024)}MB`
36041
36043
  })
36042
36044
  );
36043
36045
  }
@@ -36349,12 +36351,7 @@ var App = class _App extends React40.Component {
36349
36351
  const elements = this.scene.getElementsIncludingDeleted();
36350
36352
  let ret;
36351
36353
  try {
36352
- ret = await loadFromBlob(
36353
- file2,
36354
- this.state,
36355
- elements,
36356
- fileHandle
36357
- );
36354
+ ret = await loadFromBlob(file2, this.state, elements, fileHandle);
36358
36355
  } catch (error) {
36359
36356
  const imageSceneDataError = error instanceof ImageSceneDataError;
36360
36357
  if (imageSceneDataError && error.code === "IMAGE_NOT_CONTAINS_SCENE_DATA" && !this.isToolSupported("image")) {
@@ -41206,7 +41203,8 @@ var ExcalidrawBase = (props) => {
41206
41203
  wheelZoomsOnDefault,
41207
41204
  strokeColorTopPicks,
41208
41205
  backgroundColorTopPicks,
41209
- renderScrollbars
41206
+ renderScrollbars,
41207
+ imageOptions
41210
41208
  } = props;
41211
41209
  const canvasActions = props.UIOptions?.canvasActions;
41212
41210
  const UIOptions = {
@@ -41225,6 +41223,10 @@ var ExcalidrawBase = (props) => {
41225
41223
  if (UIOptions.canvasActions.toggleTheme === null && typeof theme === "undefined") {
41226
41224
  UIOptions.canvasActions.toggleTheme = true;
41227
41225
  }
41226
+ const normalizedImageOptions = {
41227
+ maxFileSizeBytes: imageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes,
41228
+ maxWidthOrHeight: imageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight
41229
+ };
41228
41230
  const setExcalidrawAPI = useContext4(ExcalidrawAPISetContext);
41229
41231
  const onExcalidrawAPIRef = useRef31(onExcalidrawAPI);
41230
41232
  onExcalidrawAPIRef.current = onExcalidrawAPI;
@@ -41296,6 +41298,7 @@ var ExcalidrawBase = (props) => {
41296
41298
  strokeColorTopPicks,
41297
41299
  backgroundColorTopPicks,
41298
41300
  renderScrollbars,
41301
+ imageOptions: normalizedImageOptions,
41299
41302
  children
41300
41303
  }
41301
41304
  ) }) });
@@ -41307,11 +41310,13 @@ var areEqual5 = (prevProps, nextProps) => {
41307
41310
  const {
41308
41311
  initialData: prevInitialData,
41309
41312
  UIOptions: prevUIOptions = {},
41313
+ imageOptions: prevImageOptions,
41310
41314
  ...prev
41311
41315
  } = prevProps;
41312
41316
  const {
41313
41317
  initialData: nextInitialData,
41314
41318
  UIOptions: nextUIOptions = {},
41319
+ imageOptions: nextImageOptions,
41315
41320
  ...next
41316
41321
  } = nextProps;
41317
41322
  const prevUIOptionsKeys = Object.keys(prevUIOptions);
@@ -41336,7 +41341,8 @@ var areEqual5 = (prevProps, nextProps) => {
41336
41341
  }
41337
41342
  return prevUIOptions[key] === nextUIOptions[key];
41338
41343
  });
41339
- return isUIOptionsSame && isShallowEqual9(prev, next);
41344
+ const isImageOptionsSame = (prevImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) === (nextImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) && (prevImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes) === (nextImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes);
41345
+ return isUIOptionsSame && isImageOptionsSame && isShallowEqual9(prev, next);
41340
41346
  };
41341
41347
  var Excalidraw = React42.memo(ExcalidrawBase, areEqual5);
41342
41348
  Excalidraw.displayName = "Excalidraw";