@netless/forge-whiteboard 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/changelog.md +5 -1
  2. package/dist/LiveCursor.d.ts +1 -1
  3. package/dist/LiveCursor.d.ts.map +1 -1
  4. package/dist/Whiteboard.d.ts +10 -0
  5. package/dist/Whiteboard.d.ts.map +1 -1
  6. package/dist/WhiteboardApplication.d.ts +6 -0
  7. package/dist/WhiteboardApplication.d.ts.map +1 -1
  8. package/dist/model/RenderableModel.d.ts +13 -1
  9. package/dist/model/RenderableModel.d.ts.map +1 -1
  10. package/dist/model/renderable/CurveModel.d.ts +4 -3
  11. package/dist/model/renderable/CurveModel.d.ts.map +1 -1
  12. package/dist/model/renderable/ElementModel.d.ts +17 -1
  13. package/dist/model/renderable/ElementModel.d.ts.map +1 -1
  14. package/dist/model/renderable/EraserModel.d.ts +5 -1
  15. package/dist/model/renderable/EraserModel.d.ts.map +1 -1
  16. package/dist/model/renderable/ImageModel.d.ts +4 -1
  17. package/dist/model/renderable/ImageModel.d.ts.map +1 -1
  18. package/dist/model/renderable/LaserPointerModel.d.ts +4 -1
  19. package/dist/model/renderable/LaserPointerModel.d.ts.map +1 -1
  20. package/dist/model/renderable/LineModel.d.ts +5 -1
  21. package/dist/model/renderable/LineModel.d.ts.map +1 -1
  22. package/dist/model/renderable/PointTextModel.d.ts +5 -1
  23. package/dist/model/renderable/PointTextModel.d.ts.map +1 -1
  24. package/dist/model/renderable/RectangleModel.d.ts +5 -1
  25. package/dist/model/renderable/RectangleModel.d.ts.map +1 -1
  26. package/dist/model/renderable/SegmentsModel.d.ts +5 -1
  27. package/dist/model/renderable/SegmentsModel.d.ts.map +1 -1
  28. package/dist/model/renderable/SelectorModel.d.ts +5 -1
  29. package/dist/model/renderable/SelectorModel.d.ts.map +1 -1
  30. package/dist/model/renderable/StraightLineModel.d.ts +5 -1
  31. package/dist/model/renderable/StraightLineModel.d.ts.map +1 -1
  32. package/dist/model/renderable/TriangleModel.d.ts +5 -1
  33. package/dist/model/renderable/TriangleModel.d.ts.map +1 -1
  34. package/dist/tool/CurveTool.d.ts +3 -0
  35. package/dist/tool/CurveTool.d.ts.map +1 -1
  36. package/dist/tool/LaserPointerTool.d.ts.map +1 -1
  37. package/dist/tool/WhiteboardTool.d.ts +4 -0
  38. package/dist/tool/WhiteboardTool.d.ts.map +1 -1
  39. package/dist/utils/paperjs.d.ts.map +1 -1
  40. package/dist/whiteboard.esm.js +633 -239
  41. package/dist/whiteboard.esm.js.map +3 -3
  42. package/dist/whiteboard.js +688 -294
  43. package/dist/whiteboard.js.map +3 -3
  44. package/package.json +2 -2
@@ -20839,8 +20839,8 @@ var require_lodash = __commonJS({
20839
20839
  }
20840
20840
  var runInContext = function runInContext2(context) {
20841
20841
  context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
20842
- var Array13 = context.Array, Date2 = context.Date, Error2 = context.Error, Function2 = context.Function, Math2 = context.Math, Object2 = context.Object, RegExp2 = context.RegExp, String2 = context.String, TypeError2 = context.TypeError;
20843
- var arrayProto = Array13.prototype, funcProto = Function2.prototype, objectProto = Object2.prototype;
20842
+ var Array14 = context.Array, Date2 = context.Date, Error2 = context.Error, Function2 = context.Function, Math2 = context.Math, Object2 = context.Object, RegExp2 = context.RegExp, String2 = context.String, TypeError2 = context.TypeError;
20843
+ var arrayProto = Array14.prototype, funcProto = Function2.prototype, objectProto = Object2.prototype;
20844
20844
  var coreJsData = context["__core-js_shared__"];
20845
20845
  var funcToString = funcProto.toString;
20846
20846
  var hasOwnProperty = objectProto.hasOwnProperty;
@@ -21263,7 +21263,7 @@ var require_lodash = __commonJS({
21263
21263
  }
21264
21264
  }
21265
21265
  function baseAt(object, paths) {
21266
- var index = -1, length = paths.length, result2 = Array13(length), skip = object == null;
21266
+ var index = -1, length = paths.length, result2 = Array14(length), skip = object == null;
21267
21267
  while (++index < length) {
21268
21268
  result2[index] = skip ? undefined2 : get(object, paths[index]);
21269
21269
  }
@@ -21509,7 +21509,7 @@ var require_lodash = __commonJS({
21509
21509
  return number >= nativeMin(start, end) && number < nativeMax(start, end);
21510
21510
  }
21511
21511
  function baseIntersection(arrays, iteratee2, comparator) {
21512
- var includes2 = comparator ? arrayIncludesWith : arrayIncludes, length = arrays[0].length, othLength = arrays.length, othIndex = othLength, caches = Array13(othLength), maxLength = Infinity, result2 = [];
21512
+ var includes2 = comparator ? arrayIncludesWith : arrayIncludes, length = arrays[0].length, othLength = arrays.length, othIndex = othLength, caches = Array14(othLength), maxLength = Infinity, result2 = [];
21513
21513
  while (othIndex--) {
21514
21514
  var array = arrays[othIndex];
21515
21515
  if (othIndex && iteratee2) {
@@ -21690,7 +21690,7 @@ var require_lodash = __commonJS({
21690
21690
  return value < other;
21691
21691
  }
21692
21692
  function baseMap(collection, iteratee2) {
21693
- var index = -1, result2 = isArrayLike(collection) ? Array13(collection.length) : [];
21693
+ var index = -1, result2 = isArrayLike(collection) ? Array14(collection.length) : [];
21694
21694
  baseEach(collection, function(value, key, collection2) {
21695
21695
  result2[++index] = iteratee2(value, key, collection2);
21696
21696
  });
@@ -21865,7 +21865,7 @@ var require_lodash = __commonJS({
21865
21865
  return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
21866
21866
  }
21867
21867
  function baseRange(start, end, step, fromRight) {
21868
- var index = -1, length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result2 = Array13(length);
21868
+ var index = -1, length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result2 = Array14(length);
21869
21869
  while (length--) {
21870
21870
  result2[fromRight ? length : ++index] = start;
21871
21871
  start += step;
@@ -21947,7 +21947,7 @@ var require_lodash = __commonJS({
21947
21947
  }
21948
21948
  length = start > end ? 0 : end - start >>> 0;
21949
21949
  start >>>= 0;
21950
- var result2 = Array13(length);
21950
+ var result2 = Array14(length);
21951
21951
  while (++index < length) {
21952
21952
  result2[index] = array[index + start];
21953
21953
  }
@@ -22107,7 +22107,7 @@ var require_lodash = __commonJS({
22107
22107
  if (length < 2) {
22108
22108
  return length ? baseUniq(arrays[0]) : [];
22109
22109
  }
22110
- var index = -1, result2 = Array13(length);
22110
+ var index = -1, result2 = Array14(length);
22111
22111
  while (++index < length) {
22112
22112
  var array = arrays[index], othIndex = -1;
22113
22113
  while (++othIndex < length) {
@@ -22204,7 +22204,7 @@ var require_lodash = __commonJS({
22204
22204
  return object.index - other.index;
22205
22205
  }
22206
22206
  function composeArgs(args, partials, holders, isCurried) {
22207
- var argsIndex = -1, argsLength = args.length, holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result2 = Array13(leftLength + rangeLength), isUncurried = !isCurried;
22207
+ var argsIndex = -1, argsLength = args.length, holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result2 = Array14(leftLength + rangeLength), isUncurried = !isCurried;
22208
22208
  while (++leftIndex < leftLength) {
22209
22209
  result2[leftIndex] = partials[leftIndex];
22210
22210
  }
@@ -22219,7 +22219,7 @@ var require_lodash = __commonJS({
22219
22219
  return result2;
22220
22220
  }
22221
22221
  function composeArgsRight(args, partials, holders, isCurried) {
22222
- var argsIndex = -1, argsLength = args.length, holdersIndex = -1, holdersLength = holders.length, rightIndex = -1, rightLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result2 = Array13(rangeLength + rightLength), isUncurried = !isCurried;
22222
+ var argsIndex = -1, argsLength = args.length, holdersIndex = -1, holdersLength = holders.length, rightIndex = -1, rightLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result2 = Array14(rangeLength + rightLength), isUncurried = !isCurried;
22223
22223
  while (++argsIndex < rangeLength) {
22224
22224
  result2[argsIndex] = args[argsIndex];
22225
22225
  }
@@ -22236,7 +22236,7 @@ var require_lodash = __commonJS({
22236
22236
  }
22237
22237
  function copyArray(source, array) {
22238
22238
  var index = -1, length = source.length;
22239
- array || (array = Array13(length));
22239
+ array || (array = Array14(length));
22240
22240
  while (++index < length) {
22241
22241
  array[index] = source[index];
22242
22242
  }
@@ -22369,7 +22369,7 @@ var require_lodash = __commonJS({
22369
22369
  function createCurry(func, bitmask, arity) {
22370
22370
  var Ctor = createCtor(func);
22371
22371
  function wrapper() {
22372
- var length = arguments.length, args = Array13(length), index = length, placeholder = getHolder(wrapper);
22372
+ var length = arguments.length, args = Array14(length), index = length, placeholder = getHolder(wrapper);
22373
22373
  while (index--) {
22374
22374
  args[index] = arguments[index];
22375
22375
  }
@@ -22449,7 +22449,7 @@ var require_lodash = __commonJS({
22449
22449
  function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary2, arity) {
22450
22450
  var isAry = bitmask & WRAP_ARY_FLAG, isBind = bitmask & WRAP_BIND_FLAG, isBindKey = bitmask & WRAP_BIND_KEY_FLAG, isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), isFlip = bitmask & WRAP_FLIP_FLAG, Ctor = isBindKey ? undefined2 : createCtor(func);
22451
22451
  function wrapper() {
22452
- var length = arguments.length, args = Array13(length), index = length;
22452
+ var length = arguments.length, args = Array14(length), index = length;
22453
22453
  while (index--) {
22454
22454
  args[index] = arguments[index];
22455
22455
  }
@@ -22548,7 +22548,7 @@ var require_lodash = __commonJS({
22548
22548
  function createPartial(func, bitmask, thisArg, partials) {
22549
22549
  var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func);
22550
22550
  function wrapper() {
22551
- var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, args = Array13(leftLength + argsLength), fn = this && this !== root && this instanceof wrapper ? Ctor : func;
22551
+ var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, args = Array14(leftLength + argsLength), fn = this && this !== root && this instanceof wrapper ? Ctor : func;
22552
22552
  while (++leftIndex < leftLength) {
22553
22553
  args[leftIndex] = partials[leftIndex];
22554
22554
  }
@@ -23161,12 +23161,12 @@ var require_lodash = __commonJS({
23161
23161
  function overRest(func, start, transform2) {
23162
23162
  start = nativeMax(start === undefined2 ? func.length - 1 : start, 0);
23163
23163
  return function() {
23164
- var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array13(length);
23164
+ var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array14(length);
23165
23165
  while (++index < length) {
23166
23166
  array[index] = args[start + index];
23167
23167
  }
23168
23168
  index = -1;
23169
- var otherArgs = Array13(start + 1);
23169
+ var otherArgs = Array14(start + 1);
23170
23170
  while (++index < start) {
23171
23171
  otherArgs[index] = args[index];
23172
23172
  }
@@ -23278,7 +23278,7 @@ var require_lodash = __commonJS({
23278
23278
  result2.__values__ = wrapper.__values__;
23279
23279
  return result2;
23280
23280
  }
23281
- function chunk8(array, size2, guard) {
23281
+ function chunk7(array, size2, guard) {
23282
23282
  if (guard ? isIterateeCall(array, size2, guard) : size2 === undefined2) {
23283
23283
  size2 = 1;
23284
23284
  } else {
@@ -23288,7 +23288,7 @@ var require_lodash = __commonJS({
23288
23288
  if (!length || size2 < 1) {
23289
23289
  return [];
23290
23290
  }
23291
- var index = 0, resIndex = 0, result2 = Array13(nativeCeil(length / size2));
23291
+ var index = 0, resIndex = 0, result2 = Array14(nativeCeil(length / size2));
23292
23292
  while (index < length) {
23293
23293
  result2[resIndex++] = baseSlice(array, index, index += size2);
23294
23294
  }
@@ -23309,7 +23309,7 @@ var require_lodash = __commonJS({
23309
23309
  if (!length) {
23310
23310
  return [];
23311
23311
  }
23312
- var args = Array13(length - 1), array = arguments[0], index = length;
23312
+ var args = Array14(length - 1), array = arguments[0], index = length;
23313
23313
  while (index--) {
23314
23314
  args[index - 1] = arguments[index];
23315
23315
  }
@@ -23811,7 +23811,7 @@ var require_lodash = __commonJS({
23811
23811
  return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1;
23812
23812
  }
23813
23813
  var invokeMap = baseRest(function(collection, path, args) {
23814
- var index = -1, isFunc = typeof path == "function", result2 = isArrayLike(collection) ? Array13(collection.length) : [];
23814
+ var index = -1, isFunc = typeof path == "function", result2 = isArrayLike(collection) ? Array14(collection.length) : [];
23815
23815
  baseEach(collection, function(value) {
23816
23816
  result2[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
23817
23817
  });
@@ -24194,7 +24194,7 @@ var require_lodash = __commonJS({
24194
24194
  }()) ? baseIsArguments : function(value) {
24195
24195
  return isObjectLike(value) && hasOwnProperty.call(value, "callee") && !propertyIsEnumerable.call(value, "callee");
24196
24196
  };
24197
- var isArray = Array13.isArray;
24197
+ var isArray = Array14.isArray;
24198
24198
  var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
24199
24199
  function isArrayLike(value) {
24200
24200
  return value != null && isLength(value.length) && !isFunction(value);
@@ -25150,7 +25150,7 @@ var require_lodash = __commonJS({
25150
25150
  lodash.bindKey = bindKey;
25151
25151
  lodash.castArray = castArray;
25152
25152
  lodash.chain = chain;
25153
- lodash.chunk = chunk8;
25153
+ lodash.chunk = chunk7;
25154
25154
  lodash.compact = compact;
25155
25155
  lodash.concat = concat;
25156
25156
  lodash.cond = cond;
@@ -25790,9 +25790,6 @@ function ae(e, t = {}) {
25790
25790
  return ce(me(e, t), t);
25791
25791
  }
25792
25792
 
25793
- // src/model/renderable/CurveModel.ts
25794
- var import_lodash = __toESM(require_lodash(), 1);
25795
-
25796
25793
  // src/model/renderable/ElementModel.ts
25797
25794
  import * as Y from "yjs";
25798
25795
  import { removeDeepObserver } from "@netless/forge-room";
@@ -25880,12 +25877,23 @@ var ElementModel = class _ElementModel {
25880
25877
  set shadow(value) {
25881
25878
  this.root.set(_ElementModel.KEYS.shadow, value);
25882
25879
  }
25883
- constructor(root, scope, liveCursor) {
25880
+ get isPerformanceEnvironment() {
25881
+ return this.isPerformanceMode() && this.shouldUseLocalPoints;
25882
+ }
25883
+ constructor(root, scope, liveCursor, isPerformanceMode) {
25884
25884
  _defineProperty(this, "shadowEmitter", null);
25885
25885
  _defineProperty(this, "root", void 0);
25886
25886
  _defineProperty(this, "scope", void 0);
25887
25887
  _defineProperty(this, "item", void 0);
25888
+ _defineProperty(this, "clearLocalPointsWhenYPointsChange", void 0);
25889
+ _defineProperty(this, "shouldUseLocalPoints", void 0);
25890
+ _defineProperty(this, "localPointsPick", void 0);
25888
25891
  _defineProperty(this, "liveCursor", void 0);
25892
+ _defineProperty(this, "appendPointsTimer", null);
25893
+ _defineProperty(this, "setPointsTimer", null);
25894
+ _defineProperty(this, "pointsUpdateTimer", null);
25895
+ _defineProperty(this, "isPerformanceMode", void 0);
25896
+ _defineProperty(this, "localPoints", []);
25889
25897
  _defineProperty(this, "handlePropChange", (events) => {
25890
25898
  if (!this.item) {
25891
25899
  return;
@@ -25924,24 +25932,68 @@ var ElementModel = class _ElementModel {
25924
25932
  }
25925
25933
  }
25926
25934
  } else if (event.target === this.root.get(_ElementModel.KEYS.points)) {
25927
- this.onVectorUpdate();
25928
- const liveCursorPoint = this.liveCursorPoint();
25929
- const ownerId = this.root.get(_ElementModel.KEYS.ownerId);
25930
- if (liveCursorPoint && ownerId) {
25931
- this.liveCursor.updateCursorPosition(liveCursorPoint, this.root.get(_ElementModel.KEYS.ownerId));
25935
+ if (this.isPerformanceEnvironment) {
25936
+ this.handlePointsChangePerformance();
25937
+ } else {
25938
+ this.handlePointsChangeDirect();
25932
25939
  }
25933
25940
  } else {
25934
25941
  }
25935
25942
  }
25936
25943
  });
25944
+ _defineProperty(this, "onPointsArrayChange", (points) => {
25945
+ if (this.localPoints.length >= points.length) {
25946
+ return;
25947
+ }
25948
+ const pointsChunk = points.slice(this.localPoints.length, this.localPoints.length + this.localPointsPick);
25949
+ this.localPoints = this.localPoints.concat(pointsChunk);
25950
+ this.onVectorUpdate();
25951
+ this.pointsUpdateTimer = window.requestAnimationFrame(() => {
25952
+ this.onPointsArrayChange(points);
25953
+ });
25954
+ });
25955
+ this.isPerformanceMode = isPerformanceMode;
25937
25956
  this.scope = scope;
25938
25957
  this.liveCursor = liveCursor;
25939
25958
  this.root = root;
25940
- if (!this.root.has(_ElementModel.KEYS.pointsMatrix)) {
25959
+ if (this.root.doc) {
25960
+ if (!this.root.has(_ElementModel.KEYS.pointsMatrix)) {
25961
+ this.root.set(_ElementModel.KEYS.pointsMatrix, [1, 0, 0, 1, 0, 0]);
25962
+ }
25963
+ } else {
25941
25964
  this.root.set(_ElementModel.KEYS.pointsMatrix, [1, 0, 0, 1, 0, 0]);
25942
25965
  }
25943
25966
  this.root.observeDeep(this.handlePropChange);
25944
25967
  }
25968
+ handlePointsChangeDirect() {
25969
+ this.onVectorUpdate();
25970
+ const liveCursorPoint = this.liveCursorPoint();
25971
+ const ownerId = this.root.get(_ElementModel.KEYS.ownerId);
25972
+ if (liveCursorPoint && ownerId) {
25973
+ this.liveCursor.updateCursorPosition(liveCursorPoint, this.root.get(_ElementModel.KEYS.ownerId));
25974
+ }
25975
+ }
25976
+ handlePointsChangePerformance() {
25977
+ const liveCursorPoint = this.liveCursorPoint();
25978
+ const ownerId = this.root.get(_ElementModel.KEYS.ownerId);
25979
+ if (liveCursorPoint && ownerId) {
25980
+ this.liveCursor.updateCursorPosition(liveCursorPoint, this.root.get(_ElementModel.KEYS.ownerId));
25981
+ }
25982
+ if (this.liveCursor.userManager.selfId !== ownerId || this.localPoints.length === 0) {
25983
+ if (this.pointsUpdateTimer) {
25984
+ window.cancelAnimationFrame(this.pointsUpdateTimer);
25985
+ }
25986
+ if (this.shadow == "") {
25987
+ this.localPoints = this.points;
25988
+ this.onVectorUpdate();
25989
+ } else {
25990
+ if (this.clearLocalPointsWhenYPointsChange) {
25991
+ this.localPoints = [];
25992
+ }
25993
+ this.onPointsArrayChange(this.points);
25994
+ }
25995
+ }
25996
+ }
25945
25997
  createPaperElement() {
25946
25998
  this.createPaperItem();
25947
25999
  if (this.item) {
@@ -25953,14 +26005,48 @@ var ElementModel = class _ElementModel {
25953
26005
  }
25954
26006
  }
25955
26007
  appendPoints(points) {
26008
+ if (this.isPerformanceEnvironment) {
26009
+ this.appendPointsPerformance(points);
26010
+ } else {
26011
+ this.appendPointsDirect(points);
26012
+ }
26013
+ }
26014
+ appendPointsDirect(points) {
25956
26015
  this.root.get(_ElementModel.KEYS.points).push(points);
25957
26016
  }
26017
+ appendPointsPerformance(points) {
26018
+ this.localPoints = this.localPoints.concat(points);
26019
+ this.onVectorUpdate();
26020
+ if (this.appendPointsTimer) {
26021
+ window.clearTimeout(this.appendPointsTimer);
26022
+ }
26023
+ if (this.localPoints.length % 80 === 0) {
26024
+ const yArray = this.root.get(_ElementModel.KEYS.points);
26025
+ yArray?.push(this.localPoints.slice(yArray.length));
26026
+ }
26027
+ this.appendPointsTimer = window.setTimeout(() => {
26028
+ this.appendPointsTimer = null;
26029
+ if (this.localPoints.length > 0) {
26030
+ const yArray = this.root.get(_ElementModel.KEYS.points);
26031
+ yArray?.push(this.localPoints.slice(yArray.length));
26032
+ }
26033
+ }, 100);
26034
+ }
25958
26035
  setPoints(points) {
26036
+ if (this.isPerformanceEnvironment) {
26037
+ this.setPointsPerformance(points);
26038
+ } else {
26039
+ this.setPointsDirect(points);
26040
+ }
26041
+ }
26042
+ setPointsDirect(points) {
25959
26043
  if (this.root.doc) {
25960
26044
  this.root.doc.transact(() => {
25961
26045
  const yArray = this.root.get(_ElementModel.KEYS.points);
25962
- yArray.delete(0, yArray.length);
25963
- yArray.push(points);
26046
+ if (yArray) {
26047
+ yArray.delete(0, yArray.length);
26048
+ yArray.push(points);
26049
+ }
25964
26050
  });
25965
26051
  } else {
25966
26052
  const yArray = this.root.get(_ElementModel.KEYS.points) || new Y.Array();
@@ -25969,6 +26055,29 @@ var ElementModel = class _ElementModel {
25969
26055
  this.root.set(_ElementModel.KEYS.points, yArray);
25970
26056
  }
25971
26057
  }
26058
+ setPointsPerformance(points) {
26059
+ this.localPoints = points;
26060
+ this.onVectorUpdate();
26061
+ if (this.setPointsTimer) {
26062
+ window.clearTimeout(this.setPointsTimer);
26063
+ }
26064
+ this.setPointsTimer = window.setTimeout(() => {
26065
+ if (this.root.doc) {
26066
+ this.root.doc.transact(() => {
26067
+ const yArray = this.root.get(_ElementModel.KEYS.points);
26068
+ if (yArray) {
26069
+ yArray.delete(0, yArray.length);
26070
+ yArray.push(points);
26071
+ }
26072
+ });
26073
+ } else {
26074
+ const yArray = this.root.get(_ElementModel.KEYS.points) || new Y.Array();
26075
+ yArray.delete(0, yArray.length);
26076
+ yArray.push(points);
26077
+ this.root.set(_ElementModel.KEYS.points, yArray);
26078
+ }
26079
+ }, 100);
26080
+ }
25972
26081
  appendPointsMatrix(matrix) {
25973
26082
  const current = new this.scope.Matrix(this.pointsMatrix);
25974
26083
  const next = matrix.appended(current);
@@ -26067,47 +26176,53 @@ function _toPrimitive3(t, r) {
26067
26176
  return ("string" === r ? String : Number)(t);
26068
26177
  }
26069
26178
  var CurveModel = class extends ElementModel {
26070
- constructor(root, scope, liveCursor) {
26071
- super(root, scope, liveCursor);
26179
+ constructor(root, scope, liveCursor, isPerformanceMode) {
26180
+ super(root, scope, liveCursor, isPerformanceMode);
26072
26181
  _defineProperty3(this, "item", null);
26073
- _defineProperty3(this, "debugPath", void 0);
26074
26182
  _defineProperty3(this, "debug", false);
26075
- if (!this.root.has("type")) {
26183
+ _defineProperty3(this, "clearLocalPointsWhenYPointsChange", false);
26184
+ _defineProperty3(this, "shouldUseLocalPoints", true);
26185
+ _defineProperty3(this, "localPointsPick", 6);
26186
+ if (!this.root.doc || !this.root.has("type")) {
26076
26187
  this.root.set("type", "curve");
26077
26188
  }
26078
- if (!this.root.has("points")) {
26189
+ if (!this.root.doc || !this.root.has("points")) {
26079
26190
  this.root.set("points", new Y2.Array());
26080
26191
  }
26081
- this.debugPath = new scope.Path();
26082
26192
  }
26083
26193
  average(a2, b2) {
26084
26194
  return (a2 + b2) / 2;
26085
26195
  }
26086
26196
  parsePoints(points) {
26197
+ const hasRealPressure = points.some((p) => p.length >= 3 && p[2] > 0);
26198
+ const viewScale = this.scope.project.view.matrix.scaling.x || 1;
26199
+ const taper = this.strokeWidth * 5 / viewScale;
26200
+ const streamline = Math.min(0.7, 0.7 * viewScale);
26087
26201
  return ae(points, {
26088
26202
  size: this.strokeWidth,
26089
- smoothing: 0.5,
26090
- thinning: -0.5,
26091
- streamline: 0.5,
26092
- simulatePressure: true,
26203
+ smoothing: 0.7,
26204
+ thinning: 0.5,
26205
+ streamline,
26206
+ simulatePressure: !hasRealPressure,
26093
26207
  start: {
26094
- taper: this.strokeWidth * 10,
26208
+ taper,
26095
26209
  cap: true
26096
26210
  },
26097
26211
  end: {
26098
- taper: this.strokeWidth * 20,
26212
+ taper,
26099
26213
  cap: true
26100
26214
  }
26101
26215
  });
26102
26216
  }
26103
26217
  matrixedPoints() {
26104
- const points = this.points;
26218
+ const points = this.localPoints.length === 0 ? this.points : this.localPoints;
26105
26219
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26106
26220
  const output = [];
26107
- for (let i = 0, len = points.length; i < len; i += 2) {
26221
+ for (let i = 0, len = points.length; i < len; i += 3) {
26108
26222
  const p = new this.scope.Point(points[i], points[i + 1]);
26109
26223
  const tp = p.transform(matrix);
26110
- output.push([tp.x, tp.y]);
26224
+ const pressure = points[i + 2] ?? 0;
26225
+ output.push([tp.x, tp.y, pressure]);
26111
26226
  }
26112
26227
  return output;
26113
26228
  }
@@ -26136,34 +26251,30 @@ var CurveModel = class extends ElementModel {
26136
26251
  }
26137
26252
  return path;
26138
26253
  }
26139
- updateDebugPath() {
26140
- this.debugPath = new this.scope.Path();
26141
- const points = (0, import_lodash.chunk)(this.points, 2);
26142
- for (let i = 0, len = points.length; i < len; i++) {
26143
- const point = new this.scope.Point(points[i][0], points[i][1]);
26144
- if (i === 0) {
26145
- this.debugPath.moveTo(point);
26146
- } else {
26147
- this.debugPath.lineTo(point);
26148
- }
26149
- this.debugPath.strokeWidth = 1;
26150
- this.debugPath.strokeColor = new this.scope.Color(1, 0, 0, 1);
26151
- }
26152
- }
26153
26254
  onVectorUpdate() {
26154
26255
  if (!this.item) {
26155
26256
  return;
26156
26257
  }
26258
+ const matrixedPts = this.matrixedPoints();
26157
26259
  if (this.debug) {
26158
- this.debugPath.remove();
26159
- this.updateDebugPath();
26160
- }
26161
- const points = this.parsePoints(this.matrixedPoints());
26162
- const path = this.createPath(points);
26163
- this.item.removeSegments();
26164
- this.item.addSegments(path.segments);
26165
- if (this.debug) {
26166
- this.item.addChild(this.debugPath);
26260
+ const path = new this.scope.Path();
26261
+ for (let i = 0; i < matrixedPts.length; i++) {
26262
+ const p = new this.scope.Point(matrixedPts[i][0], matrixedPts[i][1]);
26263
+ if (i === 0) {
26264
+ path.moveTo(p);
26265
+ } else {
26266
+ path.lineTo(p);
26267
+ }
26268
+ }
26269
+ this.item.removeSegments();
26270
+ this.item.addSegments(path.segments);
26271
+ this.item.fillColor = null;
26272
+ this.item.strokeWidth = this.strokeWidth;
26273
+ } else {
26274
+ const points = this.parsePoints(matrixedPts);
26275
+ const path = this.createPath(points);
26276
+ this.item.removeSegments();
26277
+ this.item.addSegments(path.segments);
26167
26278
  }
26168
26279
  }
26169
26280
  createPaperItem() {
@@ -26186,11 +26297,11 @@ var CurveModel = class extends ElementModel {
26186
26297
  }
26187
26298
  liveCursorPoint() {
26188
26299
  const yArray = this.root.get(ElementModel.KEYS.points);
26189
- if (yArray.length < 2) {
26300
+ if (yArray.length < 3) {
26190
26301
  return null;
26191
26302
  }
26192
26303
  const len = yArray.length;
26193
- const point = new this.scope.Point(yArray.get(len - 2), yArray.get(len - 1));
26304
+ const point = new this.scope.Point(yArray.get(len - 3), yArray.get(len - 2));
26194
26305
  return point.transform(new this.scope.Matrix(this.pointsMatrix));
26195
26306
  }
26196
26307
  onStyleKeyUpdate(key) {
@@ -26228,15 +26339,24 @@ function _toPrimitive4(t, r) {
26228
26339
  return ("string" === r ? String : Number)(t);
26229
26340
  }
26230
26341
  var SelectorModel = class extends ElementModel {
26231
- constructor(root, scope, liveCursor) {
26232
- super(root, scope, liveCursor);
26342
+ get drawPoints() {
26343
+ if (this.localPoints.length >= 4) {
26344
+ return this.localPoints;
26345
+ }
26346
+ return this.points;
26347
+ }
26348
+ constructor(root, scope, liveCursor, isPerformanceMode) {
26349
+ super(root, scope, liveCursor, isPerformanceMode);
26233
26350
  _defineProperty4(this, "item", null);
26234
- if (!this.root.has("type")) {
26351
+ _defineProperty4(this, "clearLocalPointsWhenYPointsChange", true);
26352
+ _defineProperty4(this, "shouldUseLocalPoints", true);
26353
+ _defineProperty4(this, "localPointsPick", 4);
26354
+ if (this.root.doc && !this.root.has("type")) {
26235
26355
  this.root.set("type", "selector");
26236
26356
  }
26237
- if (!this.root.has("points")) {
26357
+ if (this.root.doc && !this.root.has("points")) {
26238
26358
  const initPoints = new Y3.Array();
26239
- initPoints.push([0, 0, 0, 0, 0]);
26359
+ initPoints.push([0, 0, 0, 0]);
26240
26360
  this.root.set("points", initPoints);
26241
26361
  }
26242
26362
  }
@@ -26247,8 +26367,8 @@ var SelectorModel = class extends ElementModel {
26247
26367
  }
26248
26368
  createPaperRect() {
26249
26369
  const scope = this.scope;
26250
- const bounds = new scope.Rectangle(new scope.Point(this.points[0], this.points[1]), new scope.Size(this.points[2], this.points[3]));
26251
- return new scope.Path.Rectangle(bounds, new scope.Point(this.points[4], this.points[4]));
26370
+ const bounds = new scope.Rectangle(new scope.Point(this.drawPoints[0], this.drawPoints[1]), new scope.Size(this.drawPoints[2], this.drawPoints[3]));
26371
+ return new scope.Path.Rectangle(bounds);
26252
26372
  }
26253
26373
  onVectorUpdate() {
26254
26374
  if (!this.item) {
@@ -26282,7 +26402,8 @@ var SelectorModel = class extends ElementModel {
26282
26402
  import * as Y4 from "yjs";
26283
26403
 
26284
26404
  // src/utils/paperjs.ts
26285
- var import_lodash2 = __toESM(require_lodash(), 1);
26405
+ var import_lodash = __toESM(require_lodash(), 1);
26406
+ import { metrics } from "@netless/forge-room";
26286
26407
  function _defineProperty5(e, r, t) {
26287
26408
  return (r = _toPropertyKey5(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
26288
26409
  }
@@ -26315,7 +26436,7 @@ function serializePath(path) {
26315
26436
  }, []);
26316
26437
  }
26317
26438
  function deserializePath(points, scope, matrix) {
26318
- const segmentGroup = (0, import_lodash2.chunk)(points, 6);
26439
+ const segmentGroup = (0, import_lodash.chunk)(points, 6);
26319
26440
  const path = new scope.Path();
26320
26441
  path.segments = segmentGroup.map((v) => deserializeSegment(v, scope, matrix));
26321
26442
  return path;
@@ -26325,7 +26446,27 @@ var AnimationFrame = class {
26325
26446
  _defineProperty5(this, "callbacks", []);
26326
26447
  _defineProperty5(this, "lastTime", 0);
26327
26448
  _defineProperty5(this, "fps", 45);
26449
+ _defineProperty5(this, "lastCallbackTime", 0);
26450
+ _defineProperty5(this, "fpsBuffer", []);
26451
+ _defineProperty5(this, "FPS_REPORT_INTERVAL", 2700);
26328
26452
  _defineProperty5(this, "handleCallbacks", () => {
26453
+ const now = performance.now();
26454
+ if (this.lastCallbackTime > 0) {
26455
+ const actualFps = 1e3 / (now - this.lastCallbackTime);
26456
+ this.fpsBuffer.push(actualFps);
26457
+ if (this.fpsBuffer.length >= this.FPS_REPORT_INTERVAL) {
26458
+ const avg = this.fpsBuffer.reduce((a2, b2) => a2 + b2, 0) / this.fpsBuffer.length;
26459
+ const min = Math.min(...this.fpsBuffer);
26460
+ const sorted = [...this.fpsBuffer].sort((a2, b2) => a2 - b2);
26461
+ const p90 = sorted[Math.floor(sorted.length * 0.9)];
26462
+ metrics().gauge("fps", Math.round(avg), {
26463
+ min: Math.round(min),
26464
+ p90: Math.round(p90)
26465
+ });
26466
+ this.fpsBuffer = [];
26467
+ }
26468
+ }
26469
+ this.lastCallbackTime = now;
26329
26470
  const functions = this.callbacks;
26330
26471
  this.callbacks = [];
26331
26472
  for (let i = 0, l2 = functions.length; i < l2; i++) {
@@ -26369,13 +26510,22 @@ function _toPrimitive6(t, r) {
26369
26510
  return ("string" === r ? String : Number)(t);
26370
26511
  }
26371
26512
  var SegmentsModel = class extends ElementModel {
26372
- constructor(root, scope, type, liveCursor) {
26373
- super(root, scope, liveCursor);
26513
+ get drawPoints() {
26514
+ if (this.localPoints.length >= 4) {
26515
+ return this.localPoints;
26516
+ }
26517
+ return this.points;
26518
+ }
26519
+ constructor(root, scope, type, liveCursor, isPerformanceMode) {
26520
+ super(root, scope, liveCursor, isPerformanceMode);
26374
26521
  _defineProperty6(this, "item", null);
26375
- if (!this.root.has("type")) {
26522
+ _defineProperty6(this, "clearLocalPointsWhenYPointsChange", true);
26523
+ _defineProperty6(this, "shouldUseLocalPoints", true);
26524
+ _defineProperty6(this, "localPointsPick", 24);
26525
+ if (this.root.doc && !this.root.has("type")) {
26376
26526
  this.root.set("type", type);
26377
26527
  }
26378
- if (!this.root.has("points")) {
26528
+ if (this.root.doc && !this.root.has("points")) {
26379
26529
  this.root.set("points", new Y4.Array());
26380
26530
  }
26381
26531
  }
@@ -26395,13 +26545,13 @@ var SegmentsModel = class extends ElementModel {
26395
26545
  }
26396
26546
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26397
26547
  this.item.removeSegments();
26398
- const next = deserializePath(this.points, this.scope, matrix);
26548
+ const next = deserializePath(this.drawPoints, this.scope, matrix);
26399
26549
  this.item.addSegments(next.segments);
26400
26550
  this.item.closePath();
26401
26551
  }
26402
26552
  createPaperItem() {
26403
26553
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26404
- this.item = deserializePath(this.points, this.scope, matrix);
26554
+ this.item = deserializePath(this.drawPoints, this.scope, matrix);
26405
26555
  this.item.strokeColor = new this.scope.Color(this.strokeColor);
26406
26556
  this.item.dashArray = this.dashArray;
26407
26557
  this.item.strokeWidth = this.strokeWidth;
@@ -26428,7 +26578,7 @@ var SegmentsModel = class extends ElementModel {
26428
26578
  };
26429
26579
 
26430
26580
  // src/model/renderable/LineModel.ts
26431
- var import_lodash4 = __toESM(require_lodash(), 1);
26581
+ var import_lodash3 = __toESM(require_lodash(), 1);
26432
26582
  import * as Y5 from "yjs";
26433
26583
 
26434
26584
  // src/tool/WhiteboardTool.ts
@@ -26449,6 +26599,8 @@ function _toPrimitive7(t, r) {
26449
26599
  }
26450
26600
  return ("string" === r ? String : Number)(t);
26451
26601
  }
26602
+ var DRAG_FPS = 10;
26603
+ var DRAG_FRAME_MS = 1e3 / DRAG_FPS;
26452
26604
  var WhiteboardTool = class {
26453
26605
  constructor(enableToolEvent, modelGetter, shadowEmitter, scope) {
26454
26606
  _defineProperty7(this, "modelGetter", void 0);
@@ -26457,24 +26609,60 @@ var WhiteboardTool = class {
26457
26609
  _defineProperty7(this, "shadowEmitter", void 0);
26458
26610
  _defineProperty7(this, "enableToolEvent", void 0);
26459
26611
  _defineProperty7(this, "eventAvailable", false);
26612
+ _defineProperty7(this, "lastDragTime", 0);
26613
+ _defineProperty7(this, "dragRafId", 0);
26614
+ _defineProperty7(this, "pendingDragEvent", null);
26460
26615
  _defineProperty7(this, "onMouseDownSelf", (event) => {
26461
26616
  this.eventAvailable = this.enableToolEvent();
26462
26617
  if (!this.eventAvailable) {
26463
26618
  return;
26464
26619
  }
26620
+ this.lastDragTime = 0;
26621
+ if (this.dragRafId) {
26622
+ cancelAnimationFrame(this.dragRafId);
26623
+ this.dragRafId = 0;
26624
+ }
26625
+ this.pendingDragEvent = null;
26465
26626
  this.shadowEmitter.setActive(true);
26466
26627
  this.onMouseDown(event);
26467
26628
  });
26629
+ _defineProperty7(this, "flushPendingDrag", () => {
26630
+ this.dragRafId = 0;
26631
+ if (this.pendingDragEvent) {
26632
+ this.lastDragTime = performance.now();
26633
+ const event = this.pendingDragEvent;
26634
+ this.pendingDragEvent = null;
26635
+ this.onMouseDrag(event);
26636
+ }
26637
+ });
26468
26638
  _defineProperty7(this, "onMouseDragSelf", (event) => {
26469
26639
  if (!this.eventAvailable) {
26470
26640
  return;
26471
26641
  }
26472
- this.onMouseDrag(event);
26642
+ const now = performance.now();
26643
+ if (now - this.lastDragTime >= DRAG_FRAME_MS) {
26644
+ this.lastDragTime = now;
26645
+ this.pendingDragEvent = null;
26646
+ this.onMouseDrag(event);
26647
+ } else {
26648
+ this.pendingDragEvent = event;
26649
+ if (!this.dragRafId) {
26650
+ this.dragRafId = requestAnimationFrame(this.flushPendingDrag);
26651
+ }
26652
+ }
26473
26653
  });
26474
26654
  _defineProperty7(this, "onMouseUpSelf", (event) => {
26475
26655
  if (!this.eventAvailable) {
26476
26656
  return;
26477
26657
  }
26658
+ if (this.dragRafId) {
26659
+ cancelAnimationFrame(this.dragRafId);
26660
+ this.dragRafId = 0;
26661
+ }
26662
+ if (this.pendingDragEvent) {
26663
+ this.onMouseDrag(this.pendingDragEvent);
26664
+ this.pendingDragEvent = null;
26665
+ }
26478
26666
  this.onMouseUp(event);
26479
26667
  this.shadowEmitter.setActive(false);
26480
26668
  });
@@ -26490,7 +26678,7 @@ var WhiteboardTool = class {
26490
26678
  };
26491
26679
 
26492
26680
  // src/tool/LineTool.ts
26493
- var import_lodash3 = __toESM(require_lodash(), 1);
26681
+ var import_lodash2 = __toESM(require_lodash(), 1);
26494
26682
  function _defineProperty8(e, r, t) {
26495
26683
  return (r = _toPropertyKey8(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
26496
26684
  }
@@ -26539,7 +26727,7 @@ var LineTool = class extends WhiteboardTool {
26539
26727
  const point = path.getPointAt(distance);
26540
26728
  return [point.x, point.y];
26541
26729
  });
26542
- this.elementModel.setPoints((0, import_lodash3.flattenDeep)(points));
26730
+ this.elementModel.setPoints((0, import_lodash2.flattenDeep)(points));
26543
26731
  }
26544
26732
  }
26545
26733
  onMouseUp(_event) {
@@ -26569,6 +26757,12 @@ function _toPrimitive9(t, r) {
26569
26757
  return ("string" === r ? String : Number)(t);
26570
26758
  }
26571
26759
  var LineModel = class extends ElementModel {
26760
+ get drawPoints() {
26761
+ if (this.localPoints.length > 0) {
26762
+ return this.localPoints;
26763
+ }
26764
+ return this.points;
26765
+ }
26572
26766
  get arrowSize() {
26573
26767
  return this.strokeWidth * 5 + 15;
26574
26768
  }
@@ -26584,20 +26778,23 @@ var LineModel = class extends ElementModel {
26584
26778
  set tailArrow(value) {
26585
26779
  this.root.set("tailArrow", value);
26586
26780
  }
26587
- constructor(root, scope, liveCursor) {
26588
- super(root, scope, liveCursor);
26781
+ constructor(root, scope, liveCursor, isPerformanceMode) {
26782
+ super(root, scope, liveCursor, isPerformanceMode);
26589
26783
  _defineProperty9(this, "controlledPoints", []);
26784
+ _defineProperty9(this, "clearLocalPointsWhenYPointsChange", true);
26785
+ _defineProperty9(this, "shouldUseLocalPoints", true);
26786
+ _defineProperty9(this, "localPointsPick", 99);
26590
26787
  _defineProperty9(this, "item", null);
26591
- if (!this.root.has("type")) {
26788
+ if (this.root.doc && !this.root.has("type")) {
26592
26789
  this.root.set("type", "arrow");
26593
26790
  }
26594
- if (!this.root.has("points")) {
26791
+ if (this.root.doc && !this.root.has("points")) {
26595
26792
  this.root.set("points", new Y5.Array());
26596
26793
  }
26597
- if (!this.root.has("headArrow")) {
26794
+ if (this.root.doc && !this.root.has("headArrow")) {
26598
26795
  this.root.set("headArrow", "none");
26599
26796
  }
26600
- if (!this.root.has("tailArrow")) {
26797
+ if (this.root.doc && !this.root.has("tailArrow")) {
26601
26798
  this.root.set("tailArrow", "normal");
26602
26799
  }
26603
26800
  }
@@ -26613,7 +26810,7 @@ var LineModel = class extends ElementModel {
26613
26810
  }
26614
26811
  renderLine() {
26615
26812
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26616
- const papperPoints = (0, import_lodash4.chunk)(this.points, 2).map((item) => {
26813
+ const papperPoints = (0, import_lodash3.chunk)(this.drawPoints, 2).map((item) => {
26617
26814
  return new this.scope.Point(item[0], item[1]).transform(matrix);
26618
26815
  });
26619
26816
  const path = new this.scope.Path();
@@ -26727,13 +26924,14 @@ var LineControlPoint = class {
26727
26924
  if (this.position) {
26728
26925
  return this.model.scope.project.view.projectToView(this.position.transform(matrix));
26729
26926
  }
26927
+ const points = this.model["drawPoints"];
26730
26928
  const from = {
26731
- x: this.model.points[0],
26732
- y: this.model.points[1]
26929
+ x: points[0],
26930
+ y: points[1]
26733
26931
  };
26734
26932
  const to = {
26735
- x: this.model.points[this.model.points.length - 2],
26736
- y: this.model.points[this.model.points.length - 1]
26933
+ x: points[points.length - 2],
26934
+ y: points[points.length - 1]
26737
26935
  };
26738
26936
  const clonedPath = new this.scope.Path.Line(from, to);
26739
26937
  this.position = clonedPath.getPointAt(clonedPath.length * distance);
@@ -26746,9 +26944,9 @@ var LineControlPoint = class {
26746
26944
  }
26747
26945
  const pointsMatrix = new this.model.scope.Matrix(this.model.pointsMatrix);
26748
26946
  const invertedPoint = point.transform(pointsMatrix.inverted());
26749
- const points = this.model.points;
26947
+ const points = this.model["drawPoints"];
26750
26948
  this.position = invertedPoint;
26751
- const clonedPoints = (0, import_lodash4.cloneDeep)(points);
26949
+ const clonedPoints = (0, import_lodash3.cloneDeep)(points);
26752
26950
  clonedPoints[this.options.index * 2] = invertedPoint.x;
26753
26951
  clonedPoints[this.options.index * 2 + 1] = invertedPoint.y;
26754
26952
  this.model.setPoints(clonedPoints);
@@ -26794,9 +26992,18 @@ var PointTextModel = class extends ElementModel {
26794
26992
  set fontFamily(value) {
26795
26993
  this.root.set("font-family", value);
26796
26994
  }
26797
- constructor(root, scope, liveCursor) {
26798
- super(root, scope, liveCursor);
26995
+ get drawPoints() {
26996
+ if (this.localPoints.length > 1) {
26997
+ return this.localPoints;
26998
+ }
26999
+ return this.points;
27000
+ }
27001
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27002
+ super(root, scope, liveCursor, isPerformanceMode);
26799
27003
  _defineProperty10(this, "item", null);
27004
+ _defineProperty10(this, "clearLocalPointsWhenYPointsChange", true);
27005
+ _defineProperty10(this, "shouldUseLocalPoints", false);
27006
+ _defineProperty10(this, "localPointsPick", 2);
26800
27007
  _defineProperty10(this, "handleTextPropChange", (event) => {
26801
27008
  if (!this.item) {
26802
27009
  return;
@@ -26813,18 +27020,20 @@ var PointTextModel = class extends ElementModel {
26813
27020
  }
26814
27021
  }
26815
27022
  });
26816
- if (!this.root.has("type")) {
27023
+ if (this.root.doc && !this.root.has("type")) {
26817
27024
  this.root.set("type", "point-text");
26818
27025
  }
26819
- if (!this.root.has(ElementModel.KEYS.points)) {
27026
+ if (this.root.doc && !this.root.has(ElementModel.KEYS.points)) {
26820
27027
  this.root.set(ElementModel.KEYS.points, new Y6.Array());
26821
27028
  }
26822
27029
  this.root.observe(this.handleTextPropChange);
26823
- if (this.root.has("font-size")) {
26824
- setTimeout(() => {
26825
- this.updateTextPosition();
26826
- }, 60);
26827
- }
27030
+ setTimeout(() => {
27031
+ if (this.root && this.root.has("font-size")) {
27032
+ setTimeout(() => {
27033
+ this.updateTextPosition();
27034
+ }, 60);
27035
+ }
27036
+ }, 60);
26828
27037
  }
26829
27038
  subDispose() {
26830
27039
  removeObserver(this.root, this.handleTextPropChange);
@@ -26842,10 +27051,11 @@ var PointTextModel = class extends ElementModel {
26842
27051
  if (!this.item) {
26843
27052
  return null;
26844
27053
  }
27054
+ console.log("[][][] drawPoints", this.drawPoints);
26845
27055
  const bounds = this.item.internalBounds;
26846
27056
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26847
- const topLeft = new this.scope.Point(this.points[0], this.points[1]).transform(matrix);
26848
- const topRight = new this.scope.Point(this.points[0] + bounds.width, this.points[1]).transform(matrix);
27057
+ const topLeft = new this.scope.Point(this.drawPoints[0], this.drawPoints[1]).transform(matrix);
27058
+ const topRight = new this.scope.Point(this.drawPoints[0] + bounds.width, this.drawPoints[1]).transform(matrix);
26849
27059
  let scaleX = topRight.getDistance(topLeft) / bounds.width;
26850
27060
  scaleX = Number.isNaN(scaleX) ? 1 : scaleX;
26851
27061
  const angle = topRight.subtract(topLeft).angle;
@@ -26933,13 +27143,22 @@ function _toPrimitive11(t, r) {
26933
27143
  return ("string" === r ? String : Number)(t);
26934
27144
  }
26935
27145
  var TriangleModel = class extends ElementModel {
26936
- constructor(root, scope, liveCursor) {
26937
- super(root, scope, liveCursor);
27146
+ get drawPoints() {
27147
+ if (this.localPoints.length >= 6) {
27148
+ return this.localPoints;
27149
+ }
27150
+ return this.points;
27151
+ }
27152
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27153
+ super(root, scope, liveCursor, isPerformanceMode);
26938
27154
  _defineProperty11(this, "item", null);
26939
- if (!this.root.has("type")) {
27155
+ _defineProperty11(this, "clearLocalPointsWhenYPointsChange", true);
27156
+ _defineProperty11(this, "shouldUseLocalPoints", true);
27157
+ _defineProperty11(this, "localPointsPick", 6);
27158
+ if (this.root.doc && !this.root.has("type")) {
26940
27159
  this.root.set("type", "triangle");
26941
27160
  }
26942
- if (!this.root.has("points")) {
27161
+ if (this.root.doc && !this.root.has("points")) {
26943
27162
  this.root.set("points", new Y7.Array());
26944
27163
  }
26945
27164
  }
@@ -26971,9 +27190,9 @@ var TriangleModel = class extends ElementModel {
26971
27190
  return;
26972
27191
  }
26973
27192
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26974
- const p1 = new this.scope.Point(this.points[0], this.points[1]).transform(matrix);
26975
- const p2 = new this.scope.Point(this.points[2], this.points[3]).transform(matrix);
26976
- const p3 = new this.scope.Point(this.points[4], this.points[5]).transform(matrix);
27193
+ const p1 = new this.scope.Point(this.drawPoints[0], this.drawPoints[1]).transform(matrix);
27194
+ const p2 = new this.scope.Point(this.drawPoints[2], this.drawPoints[3]).transform(matrix);
27195
+ const p3 = new this.scope.Point(this.drawPoints[4], this.drawPoints[5]).transform(matrix);
26977
27196
  this.item.removeSegments();
26978
27197
  this.item.moveTo(p1);
26979
27198
  this.item.lineTo(p2);
@@ -26985,7 +27204,7 @@ var TriangleModel = class extends ElementModel {
26985
27204
  config.controlPoints.push({
26986
27205
  name: "triangle",
26987
27206
  getPosition: () => {
26988
- const point = new this.scope.Point(this.points[0], this.points[1]);
27207
+ const point = new this.scope.Point(this.drawPoints[0], this.drawPoints[1]);
26989
27208
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
26990
27209
  return this.scope.project.view.projectToView(point.transform(pointsMatrix));
26991
27210
  },
@@ -26995,7 +27214,7 @@ var TriangleModel = class extends ElementModel {
26995
27214
  }
26996
27215
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
26997
27216
  const trPoint = point.transform(pointsMatrix.inverted());
26998
- const oldPoints = this.points;
27217
+ const oldPoints = this.drawPoints;
26999
27218
  this.setPoints([trPoint.x, trPoint.y, oldPoints[2], oldPoints[3], oldPoints[4], oldPoints[5]]);
27000
27219
  }
27001
27220
  });
@@ -27034,25 +27253,34 @@ function _toPrimitive12(t, r) {
27034
27253
  return ("string" === r ? String : Number)(t);
27035
27254
  }
27036
27255
  var RectangleModel = class extends ElementModel {
27037
- constructor(root, scope, liveCursor) {
27038
- super(root, scope, liveCursor);
27256
+ get drawPoints() {
27257
+ if (this.localPoints.length >= 4) {
27258
+ return this.localPoints;
27259
+ }
27260
+ return this.points;
27261
+ }
27262
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27263
+ super(root, scope, liveCursor, isPerformanceMode);
27039
27264
  _defineProperty12(this, "item", null);
27040
- if (!this.root.has("type")) {
27265
+ _defineProperty12(this, "clearLocalPointsWhenYPointsChange", true);
27266
+ _defineProperty12(this, "shouldUseLocalPoints", true);
27267
+ _defineProperty12(this, "localPointsPick", 4);
27268
+ if (this.root.doc && !this.root.has("type")) {
27041
27269
  this.root.set("type", "rectangle");
27042
27270
  }
27043
- if (!this.root.has("points")) {
27271
+ if (this.root.doc && !this.root.has("points")) {
27044
27272
  const initPoints = new Y8.Array();
27045
27273
  initPoints.push([0, 0, 0, 0]);
27046
27274
  this.root.set("points", initPoints);
27047
27275
  }
27048
- if (!this.root.has("radius")) {
27276
+ if (this.root.doc && !this.root.has("radius")) {
27049
27277
  this.root.set("radius", 0);
27050
27278
  }
27051
27279
  }
27052
27280
  subDispose() {
27053
27281
  }
27054
27282
  liveCursorPoint() {
27055
- const points = this.points;
27283
+ const points = this.drawPoints;
27056
27284
  if (points.length < 4) {
27057
27285
  return null;
27058
27286
  }
@@ -27060,7 +27288,7 @@ var RectangleModel = class extends ElementModel {
27060
27288
  return new this.scope.Point(points[2], points[3]).transform(matrix);
27061
27289
  }
27062
27290
  createSegments() {
27063
- const [a2, b2, c, d] = this.points;
27291
+ const [a2, b2, c, d] = this.drawPoints;
27064
27292
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27065
27293
  const maxRadius = this.maxRadiusLength();
27066
27294
  const radius = this.root.get("radius") * maxRadius;
@@ -27125,7 +27353,7 @@ var RectangleModel = class extends ElementModel {
27125
27353
  }
27126
27354
  maxRadiusLength() {
27127
27355
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27128
- const points = this.points;
27356
+ const points = this.drawPoints;
27129
27357
  const topLeft = new this.scope.Point(points[0], points[1]).transform(pointsMatrix);
27130
27358
  const topRight = new this.scope.Point(points[2], points[1]).transform(pointsMatrix);
27131
27359
  const bottomLeft = new this.scope.Point(points[0], points[3]).transform(pointsMatrix);
@@ -27150,7 +27378,7 @@ var RectangleModel = class extends ElementModel {
27150
27378
  name: "rect-radius",
27151
27379
  getPosition: () => {
27152
27380
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27153
- const points = this.points;
27381
+ const points = this.drawPoints;
27154
27382
  const radius = this.root.get("radius") * this.maxRadiusLength();
27155
27383
  let c1 = new this.scope.Point(points[0], points[1]).transform(matrix);
27156
27384
  const c3 = new this.scope.Point(points[2], points[3]).transform(matrix);
@@ -27169,7 +27397,7 @@ var RectangleModel = class extends ElementModel {
27169
27397
  if (!this.item) {
27170
27398
  return;
27171
27399
  }
27172
- const points = this.points;
27400
+ const points = this.drawPoints;
27173
27401
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27174
27402
  const maxRadius = Math.min(points[2] - points[0], points[3] - points[1]) / 2;
27175
27403
  const trPoint = point.transform(pointsMatrix.inverted());
@@ -27198,7 +27426,7 @@ var RectangleModel = class extends ElementModel {
27198
27426
  var elementsUndoOrigin = "elementsUndoOrigin";
27199
27427
 
27200
27428
  // src/model/renderable/EraserModel.ts
27201
- var import_lodash5 = __toESM(require_lodash(), 1);
27429
+ var import_lodash4 = __toESM(require_lodash(), 1);
27202
27430
  import * as Y9 from "yjs";
27203
27431
  function _defineProperty13(e, r, t) {
27204
27432
  return (r = _toPropertyKey13(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
@@ -27218,14 +27446,23 @@ function _toPrimitive13(t, r) {
27218
27446
  return ("string" === r ? String : Number)(t);
27219
27447
  }
27220
27448
  var EraserModel = class extends ElementModel {
27221
- constructor(root, scope, liveCursor) {
27222
- super(root, scope, liveCursor);
27449
+ get drawPoints() {
27450
+ if (this.localPoints.length > 0) {
27451
+ return this.localPoints;
27452
+ }
27453
+ return this.points;
27454
+ }
27455
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27456
+ super(root, scope, liveCursor, isPerformanceMode);
27223
27457
  _defineProperty13(this, "item", null);
27224
27458
  _defineProperty13(this, "sliceBegin", 0);
27225
- if (!this.root.has("type")) {
27459
+ _defineProperty13(this, "clearLocalPointsWhenYPointsChange", false);
27460
+ _defineProperty13(this, "shouldUseLocalPoints", true);
27461
+ _defineProperty13(this, "localPointsPick", 4);
27462
+ if (this.root.doc && !this.root.has("type")) {
27226
27463
  this.root.set("type", "eraser");
27227
27464
  }
27228
- if (!this.root.has("points")) {
27465
+ if (this.root.doc && !this.root.has("points")) {
27229
27466
  this.root.set("points", new Y9.Array());
27230
27467
  }
27231
27468
  }
@@ -27258,7 +27495,7 @@ var EraserModel = class extends ElementModel {
27258
27495
  return path;
27259
27496
  }
27260
27497
  parsePoints(points) {
27261
- const groupPoints = (0, import_lodash5.chunk)(points, 2);
27498
+ const groupPoints = (0, import_lodash4.chunk)(points, 2);
27262
27499
  return ae(groupPoints, {
27263
27500
  size: this.strokeWidth,
27264
27501
  smoothing: 0.5,
@@ -27276,7 +27513,7 @@ var EraserModel = class extends ElementModel {
27276
27513
  });
27277
27514
  }
27278
27515
  matrixedPoints() {
27279
- const currentPoints = (0, import_lodash5.chunk)(this.points, 2).slice(this.sliceBegin);
27516
+ const currentPoints = (0, import_lodash4.chunk)(this.drawPoints, 2).slice(this.sliceBegin);
27280
27517
  return currentPoints.map((_ref) => {
27281
27518
  let [x, y] = _ref;
27282
27519
  return new this.scope.Point(x, y);
@@ -27304,11 +27541,11 @@ var EraserModel = class extends ElementModel {
27304
27541
  this.item.fillColor = new this.scope.Color(this.strokeColor);
27305
27542
  this.onVectorUpdate();
27306
27543
  this.item.onFrame = () => {
27307
- if (!this.points) {
27544
+ if (!this.drawPoints) {
27308
27545
  return;
27309
27546
  }
27310
- if (this.points.length / 2 > 50) {
27311
- this.sliceBegin = this.points.length / 2 - 50;
27547
+ if (this.drawPoints.length / 2 > 50) {
27548
+ this.sliceBegin = this.drawPoints.length / 2 - 50;
27312
27549
  }
27313
27550
  };
27314
27551
  }
@@ -27341,7 +27578,7 @@ var EraserModel = class extends ElementModel {
27341
27578
  };
27342
27579
 
27343
27580
  // src/model/renderable/LaserPointerModel.ts
27344
- var import_lodash6 = __toESM(require_lodash(), 1);
27581
+ var import_lodash5 = __toESM(require_lodash(), 1);
27345
27582
  import * as Y10 from "yjs";
27346
27583
  function _defineProperty14(e, r, t) {
27347
27584
  return (r = _toPropertyKey14(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
@@ -27361,21 +27598,24 @@ function _toPrimitive14(t, r) {
27361
27598
  return ("string" === r ? String : Number)(t);
27362
27599
  }
27363
27600
  var LaserPointerModel = class extends ElementModel {
27364
- constructor(clientId, root, scope, liveCursor, removeElement) {
27365
- super(root, scope, liveCursor);
27601
+ constructor(clientId, root, scope, liveCursor, removeElement, isPerformanceMode) {
27602
+ super(root, scope, liveCursor, isPerformanceMode);
27366
27603
  _defineProperty14(this, "item", null);
27367
27604
  _defineProperty14(this, "clientId", void 0);
27368
27605
  _defineProperty14(this, "sliceBegin", 0);
27369
27606
  _defineProperty14(this, "displayStrokeWidth", 8);
27370
27607
  _defineProperty14(this, "cachedPoints", null);
27608
+ _defineProperty14(this, "clearLocalPointsWhenYPointsChange", false);
27609
+ _defineProperty14(this, "shouldUseLocalPoints", false);
27610
+ _defineProperty14(this, "localPointsPick", 4);
27371
27611
  this.clientId = clientId;
27372
- if (!this.root.has("type")) {
27612
+ if (this.root.doc && !this.root.has("type")) {
27373
27613
  this.root.set("type", "laser");
27374
27614
  }
27375
- if (!this.root.has("points")) {
27615
+ if (this.root.doc && !this.root.has("points")) {
27376
27616
  this.root.set("points", new Y10.Array());
27377
27617
  }
27378
- if (!this.root.has("removed")) {
27618
+ if (this.root.doc && !this.root.has("removed")) {
27379
27619
  this.root.set("removed", false);
27380
27620
  }
27381
27621
  this.root.observe((event) => {
@@ -27455,7 +27695,8 @@ var LaserPointerModel = class extends ElementModel {
27455
27695
  matrixedPoints() {
27456
27696
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27457
27697
  const points = this.cachedPoints || this.points;
27458
- const groupPoints = (0, import_lodash6.chunk)(points, 2).slice(this.sliceBegin);
27698
+ console.log("[][][] ,", this.points.length, this.cachedPoints?.length, this.localPoints.length);
27699
+ const groupPoints = (0, import_lodash5.chunk)(points, 2).slice(this.sliceBegin);
27459
27700
  return groupPoints.map((_ref) => {
27460
27701
  let [x, y] = _ref;
27461
27702
  return matrix.transform([x, y]);
@@ -27536,7 +27777,7 @@ var WhiteboardPermissions = class extends AbstractApplicationPermissions {
27536
27777
  };
27537
27778
 
27538
27779
  // src/model/renderable/StraightLineModel.ts
27539
- var import_lodash7 = __toESM(require_lodash(), 1);
27780
+ var import_lodash6 = __toESM(require_lodash(), 1);
27540
27781
  import * as Y11 from "yjs";
27541
27782
  function _defineProperty15(e, r, t) {
27542
27783
  return (r = _toPropertyKey15(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
@@ -27556,13 +27797,22 @@ function _toPrimitive15(t, r) {
27556
27797
  return ("string" === r ? String : Number)(t);
27557
27798
  }
27558
27799
  var StraightLineModel = class extends ElementModel {
27559
- constructor(root, scope, liveCursor) {
27560
- super(root, scope, liveCursor);
27800
+ get drawPoints() {
27801
+ if (this.localPoints.length >= 4) {
27802
+ return this.localPoints;
27803
+ }
27804
+ return this.points;
27805
+ }
27806
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27807
+ super(root, scope, liveCursor, isPerformanceMode);
27561
27808
  _defineProperty15(this, "item", null);
27562
- if (!this.root.has("type")) {
27809
+ _defineProperty15(this, "clearLocalPointsWhenYPointsChange", true);
27810
+ _defineProperty15(this, "shouldUseLocalPoints", true);
27811
+ _defineProperty15(this, "localPointsPick", 4);
27812
+ if (this.root.doc && !this.root.has("type")) {
27563
27813
  this.root.set("type", "line");
27564
27814
  }
27565
- if (!this.root.has("points")) {
27815
+ if (this.root.doc && !this.root.has("points")) {
27566
27816
  this.root.set("points", new Y11.Array());
27567
27817
  }
27568
27818
  }
@@ -27587,7 +27837,7 @@ var StraightLineModel = class extends ElementModel {
27587
27837
  }
27588
27838
  renderLine() {
27589
27839
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27590
- const papperPoints = (0, import_lodash7.chunk)(this.points, 2).map((item) => {
27840
+ const papperPoints = (0, import_lodash6.chunk)(this.drawPoints, 2).map((item) => {
27591
27841
  return new this.scope.Point(item[0], item[1]).transform(matrix);
27592
27842
  });
27593
27843
  const path = new this.scope.Path();
@@ -27609,7 +27859,7 @@ var StraightLineModel = class extends ElementModel {
27609
27859
  name: "line-start",
27610
27860
  getPosition: () => {
27611
27861
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27612
- const points = this.points;
27862
+ const points = this.drawPoints;
27613
27863
  const start = new this.scope.Point(points[0], points[1]);
27614
27864
  return this.scope.project.view.projectToView(start.transform(matrix));
27615
27865
  },
@@ -27619,14 +27869,15 @@ var StraightLineModel = class extends ElementModel {
27619
27869
  }
27620
27870
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27621
27871
  const trPoint = point.transform(pointsMatrix.inverted());
27622
- this.setPoints([trPoint.x, trPoint.y, this.points[2], this.points[3]]);
27872
+ const oldPoints = this.drawPoints;
27873
+ this.setPoints([trPoint.x, trPoint.y, oldPoints[2], oldPoints[3]]);
27623
27874
  }
27624
27875
  });
27625
27876
  cfg.controlPoints.push({
27626
27877
  name: "line-end",
27627
27878
  getPosition: () => {
27628
27879
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27629
- const points = this.points;
27880
+ const points = this.drawPoints;
27630
27881
  const end = new this.scope.Point(points[2], points[3]);
27631
27882
  return this.scope.project.view.projectToView(end.transform(matrix));
27632
27883
  },
@@ -27636,7 +27887,8 @@ var StraightLineModel = class extends ElementModel {
27636
27887
  }
27637
27888
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27638
27889
  const trPoint = point.transform(pointsMatrix.inverted());
27639
- this.setPoints([this.points[0], this.points[1], trPoint.x, trPoint.y]);
27890
+ const oldPoints = this.drawPoints;
27891
+ this.setPoints([oldPoints[0], oldPoints[1], trPoint.x, trPoint.y]);
27640
27892
  }
27641
27893
  });
27642
27894
  return cfg;
@@ -27682,10 +27934,13 @@ var ImageModel = class extends ElementModel {
27682
27934
  get src() {
27683
27935
  return this.root.get("src");
27684
27936
  }
27685
- constructor(root, scope, imageSets, liveCursor) {
27686
- super(root, scope, liveCursor);
27937
+ constructor(root, scope, imageSets, liveCursor, isPerformanceMode) {
27938
+ super(root, scope, liveCursor, isPerformanceMode);
27687
27939
  _defineProperty16(this, "item", null);
27688
27940
  _defineProperty16(this, "imageSets", void 0);
27941
+ _defineProperty16(this, "clearLocalPointsWhenYPointsChange", true);
27942
+ _defineProperty16(this, "shouldUseLocalPoints", true);
27943
+ _defineProperty16(this, "localPointsPick", 4);
27689
27944
  this.imageSets = imageSets;
27690
27945
  if (!this.root.has("type")) {
27691
27946
  this.root.set("type", "image");
@@ -27768,7 +28023,7 @@ var RenderableModel = class extends EventEmitter {
27768
28023
  get uuid() {
27769
28024
  return uuidv4().replace(/-/g, "");
27770
28025
  }
27771
- constructor(layerId, shadowEmitter, elements, scope, toolbarModel, userManager, imageSets, liveCursor, hasPermission) {
28026
+ constructor(options) {
27772
28027
  super();
27773
28028
  _defineProperty17(this, "scope", void 0);
27774
28029
  _defineProperty17(this, "toolbarModel", void 0);
@@ -27781,6 +28036,7 @@ var RenderableModel = class extends EventEmitter {
27781
28036
  _defineProperty17(this, "shadowEmitter", void 0);
27782
28037
  _defineProperty17(this, "imageSets", void 0);
27783
28038
  _defineProperty17(this, "liveCursor", void 0);
28039
+ _defineProperty17(this, "isPerformanceMode", void 0);
27784
28040
  _defineProperty17(this, "onElementsChange", (event) => {
27785
28041
  for (const [key, value] of event.changes.keys.entries()) {
27786
28042
  if (value.action === "add") {
@@ -27799,15 +28055,16 @@ var RenderableModel = class extends EventEmitter {
27799
28055
  }
27800
28056
  }
27801
28057
  });
27802
- this.liveCursor = liveCursor;
27803
- this.imageSets = imageSets;
27804
- this.hasPermission = hasPermission;
27805
- this.shadowEmitter = shadowEmitter;
27806
- this.layerId = layerId;
27807
- this.userManager = userManager;
27808
- this.elements = elements;
27809
- this.scope = scope;
27810
- this.toolbarModel = toolbarModel;
28058
+ this.isPerformanceMode = options.isPerformanceMode;
28059
+ this.liveCursor = options.liveCursor;
28060
+ this.imageSets = options.imageSets;
28061
+ this.hasPermission = options.hasPermission;
28062
+ this.shadowEmitter = options.shadowEmitter;
28063
+ this.layerId = options.layerId;
28064
+ this.userManager = options.userManager;
28065
+ this.elements = options.elements;
28066
+ this.scope = options.scope;
28067
+ this.toolbarModel = options.toolbarModel;
27811
28068
  this.elementModels = /* @__PURE__ */ new Map();
27812
28069
  for (const key of this.elements.keys()) {
27813
28070
  const type = this.elements.get(key)?.get("type");
@@ -27838,30 +28095,38 @@ var RenderableModel = class extends EventEmitter {
27838
28095
  convertToModel(yMap) {
27839
28096
  const type = yMap.get("type");
27840
28097
  let model = null;
28098
+ const uuid = yMap.get(ElementModel.KEYS.uuid);
28099
+ if (uuid) {
28100
+ const existingModel = this.elementModels.get(uuid);
28101
+ if (existingModel) {
28102
+ existingModel.shadowEmitter = this.shadowEmitter;
28103
+ return existingModel;
28104
+ }
28105
+ }
27841
28106
  if (type === "curve") {
27842
- model = new CurveModel(yMap, this.scope, this.liveCursor);
28107
+ model = new CurveModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27843
28108
  } else if (["ellipse"].indexOf(type) >= 0) {
27844
- model = new SegmentsModel(yMap, this.scope, type, this.liveCursor);
28109
+ model = new SegmentsModel(yMap, this.scope, type, this.liveCursor, this.isPerformanceMode);
27845
28110
  } else if (type === "selector") {
27846
- model = new SelectorModel(yMap, this.scope, this.liveCursor);
28111
+ model = new SelectorModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27847
28112
  } else if (type === "arrow") {
27848
- model = new LineModel(yMap, this.scope, this.liveCursor);
28113
+ model = new LineModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27849
28114
  } else if (type === "line") {
27850
- model = new StraightLineModel(yMap, this.scope, this.liveCursor);
28115
+ model = new StraightLineModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27851
28116
  } else if (type === "point-text") {
27852
- model = new PointTextModel(yMap, this.scope, this.liveCursor);
28117
+ model = new PointTextModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27853
28118
  } else if (type === "triangle") {
27854
- model = new TriangleModel(yMap, this.scope, this.liveCursor);
28119
+ model = new TriangleModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27855
28120
  } else if (type === "rectangle") {
27856
- model = new RectangleModel(yMap, this.scope, this.liveCursor);
28121
+ model = new RectangleModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27857
28122
  } else if (type === "eraser") {
27858
- model = new EraserModel(yMap, this.scope, this.liveCursor);
28123
+ model = new EraserModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27859
28124
  } else if (type === "laser") {
27860
- model = new LaserPointerModel(this.userManager.selfId, yMap, this.scope, this.liveCursor, (uuid) => {
27861
- this.removeElementItem(uuid);
27862
- });
28125
+ model = new LaserPointerModel(this.userManager.selfId, yMap, this.scope, this.liveCursor, (uuid2) => {
28126
+ this.removeElementItem(uuid2);
28127
+ }, this.isPerformanceMode);
27863
28128
  } else if (type === "image") {
27864
- model = new ImageModel(yMap, this.scope, this.imageSets, this.liveCursor);
28129
+ model = new ImageModel(yMap, this.scope, this.imageSets, this.liveCursor, this.isPerformanceMode);
27865
28130
  }
27866
28131
  if (model) {
27867
28132
  model.shadowEmitter = this.shadowEmitter;
@@ -27895,7 +28160,7 @@ var RenderableModel = class extends EventEmitter {
27895
28160
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27896
28161
  this.elements.set(uuid, yMap);
27897
28162
  }, elementsUndoOrigin);
27898
- const model = new ImageModel(yMap, this.scope, this.imageSets, this.liveCursor);
28163
+ const model = new ImageModel(yMap, this.scope, this.imageSets, this.liveCursor, this.isPerformanceMode);
27899
28164
  model.root.set("src", src);
27900
28165
  const initMatrix = new this.scope.Matrix();
27901
28166
  const center = this.scope.project.view.center;
@@ -27912,8 +28177,10 @@ var RenderableModel = class extends EventEmitter {
27912
28177
  return null;
27913
28178
  }
27914
28179
  const yMap = new Y12.Map();
28180
+ const uuid = this.uuid;
28181
+ const curveModel = new CurveModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28182
+ this.elementModels.set(uuid, curveModel);
27915
28183
  this.elements.doc?.transact(() => {
27916
- const uuid = this.uuid;
27917
28184
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
27918
28185
  yMap.set(ElementModel.KEYS.uuid, uuid);
27919
28186
  yMap.set("type", "curve");
@@ -27926,7 +28193,6 @@ var RenderableModel = class extends EventEmitter {
27926
28193
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27927
28194
  this.elements.set(uuid, yMap);
27928
28195
  }, elementsUndoOrigin);
27929
- const curveModel = new CurveModel(yMap, this.scope, this.liveCursor);
27930
28196
  this.initElement(curveModel);
27931
28197
  return curveModel;
27932
28198
  }
@@ -27935,11 +28201,17 @@ var RenderableModel = class extends EventEmitter {
27935
28201
  return null;
27936
28202
  }
27937
28203
  const yMap = new Y12.Map();
28204
+ const uuid = this.uuid;
28205
+ const model = new LaserPointerModel(this.userManager.selfId, yMap, this.scope, this.liveCursor, (uuid2) => {
28206
+ this.removeElementItem(uuid2);
28207
+ }, this.isPerformanceMode);
28208
+ this.elementModels.set(uuid, model);
27938
28209
  this.elements.doc?.transact(() => {
27939
- const uuid = this.uuid;
27940
28210
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
27941
28211
  yMap.set(ElementModel.KEYS.uuid, uuid);
27942
28212
  yMap.set("type", "laser");
28213
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
28214
+ yMap.set("removed", false);
27943
28215
  yMap.set(ElementModel.KEYS.shadow, "layer");
27944
28216
  yMap.set(ElementModel.KEYS.strokeWidth, 8);
27945
28217
  yMap.set(ElementModel.KEYS.strokeColor, "#F44336");
@@ -27947,9 +28219,7 @@ var RenderableModel = class extends EventEmitter {
27947
28219
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27948
28220
  this.elements.set(uuid, yMap);
27949
28221
  }, elementsUndoOrigin);
27950
- const model = new LaserPointerModel(this.userManager.selfId, yMap, this.scope, this.liveCursor, (uuid) => {
27951
- this.removeElementItem(uuid);
27952
- });
28222
+ this.initElement(model);
27953
28223
  return model;
27954
28224
  }
27955
28225
  createEraser() {
@@ -27957,11 +28227,14 @@ var RenderableModel = class extends EventEmitter {
27957
28227
  return null;
27958
28228
  }
27959
28229
  const yMap = new Y12.Map();
28230
+ const uuid = this.uuid;
28231
+ const model = new EraserModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28232
+ this.elementModels.set(uuid, model);
27960
28233
  this.elements.doc?.transact(() => {
27961
- const uuid = this.uuid;
27962
28234
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
27963
28235
  yMap.set(ElementModel.KEYS.uuid, uuid);
27964
28236
  yMap.set("type", "eraser");
28237
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
27965
28238
  yMap.set(ElementModel.KEYS.shadow, "layer");
27966
28239
  yMap.set(ElementModel.KEYS.strokeWidth, 4);
27967
28240
  yMap.set(ElementModel.KEYS.strokeColor, "#9E9E9E");
@@ -27969,7 +28242,6 @@ var RenderableModel = class extends EventEmitter {
27969
28242
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27970
28243
  this.elements.set(uuid, yMap);
27971
28244
  }, elementsUndoOrigin);
27972
- const model = new EraserModel(yMap, this.scope, this.liveCursor);
27973
28245
  return model;
27974
28246
  }
27975
28247
  createTriangle(shadow) {
@@ -27977,45 +28249,52 @@ var RenderableModel = class extends EventEmitter {
27977
28249
  return null;
27978
28250
  }
27979
28251
  const yMap = new Y12.Map();
28252
+ const uuid = this.uuid;
28253
+ const triangleModel = new TriangleModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28254
+ this.elementModels.set(uuid, triangleModel);
27980
28255
  this.elements.doc?.transact(() => {
27981
- const uuid = this.uuid;
27982
28256
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
27983
28257
  yMap.set(ElementModel.KEYS.uuid, uuid);
27984
28258
  yMap.set("type", "triangle");
27985
28259
  if (shadow) {
27986
28260
  yMap.set(ElementModel.KEYS.shadow, "layer");
27987
28261
  }
28262
+ yMap.set("points", new Y12.Array());
27988
28263
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
27989
28264
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
27990
28265
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
27991
28266
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27992
28267
  this.elements.set(uuid, yMap);
27993
28268
  }, elementsUndoOrigin);
27994
- const triangle = new TriangleModel(yMap, this.scope, this.liveCursor);
27995
- this.initElement(triangle);
27996
- triangle.dashArray = this.toolbarModel.dashArray;
27997
- return triangle;
28269
+ this.initElement(triangleModel);
28270
+ triangleModel.dashArray = this.toolbarModel.dashArray;
28271
+ return triangleModel;
27998
28272
  }
27999
28273
  createRectangle(shadow) {
28000
28274
  if (!this.confirmPermission()) {
28001
28275
  return null;
28002
28276
  }
28003
28277
  const yMap = new Y12.Map();
28278
+ const uuid = this.uuid;
28279
+ const rect = new RectangleModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28280
+ this.elementModels.set(uuid, rect);
28004
28281
  this.elements.doc?.transact(() => {
28005
- const uuid = this.uuid;
28006
28282
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28007
28283
  yMap.set(ElementModel.KEYS.uuid, uuid);
28008
28284
  yMap.set("type", "rectangle");
28009
28285
  if (shadow) {
28010
28286
  yMap.set(ElementModel.KEYS.shadow, "layer");
28011
28287
  }
28288
+ const initPoints = new Y12.Array();
28289
+ initPoints.push([0, 0, 0, 0]);
28290
+ yMap.set("points", initPoints);
28291
+ yMap.set("radius", 0);
28012
28292
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28013
28293
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28014
28294
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28015
28295
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28016
28296
  this.elements.set(uuid, yMap);
28017
28297
  }, elementsUndoOrigin);
28018
- const rect = new RectangleModel(yMap, this.scope, this.liveCursor);
28019
28298
  this.initElement(rect);
28020
28299
  rect.dashArray = this.toolbarModel.dashArray;
28021
28300
  return rect;
@@ -28025,21 +28304,23 @@ var RenderableModel = class extends EventEmitter {
28025
28304
  return null;
28026
28305
  }
28027
28306
  const yMap = new Y12.Map();
28307
+ const uuid = this.uuid;
28308
+ const segmentsModel = new SegmentsModel(yMap, this.scope, type, this.liveCursor, this.isPerformanceMode);
28309
+ this.elementModels.set(uuid, segmentsModel);
28028
28310
  this.elements.doc?.transact(() => {
28029
- const uuid = this.uuid;
28030
28311
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28031
28312
  yMap.set(ElementModel.KEYS.uuid, uuid);
28032
28313
  yMap.set("type", type);
28033
28314
  if (shadow) {
28034
28315
  yMap.set(ElementModel.KEYS.shadow, "layer");
28035
28316
  }
28317
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
28036
28318
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28037
28319
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28038
28320
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28039
28321
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28040
28322
  this.elements.set(uuid, yMap);
28041
28323
  }, elementsUndoOrigin);
28042
- const segmentsModel = new SegmentsModel(yMap, this.scope, type, this.liveCursor);
28043
28324
  this.initElement(segmentsModel);
28044
28325
  segmentsModel.dashArray = this.toolbarModel.dashArray;
28045
28326
  return segmentsModel;
@@ -28050,16 +28331,20 @@ var RenderableModel = class extends EventEmitter {
28050
28331
  return null;
28051
28332
  }
28052
28333
  const yMap = new Y12.Map();
28334
+ const uuid = this.uuid;
28335
+ const selectorModel = new SelectorModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28336
+ this.elementModels.set(uuid, selectorModel);
28053
28337
  this.elements.doc?.transact(() => {
28054
- const uuid = this.uuid;
28055
28338
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28056
28339
  yMap.set(ElementModel.KEYS.uuid, uuid);
28057
28340
  yMap.set("type", "selector");
28341
+ const initPoints = new Y12.Array();
28342
+ initPoints.push([0, 0, 0, 0]);
28343
+ yMap.set(ElementModel.KEYS.points, initPoints);
28058
28344
  yMap.set(ElementModel.KEYS.shadow, "layer");
28059
28345
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28060
28346
  this.elements.set(uuid, yMap);
28061
28347
  }, elementsUndoOrigin);
28062
- const selectorModel = new SelectorModel(yMap, this.scope, this.liveCursor);
28063
28348
  selectorModel.shadow = "layer";
28064
28349
  return selectorModel;
28065
28350
  }
@@ -28068,21 +28353,23 @@ var RenderableModel = class extends EventEmitter {
28068
28353
  return null;
28069
28354
  }
28070
28355
  const yMap = new Y12.Map();
28356
+ const uuid = this.uuid;
28357
+ const straightLineModel = new StraightLineModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28358
+ this.elementModels.set(uuid, straightLineModel);
28071
28359
  this.elements.doc?.transact(() => {
28072
- const uuid = this.uuid;
28073
28360
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28074
28361
  yMap.set(ElementModel.KEYS.uuid, uuid);
28075
28362
  yMap.set("type", "line");
28076
28363
  if (shadow) {
28077
28364
  yMap.set(ElementModel.KEYS.shadow, "layer");
28078
28365
  }
28366
+ yMap.set("points", new Y12.Array());
28079
28367
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28080
28368
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28081
28369
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28082
28370
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28083
28371
  this.elements.set(uuid, yMap);
28084
28372
  }, elementsUndoOrigin);
28085
- const straightLineModel = new StraightLineModel(yMap, this.scope, this.liveCursor);
28086
28373
  this.initElement(straightLineModel);
28087
28374
  straightLineModel.dashArray = this.toolbarModel.dashArray;
28088
28375
  return straightLineModel;
@@ -28092,21 +28379,25 @@ var RenderableModel = class extends EventEmitter {
28092
28379
  return null;
28093
28380
  }
28094
28381
  const yMap = new Y12.Map();
28382
+ const uuid = this.uuid;
28383
+ const lineModel = new LineModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28384
+ this.elementModels.set(uuid, lineModel);
28095
28385
  this.elements.doc?.transact(() => {
28096
- const uuid = this.uuid;
28097
28386
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28098
28387
  yMap.set(ElementModel.KEYS.uuid, uuid);
28099
28388
  yMap.set("type", "arrow");
28100
28389
  if (shadow) {
28101
28390
  yMap.set(ElementModel.KEYS.shadow, "layer");
28102
28391
  }
28392
+ yMap.set("headArrow", "none");
28393
+ yMap.set("tailArrow", "normal");
28394
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
28103
28395
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28104
28396
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28105
28397
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28106
28398
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28107
28399
  this.elements.set(uuid, yMap);
28108
28400
  }, elementsUndoOrigin);
28109
- const lineModel = new LineModel(yMap, this.scope, this.liveCursor);
28110
28401
  this.initElement(lineModel);
28111
28402
  lineModel.dashArray = this.toolbarModel.dashArray;
28112
28403
  return lineModel;
@@ -28116,21 +28407,23 @@ var RenderableModel = class extends EventEmitter {
28116
28407
  return null;
28117
28408
  }
28118
28409
  const yMap = new Y12.Map();
28410
+ const uuid = this.uuid;
28411
+ const pointTextModel = new PointTextModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28412
+ this.elementModels.set(uuid, pointTextModel);
28119
28413
  this.elements.doc?.transact(() => {
28120
- const uuid = this.uuid;
28121
28414
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28122
28415
  yMap.set(ElementModel.KEYS.uuid, uuid);
28123
28416
  yMap.set("type", "point-text");
28124
28417
  if (shadow) {
28125
28418
  yMap.set(ElementModel.KEYS.shadow, "layer");
28126
28419
  }
28420
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
28127
28421
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28128
28422
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28129
28423
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28130
28424
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28131
28425
  this.elements.set(uuid, yMap);
28132
28426
  }, elementsUndoOrigin);
28133
- const pointTextModel = new PointTextModel(yMap, this.scope, this.liveCursor);
28134
28427
  pointTextModel.setPoints([x, y]);
28135
28428
  pointTextModel.fontSize = this.toolbarModel.fontSize;
28136
28429
  pointTextModel.fontFamily = this.toolbarModel.fontFamily;
@@ -28164,7 +28457,7 @@ var RenderableModel = class extends EventEmitter {
28164
28457
  };
28165
28458
 
28166
28459
  // src/utils/Recognizer.ts
28167
- var import_lodash8 = __toESM(require_lodash(), 1);
28460
+ var import_lodash7 = __toESM(require_lodash(), 1);
28168
28461
 
28169
28462
  // src/utils/UnistrokeRecognizer.js
28170
28463
  function Point(x, y) {
@@ -28411,7 +28704,7 @@ var Recognizer = class {
28411
28704
  let maxX = -Number.MAX_VALUE;
28412
28705
  let minY = Number.MAX_VALUE;
28413
28706
  let maxY = -Number.MAX_VALUE;
28414
- const result = this.dollar.Recognize((0, import_lodash8.chunk)(points, 2).map((v) => {
28707
+ const result = this.dollar.Recognize((0, import_lodash7.chunk)(points, 3).map((v) => {
28415
28708
  minX = Math.min(minX, v[0]);
28416
28709
  maxX = Math.max(maxX, v[0]);
28417
28710
  minY = Math.min(minY, v[1]);
@@ -28455,11 +28748,24 @@ var CurveTool = class extends WhiteboardTool {
28455
28748
  _defineProperty19(this, "elementModel", null);
28456
28749
  _defineProperty19(this, "recognizer", new Recognizer());
28457
28750
  _defineProperty19(this, "pointCount", 0);
28751
+ _defineProperty19(this, "pendingPoints", []);
28752
+ _defineProperty19(this, "flushRafId", 0);
28458
28753
  _defineProperty19(this, "showLiveCursor", true);
28459
- this.tool.minDistance = 5;
28754
+ _defineProperty19(this, "flushPendingPoints", () => {
28755
+ this.flushRafId = 0;
28756
+ if (this.elementModel && this.pendingPoints.length > 0) {
28757
+ this.elementModel.appendPoints(this.pendingPoints);
28758
+ this.pendingPoints = [];
28759
+ }
28760
+ });
28460
28761
  }
28461
28762
  onMouseDown(_event) {
28462
28763
  this.pointCount = 0;
28764
+ this.pendingPoints = [];
28765
+ if (this.flushRafId) {
28766
+ cancelAnimationFrame(this.flushRafId);
28767
+ this.flushRafId = 0;
28768
+ }
28463
28769
  if (this.elementModel) {
28464
28770
  this.elementModel.dispose();
28465
28771
  }
@@ -28474,27 +28780,38 @@ var CurveTool = class extends WhiteboardTool {
28474
28780
  if (this.pointCount > 1024) {
28475
28781
  return;
28476
28782
  }
28477
- const MIN_DISTANCE = 4;
28783
+ const MIN_DISTANCE = 2;
28478
28784
  if (this.elementModel) {
28479
- const len = this.elementModel.points.length;
28480
- let last = {
28481
- x: 0,
28482
- y: 0
28483
- };
28484
- if (len >= 2) {
28485
- last = {
28486
- x: this.elementModel.points[len - 2],
28487
- y: this.elementModel.points[len - 1]
28488
- };
28785
+ let lastX = 0;
28786
+ let lastY = 0;
28787
+ if (this.pendingPoints.length >= 3) {
28788
+ lastX = this.pendingPoints[this.pendingPoints.length - 3];
28789
+ lastY = this.pendingPoints[this.pendingPoints.length - 2];
28790
+ } else {
28791
+ const len = this.elementModel.points.length;
28792
+ if (len >= 3) {
28793
+ lastX = this.elementModel.points[len - 3];
28794
+ lastY = this.elementModel.points[len - 2];
28795
+ }
28489
28796
  }
28490
- const dist = Math.max(Math.abs(last.x - event.point.x), Math.abs(last.y - event.point.y));
28797
+ const dist = Math.max(Math.abs(lastX - event.point.x), Math.abs(lastY - event.point.y));
28491
28798
  if (dist >= MIN_DISTANCE) {
28492
28799
  this.pointCount += 1;
28493
- this.elementModel.appendPoints([Math.round(event.point.x), Math.round(event.point.y)]);
28800
+ const nativeEvent = event.event;
28801
+ const pressure = nativeEvent.pointerType === "pen" && nativeEvent.pressure > 0 ? nativeEvent.pressure : 0;
28802
+ this.pendingPoints.push(event.point.x, event.point.y, pressure);
28803
+ if (!this.flushRafId) {
28804
+ this.flushRafId = requestAnimationFrame(this.flushPendingPoints);
28805
+ }
28494
28806
  }
28495
28807
  }
28496
28808
  }
28497
28809
  onMouseUp(event) {
28810
+ if (this.flushRafId) {
28811
+ cancelAnimationFrame(this.flushRafId);
28812
+ this.flushRafId = 0;
28813
+ }
28814
+ this.flushPendingPoints();
28498
28815
  this.modelGetter().then((model) => {
28499
28816
  if (!model) {
28500
28817
  return;
@@ -30419,6 +30736,8 @@ var Whiteboard = class extends EventEmitter8 {
30419
30736
  _defineProperty31(this, "enableCameraBoundaryHighlight", void 0);
30420
30737
  _defineProperty31(this, "getElementAttribute", void 0);
30421
30738
  _defineProperty31(this, "setElementAttribute", void 0);
30739
+ _defineProperty31(this, "setPerformanceMode", void 0);
30740
+ _defineProperty31(this, "isPerformanceMode", void 0);
30422
30741
  _defineProperty31(this, "removeElement", void 0);
30423
30742
  _defineProperty31(this, "getCurrentTool", void 0);
30424
30743
  _defineProperty31(this, "setCurrentTool", void 0);
@@ -30717,9 +31036,24 @@ var LaserPointerTool = class extends WhiteboardTool {
30717
31036
  if (this.pointCount > 1024) {
30718
31037
  return;
30719
31038
  }
31039
+ const MIN_DISTANCE = 4;
30720
31040
  if (this.elementModel) {
30721
- this.pointCount += 1;
30722
- this.elementModel.appendPoints([event.point.x, event.point.y]);
31041
+ const len = this.elementModel.points.length;
31042
+ let last = {
31043
+ x: 0,
31044
+ y: 0
31045
+ };
31046
+ if (len >= 2) {
31047
+ last = {
31048
+ x: this.elementModel.points[len - 2],
31049
+ y: this.elementModel.points[len - 1]
31050
+ };
31051
+ }
31052
+ const dist = Math.max(Math.abs(last.x - event.point.x), Math.abs(last.y - event.point.y));
31053
+ if (dist >= MIN_DISTANCE) {
31054
+ this.pointCount += 1;
31055
+ this.elementModel.appendPoints([Math.round(event.point.x), Math.round(event.point.y)]);
31056
+ }
30723
31057
  }
30724
31058
  }
30725
31059
  onMouseUp(_event) {
@@ -31707,6 +32041,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends AbstractApplica
31707
32041
  _defineProperty43(this, "permissions", void 0);
31708
32042
  _defineProperty43(this, "inputType", "any");
31709
32043
  _defineProperty43(this, "isPenEvent", false);
32044
+ _defineProperty43(this, "activePenPointerId", null);
31710
32045
  _defineProperty43(this, "hasPenInput", null);
31711
32046
  _defineProperty43(this, "disableViewModelUpdate", false);
31712
32047
  _defineProperty43(this, "internalResizeObserver", true);
@@ -31823,6 +32158,9 @@ var WhiteboardApplication = class _WhiteboardApplication extends AbstractApplica
31823
32158
  _defineProperty43(this, "hasPermission", (flag) => {
31824
32159
  return this.permissions.hasPermission(flag, this.userId);
31825
32160
  });
32161
+ _defineProperty43(this, "isPerformanceMode", () => {
32162
+ return this.option.performance ?? false;
32163
+ });
31826
32164
  _defineProperty43(this, "handleStackItemAdded", () => {
31827
32165
  this.selectElementsModel.clearSelectElementForSelf();
31828
32166
  this.emitter.emit("redoStackLength", this.undoManager?.redoStack.length ?? 0);
@@ -31837,7 +32175,18 @@ var WhiteboardApplication = class _WhiteboardApplication extends AbstractApplica
31837
32175
  const id = ids[i];
31838
32176
  if (!this.layers.has(id)) {
31839
32177
  const elementsMap = this.getMap(`layer/${id}/elements`);
31840
- const renderableModel = new RenderableModel(id, this.shadowEmitter, elementsMap, this.paperScope, this.toolbarModel, this.userManager, this.imageSets, this.liveCursor, this.hasPermission);
32178
+ const renderableModel = new RenderableModel({
32179
+ layerId: id,
32180
+ shadowEmitter: this.shadowEmitter,
32181
+ elements: elementsMap,
32182
+ scope: this.paperScope,
32183
+ toolbarModel: this.toolbarModel,
32184
+ userManager: this.userManager,
32185
+ imageSets: this.imageSets,
32186
+ liveCursor: this.liveCursor,
32187
+ hasPermission: this.hasPermission,
32188
+ isPerformanceMode: this.isPerformanceMode
32189
+ });
31841
32190
  this.layers.set(id, renderableModel);
31842
32191
  }
31843
32192
  if (!this.undoManagers.has(id)) {
@@ -32021,11 +32370,34 @@ var WhiteboardApplication = class _WhiteboardApplication extends AbstractApplica
32021
32370
  this.imageSets.setAttribute("data-image-sets", "");
32022
32371
  this.rootElement.appendChild(this.imageSets);
32023
32372
  document.body.addEventListener("pointerdown", (evt) => {
32024
- this.isPenEvent = evt.pointerType === "pen";
32025
- if (evt.pointerType === "pen" && this.hasPenInput === null) {
32026
- this.hasPenInput = true;
32027
- this.inputType = "pen";
32028
- this.emitter.emit("inputTypeChange", this.inputType);
32373
+ if (evt.pointerType === "pen") {
32374
+ this.isPenEvent = true;
32375
+ this.activePenPointerId = evt.pointerId;
32376
+ if (this.hasPenInput === null) {
32377
+ this.hasPenInput = true;
32378
+ this.inputType = "pen";
32379
+ this.emitter.emit("inputTypeChange", this.inputType);
32380
+ }
32381
+ } else {
32382
+ if (this.activePenPointerId === null) {
32383
+ this.isPenEvent = false;
32384
+ }
32385
+ }
32386
+ }, {
32387
+ capture: true
32388
+ });
32389
+ document.body.addEventListener("pointerup", (evt) => {
32390
+ if (evt.pointerId === this.activePenPointerId) {
32391
+ this.activePenPointerId = null;
32392
+ this.isPenEvent = false;
32393
+ }
32394
+ }, {
32395
+ capture: true
32396
+ });
32397
+ document.body.addEventListener("pointercancel", (evt) => {
32398
+ if (evt.pointerId === this.activePenPointerId) {
32399
+ this.activePenPointerId = null;
32400
+ this.isPenEvent = false;
32029
32401
  }
32030
32402
  }, {
32031
32403
  capture: true
@@ -32104,6 +32476,12 @@ var WhiteboardApplication = class _WhiteboardApplication extends AbstractApplica
32104
32476
  this.camera.resetViewMatrixToFlow(flowId);
32105
32477
  }
32106
32478
  };
32479
+ this.emitter.setPerformanceMode = (enabled) => {
32480
+ this.option.performance = enabled;
32481
+ };
32482
+ this.emitter.isPerformanceMode = () => {
32483
+ return this.isPerformanceMode();
32484
+ };
32107
32485
  this.emitter.setViewModeToMain = (userId) => {
32108
32486
  if (that.disableViewModelUpdate) {
32109
32487
  console.warn("Operation failed. Perspective mode switching is disabled in the current environment.");
@@ -32158,7 +32536,18 @@ var WhiteboardApplication = class _WhiteboardApplication extends AbstractApplica
32158
32536
  const source = this.getMap(`layer/${sourceId}/elements`);
32159
32537
  const target = this.getMap(`layer/${targetId}/elements`);
32160
32538
  if (!this.layers.has(targetId)) {
32161
- this.layers.set(targetId, new RenderableModel(targetId, this.shadowEmitter, target, this.paperScope, this.toolbarModel, this.userManager, this.imageSets, this.liveCursor, this.hasPermission));
32539
+ this.layers.set(targetId, new RenderableModel({
32540
+ layerId: targetId,
32541
+ shadowEmitter: this.shadowEmitter,
32542
+ elements: target,
32543
+ scope: this.paperScope,
32544
+ toolbarModel: this.toolbarModel,
32545
+ userManager: this.userManager,
32546
+ imageSets: this.imageSets,
32547
+ liveCursor: this.liveCursor,
32548
+ hasPermission: this.hasPermission,
32549
+ isPerformanceMode: this.isPerformanceMode
32550
+ }));
32162
32551
  }
32163
32552
  if (!this.undoManagers.has(targetId)) {
32164
32553
  const undoManager = new Y15.UndoManager(target, {
@@ -32393,6 +32782,11 @@ var WhiteboardApplication = class _WhiteboardApplication extends AbstractApplica
32393
32782
  this.editors.forEach((editor) => {
32394
32783
  editor.updateBounds();
32395
32784
  });
32785
+ const area = this.paperScope.project.view.size.width * this.paperScope.project.view.size.height;
32786
+ const minDistance = Math.ceil(area / 4e5);
32787
+ Object.keys(this.tools).forEach((key) => {
32788
+ this.tools[key].tool.minDistance = minDistance;
32789
+ });
32396
32790
  });
32397
32791
  this.camera.on("userPageChange", (userId, pageId) => {
32398
32792
  this.emitter.emit("activePageChange", userId, pageId);