mce 0.15.33 → 0.15.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Node as Node$1, Element2D, Timeline, Engine, Camera2D, DrawboardEffect, Aabb2D, IN_BROWSER, clamp, assets, TimelineNode, Video2D, Transform2D, Obb2D, render, Vector2 as Vector2$1, Lottie2D, customNodes, Animation, IN_MAC_OS } from "modern-canvas";
2
- import { reactive, computed, watch, markRaw, isReactive, ref, warn, shallowRef, defineComponent, createElementBlock, createCommentVNode, unref, openBlock, normalizeStyle as normalizeStyle$1, toDisplayString, onBeforeUnmount, createVNode, useAttrs, createBlock, resolveDynamicComponent, normalizeClass, mergeProps, createElementVNode, inject, toValue, getCurrentInstance, provide, useId, readonly, toRef, onMounted, onDeactivated, onActivated, onScopeDispose, useModel, useTemplateRef, withDirectives, withModifiers, vModelText, vShow, nextTick, Fragment, renderList, renderSlot, mergeModels, resolveComponent, withCtx, Teleport, createTextVNode, createSlots, normalizeProps, guardReactiveProps, onBeforeMount, h, isRef, useSlots } from "vue";
2
+ import { reactive, computed, watch, markRaw, isReactive, ref, onBeforeMount, onScopeDispose, warn, shallowRef, defineComponent, createElementBlock, createCommentVNode, unref, openBlock, normalizeStyle as normalizeStyle$1, toDisplayString, onMounted, createVNode, useAttrs, createBlock, resolveDynamicComponent, normalizeClass, mergeProps, createElementVNode, inject, toValue, getCurrentInstance, provide, useId, onBeforeUnmount, readonly, toRef, onDeactivated, onActivated, useModel, useTemplateRef, withDirectives, withModifiers, vModelText, vShow, nextTick, Fragment, renderList, renderSlot, mergeModels, resolveComponent, withCtx, Teleport, createTextVNode, createSlots, normalizeProps, guardReactiveProps, h, isRef, effectScope, useSlots } from "vue";
3
3
  import { useFileDialog, useEventListener, isClient, onClickOutside, useDebounceFn, useResizeObserver as useResizeObserver$1, useLocalStorage, useImage } from "@vueuse/core";
4
4
  import { getObjectValueByPath, setObjectValueByPath, Observable, Reactivable, idGenerator, property, normalizeTextContent, isCRLF, textContentToString, normalizeCRLF, isEqualObject } from "modern-idoc";
5
5
  import { saveAs } from "file-saver";
@@ -885,7 +885,6 @@ const _0_context = defineMixin((editor) => {
885
885
  _renderEngine.root.append(camera.value);
886
886
  _renderEngine.root.append(drawboardEffect.value);
887
887
  const renderEngine = ref(_renderEngine);
888
- renderEngine.value.start();
889
888
  const drawboardDom = ref();
890
889
  const drawboardAabb = ref(new Aabb2D());
891
890
  const drawboardPointer = ref();
@@ -998,6 +997,7 @@ const _0_context = defineMixin((editor) => {
998
997
  return () => {
999
998
  const {
1000
999
  on,
1000
+ off,
1001
1001
  root: root2,
1002
1002
  state: state2
1003
1003
  } = editor;
@@ -1016,7 +1016,9 @@ const _0_context = defineMixin((editor) => {
1016
1016
  nodes.value.push(node);
1017
1017
  nodeIndexMap.set(node.id, nodes.value.length - 1);
1018
1018
  }
1019
- on("setDoc", () => updateNodes());
1019
+ function onSetDoc() {
1020
+ updateNodes();
1021
+ }
1020
1022
  watch(selection, (value) => {
1021
1023
  window.$$0 = value[0];
1022
1024
  });
@@ -1024,6 +1026,14 @@ const _0_context = defineMixin((editor) => {
1024
1026
  textSelection.value = void 0;
1025
1027
  hoverElement.value = void 0;
1026
1028
  });
1029
+ onBeforeMount(() => {
1030
+ on("setDoc", onSetDoc);
1031
+ renderEngine.value.start();
1032
+ });
1033
+ onScopeDispose(() => {
1034
+ off("setDoc", onSetDoc);
1035
+ renderEngine.value.stop();
1036
+ });
1027
1037
  };
1028
1038
  });
1029
1039
  const _0_font = defineMixin((editor, options) => {
@@ -1077,7 +1087,7 @@ const en = {
1077
1087
  "selectObject": "Select object",
1078
1088
  "commitChanges": "Commit changes",
1079
1089
  "extend": "Extend",
1080
- "goBackSelectedArea": "Go back selected area",
1090
+ "scrollToSelection": "Scroll to selection",
1081
1091
  "selectArea": "Select area",
1082
1092
  "dragSelected": "Drag selected",
1083
1093
  "startTyping": "Start typing",
@@ -1193,7 +1203,7 @@ const zhHans = {
1193
1203
  "selectObject": "选择对象",
1194
1204
  "commitChanges": "提交修改",
1195
1205
  "extend": "扩展",
1196
- "goBackSelectedArea": "返回选中区域",
1206
+ "scrollToSelection": "返回选中区域",
1197
1207
  "selectArea": "选择区域",
1198
1208
  "dragSelected": "拖拽选择的",
1199
1209
  "startTyping": "编辑文字",
@@ -1939,14 +1949,21 @@ const _1_timeline = defineMixin((editor) => {
1939
1949
  });
1940
1950
  return () => {
1941
1951
  const {
1942
- on
1952
+ on,
1953
+ off
1943
1954
  } = editor;
1944
1955
  async function updateEndTime() {
1945
1956
  await renderEngine.value.nextTick();
1946
1957
  timeline.value.endTime = root.value ? getTimeRange(root.value).endTime : 0;
1947
1958
  }
1948
- assets.on("loaded", updateEndTime);
1949
- on("setDoc", updateEndTime);
1959
+ onBeforeMount(() => {
1960
+ on("setDoc", updateEndTime);
1961
+ assets.on("loaded", updateEndTime);
1962
+ });
1963
+ onScopeDispose(() => {
1964
+ off("setDoc", updateEndTime);
1965
+ assets.off("loaded", updateEndTime);
1966
+ });
1950
1967
  };
1951
1968
  });
1952
1969
  const _1_upload = defineMixin((editor, options) => {
@@ -2047,14 +2064,7 @@ const _2_box = defineMixin((editor) => {
2047
2064
  obb = new Obb2D();
2048
2065
  }
2049
2066
  if (inTarget === "drawboard") {
2050
- const zoom = camera.value.zoom;
2051
- const position = camera.value.position;
2052
- obb.left *= zoom.x;
2053
- obb.top *= zoom.y;
2054
- obb.width *= zoom.x;
2055
- obb.height *= zoom.y;
2056
- obb.left -= position.x;
2057
- obb.top -= position.y;
2067
+ obb = obbToDrawboardObb(obb);
2058
2068
  } else if (inTarget === "frame") {
2059
2069
  const first = Array.isArray(node) ? node[0] : node;
2060
2070
  if (isElement(first)) {
@@ -2150,6 +2160,18 @@ const _2_box = defineMixin((editor) => {
2150
2160
  _aabb.top -= position.y;
2151
2161
  return _aabb;
2152
2162
  }
2163
+ function obbToDrawboardObb(obb) {
2164
+ const _obb = new Obb2D(obb);
2165
+ const zoom = camera.value.zoom;
2166
+ const position = camera.value.position;
2167
+ _obb.left *= zoom.x;
2168
+ _obb.top *= zoom.y;
2169
+ _obb.width *= zoom.x;
2170
+ _obb.height *= zoom.y;
2171
+ _obb.left -= position.x;
2172
+ _obb.top -= position.y;
2173
+ return _obb;
2174
+ }
2153
2175
  const viewportAabb = computed(() => {
2154
2176
  const _camera = camera.value;
2155
2177
  const { position, zoom } = _camera;
@@ -2172,12 +2194,13 @@ const _2_box = defineMixin((editor) => {
2172
2194
  });
2173
2195
  const rootAabb = computed(() => getAabb(root.value.children));
2174
2196
  const selectionAabb = computed(() => getAabb(selection.value));
2175
- const selectionAabbInDrawboard = computed(() => getAabb(selection.value, "drawboard"));
2197
+ const selectionAabbInDrawboard = computed(() => aabbToDrawboardAabb(selectionAabb.value));
2176
2198
  const selectionObb = computed(() => getObb(selection.value));
2177
- const selectionObbInDrawboard = computed(() => getObb(selection.value, "drawboard"));
2199
+ const selectionObbInDrawboard = computed(() => obbToDrawboardObb(selectionObb.value));
2178
2200
  Object.assign(editor, {
2179
2201
  obbToFit,
2180
2202
  getObb,
2203
+ obbToDrawboardObb,
2181
2204
  getAabb,
2182
2205
  aabbToDrawboardAabb,
2183
2206
  viewportAabb,
@@ -3932,106 +3955,6 @@ const _http = defineMixin((editor, options) => {
3932
3955
  http: options.http ?? createHttp()
3933
3956
  });
3934
3957
  });
3935
- const _scroll$1 = defineMixin((editor) => {
3936
- const {
3937
- camera,
3938
- getAabb,
3939
- selectionAabb,
3940
- rootAabb,
3941
- viewportAabb,
3942
- screenCenter,
3943
- screenCenterOffset
3944
- } = editor;
3945
- const scrollTo = async (target, options = {}) => {
3946
- const {
3947
- intoView,
3948
- behavior,
3949
- duration = 500
3950
- } = options;
3951
- const _camera = camera.value;
3952
- const { position: _position, zoom } = _camera;
3953
- const oldPosition = { x: _position.x, y: _position.y };
3954
- const _screenCenter = screenCenter.value;
3955
- const offset2 = { x: 0, y: 0 };
3956
- let targetPosition = {};
3957
- if (typeof target === "object") {
3958
- if ("x" in target) {
3959
- targetPosition.x = target.x;
3960
- offset2.x = -screenCenterOffset.value.left;
3961
- }
3962
- if ("y" in target) {
3963
- targetPosition.y = target.y;
3964
- offset2.y = -screenCenterOffset.value.top;
3965
- }
3966
- } else {
3967
- let aabb;
3968
- if (Array.isArray(target)) {
3969
- aabb = getAabb(target);
3970
- } else {
3971
- switch (target) {
3972
- case "selection":
3973
- aabb = selectionAabb.value;
3974
- break;
3975
- case "root":
3976
- default:
3977
- aabb = rootAabb.value;
3978
- break;
3979
- }
3980
- }
3981
- if (intoView && viewportAabb.value.contains(aabb)) {
3982
- return;
3983
- }
3984
- targetPosition = { x: aabb.left + aabb.width / 2, y: aabb.top + aabb.height / 2 };
3985
- offset2.x += -_screenCenter.x;
3986
- offset2.y = -_screenCenter.y;
3987
- }
3988
- if (targetPosition.x !== void 0) {
3989
- targetPosition.x *= zoom.x;
3990
- targetPosition.x += offset2.x;
3991
- }
3992
- if (targetPosition.y !== void 0) {
3993
- targetPosition.y *= zoom.y;
3994
- targetPosition.y += offset2.y;
3995
- }
3996
- const position = {
3997
- ...oldPosition,
3998
- ...targetPosition
3999
- };
4000
- switch (behavior) {
4001
- case "smooth":
4002
- await new Promise((resolve) => {
4003
- const positionDistance = {
4004
- x: position.x - oldPosition.x,
4005
- y: position.y - oldPosition.y
4006
- };
4007
- const startTime = performance.now();
4008
- function step(now) {
4009
- const elapsed = now - startTime;
4010
- const progress = Math.min(elapsed / duration, 1);
4011
- const ease = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress;
4012
- _position.set(
4013
- oldPosition.x + positionDistance.x * ease,
4014
- oldPosition.y + positionDistance.y * ease
4015
- );
4016
- if (elapsed < duration) {
4017
- requestAnimationFrame(step);
4018
- } else {
4019
- resolve();
4020
- }
4021
- }
4022
- requestAnimationFrame(step);
4023
- });
4024
- break;
4025
- case "instant":
4026
- default:
4027
- _position.set(position.x, position.y);
4028
- break;
4029
- }
4030
- };
4031
- Object.assign(editor, {
4032
- scrollTo
4033
- });
4034
- });
4035
3958
  const _snapshot = defineMixin((editor) => {
4036
3959
  const {
4037
3960
  isElement,
@@ -4092,10 +4015,11 @@ const _snapshot = defineMixin((editor) => {
4092
4015
  return () => {
4093
4016
  const {
4094
4017
  on,
4018
+ off,
4095
4019
  config,
4096
4020
  inEditorIs
4097
4021
  } = editor;
4098
- on("setDoc", (doc) => {
4022
+ function onSetDoc(doc) {
4099
4023
  if (config.value.frameScreenshot) {
4100
4024
  snapshot();
4101
4025
  }
@@ -4121,130 +4045,14 @@ const _snapshot = defineMixin((editor) => {
4121
4045
  }
4122
4046
  doc.root.on("addChild", onAddChild);
4123
4047
  doc.root.on("removeChild", onRemoveChild);
4124
- });
4125
- };
4126
- });
4127
- const _zoom$1 = defineMixin((editor) => {
4128
- const {
4129
- camera,
4130
- drawboardAabb,
4131
- selectionAabb,
4132
- rootAabb,
4133
- getAabb,
4134
- screenCenterOffset,
4135
- viewportAabb
4136
- } = editor;
4137
- const zoomTo = async (target, options = {}) => {
4138
- const {
4139
- intoView,
4140
- mode = "contain",
4141
- duration = 500,
4142
- behavior
4143
- } = options;
4144
- let aabb;
4145
- if (Array.isArray(target) || typeof target === "object") {
4146
- aabb = getAabb(target);
4147
- } else {
4148
- switch (target) {
4149
- case "selection":
4150
- aabb = selectionAabb.value;
4151
- break;
4152
- case "root":
4153
- default:
4154
- aabb = rootAabb.value;
4155
- break;
4156
- }
4157
- }
4158
- if (intoView && viewportAabb.value.contains(aabb)) {
4159
- return;
4160
- }
4161
- const offset2 = screenCenterOffset.value;
4162
- const { width, height } = drawboardAabb.value;
4163
- const tw = width - (offset2.left + offset2.right);
4164
- const th = height - (offset2.top + offset2.bottom);
4165
- const [sx, sy, sw, sh] = aabb.toArray();
4166
- if (!sw || !sh)
4167
- return;
4168
- const zw = tw / sw;
4169
- const zh = th / sh;
4170
- const _camera = camera.value;
4171
- let targetZoom;
4172
- if (typeof target === "number") {
4173
- targetZoom = target;
4174
- } else {
4175
- switch (mode) {
4176
- case "width":
4177
- targetZoom = zw;
4178
- break;
4179
- case "height":
4180
- targetZoom = zh;
4181
- break;
4182
- case "cover":
4183
- targetZoom = Math.max(zw, zh);
4184
- break;
4185
- case "contain":
4186
- default:
4187
- targetZoom = Math.min(zw, zh);
4188
- break;
4189
- }
4190
- }
4191
- const oldZoom = Math.min(_camera.zoom.x, _camera.zoom.y);
4192
- const newZoom = Math.min(
4193
- clamp(targetZoom, _camera.minZoom.x, _camera.maxZoom.x),
4194
- clamp(targetZoom, _camera.minZoom.y, _camera.maxZoom.y)
4195
- );
4196
- let x = offset2.left;
4197
- let y = offset2.top;
4198
- if (zw < zh) {
4199
- y += (th - sh * newZoom) / 2;
4200
- } else {
4201
- x += (tw - sw * newZoom) / 2;
4202
- }
4203
- const oldPosition = {
4204
- x: _camera.position.x,
4205
- y: _camera.position.y
4206
- };
4207
- const newPosition = {
4208
- x: sx * newZoom - x,
4209
- y: sy * newZoom - y
4210
- };
4211
- switch (behavior) {
4212
- case "smooth":
4213
- await new Promise((resolve) => {
4214
- const zoomDistance = newZoom - oldZoom;
4215
- const positionDistance = {
4216
- x: newPosition.x - oldPosition.x,
4217
- y: newPosition.y - oldPosition.y
4218
- };
4219
- const startTime = performance.now();
4220
- function step(now) {
4221
- const elapsed = now - startTime;
4222
- const progress = Math.min(elapsed / duration, 1);
4223
- const ease = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress;
4224
- _camera.zoom.set(oldZoom + zoomDistance * ease);
4225
- _camera.position.set(
4226
- oldPosition.x + positionDistance.x * ease,
4227
- oldPosition.y + positionDistance.y * ease
4228
- );
4229
- if (elapsed < duration) {
4230
- requestAnimationFrame(step);
4231
- } else {
4232
- resolve();
4233
- }
4234
- }
4235
- requestAnimationFrame(step);
4236
- });
4237
- break;
4238
- case "instant":
4239
- default:
4240
- _camera.zoom.set(newZoom);
4241
- _camera.position.set(newPosition.x, newPosition.y);
4242
- break;
4243
4048
  }
4049
+ onBeforeMount(() => {
4050
+ on("setDoc", onSetDoc);
4051
+ });
4052
+ onScopeDispose(() => {
4053
+ off("setDoc", onSetDoc);
4054
+ });
4244
4055
  };
4245
- Object.assign(editor, {
4246
- zoomTo
4247
- });
4248
4056
  });
4249
4057
  const mixins = [
4250
4058
  _0_command,
@@ -4269,9 +4077,7 @@ const mixins = [
4269
4077
  _4_4_doc,
4270
4078
  _drawingTool$1,
4271
4079
  _http,
4272
- _scroll$1,
4273
- _snapshot,
4274
- _zoom$1
4080
+ _snapshot
4275
4081
  ];
4276
4082
  function definePlugin(cb) {
4277
4083
  return cb;
@@ -4539,7 +4345,7 @@ const _autoNest = definePlugin((editor) => {
4539
4345
  }
4540
4346
  }
4541
4347
  },
4542
- selectionTransforming: ({ handle, startEvent, elements }) => {
4348
+ selectionTransform: ({ handle, startEvent, elements }) => {
4543
4349
  if (handle === "move" && !startEvent?.__FROM__) {
4544
4350
  if (Object.keys(startContext).length > 0) {
4545
4351
  elements.forEach((el) => {
@@ -4617,11 +4423,11 @@ const _drawingTool = definePlugin((editor) => {
4617
4423
  } = editor;
4618
4424
  return {
4619
4425
  name: "mce:drawingTool",
4620
- components: [
4621
- { name: "drawing", type: "overlay", component: _sfc_main$E }
4622
- ],
4623
4426
  commands: [
4624
4427
  { command: "setActiveDrawingTool", handle: (val) => setActiveDrawingTool(val) }
4428
+ ],
4429
+ components: [
4430
+ { name: "drawing", type: "overlay", component: _sfc_main$E }
4625
4431
  ]
4626
4432
  };
4627
4433
  });
@@ -4885,8 +4691,8 @@ const _edit = definePlugin((editor, options) => {
4885
4691
  await paste(e.clipboardData);
4886
4692
  }
4887
4693
  }
4888
- window.addEventListener("paste", onPaste);
4889
- onBeforeUnmount(() => window.removeEventListener("paste", onPaste));
4694
+ onMounted(() => window.addEventListener("paste", onPaste));
4695
+ onScopeDispose(() => window.removeEventListener("paste", onPaste));
4890
4696
  }
4891
4697
  }
4892
4698
  };
@@ -6008,7 +5814,7 @@ const _import = definePlugin((editor) => {
6008
5814
  drawboardDom.value?.addEventListener("dragover", onDragover);
6009
5815
  drawboardDom.value?.addEventListener("drop", onDrop);
6010
5816
  });
6011
- onBeforeUnmount(() => {
5817
+ onScopeDispose(() => {
6012
5818
  drawboardDom.value?.removeEventListener("dragover", onDragover);
6013
5819
  drawboardDom.value?.removeEventListener("drop", onDrop);
6014
5820
  });
@@ -6161,7 +5967,6 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
6161
5967
  selection,
6162
5968
  nodes,
6163
5969
  nodeIndexMap,
6164
- zoomTo,
6165
5970
  hoverElement,
6166
5971
  exec,
6167
5972
  t
@@ -6286,7 +6091,7 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
6286
6091
  function onDblclickThumbnail(e) {
6287
6092
  e.stopPropagation();
6288
6093
  if (isElement(props.node)) {
6289
- zoomTo("selection", {
6094
+ exec("zoomTo", "selection", {
6290
6095
  behavior: "smooth"
6291
6096
  });
6292
6097
  }
@@ -12213,22 +12018,115 @@ const _sfc_main$n = /* @__PURE__ */ defineComponent({
12213
12018
  });
12214
12019
  const _scroll = definePlugin((editor) => {
12215
12020
  const {
12216
- scrollTo,
12217
12021
  config,
12218
- registerConfig
12022
+ registerConfig,
12023
+ camera,
12024
+ getAabb,
12025
+ selectionAabb,
12026
+ rootAabb,
12027
+ viewportAabb,
12028
+ screenCenter,
12029
+ screenCenterOffset
12219
12030
  } = editor;
12220
12031
  registerConfig("scrollbar", false);
12221
- return {
12222
- name: "mce:scroll",
12223
- commands: [
12224
- { command: "scrollToSelection", handle: (options) => scrollTo("selection", options) }
12225
- ],
12226
- components: [
12227
- {
12228
- type: "overlay",
12229
- component: _sfc_main$n,
12230
- ignore: () => !config.value.scrollbar
12231
- }
12032
+ const scrollTo = async (target, options = {}) => {
12033
+ const {
12034
+ intoView,
12035
+ behavior,
12036
+ duration = 500
12037
+ } = options;
12038
+ const _camera = camera.value;
12039
+ const { position: _position, zoom } = _camera;
12040
+ const oldPosition = { x: _position.x, y: _position.y };
12041
+ const _screenCenter = screenCenter.value;
12042
+ const offset2 = { x: 0, y: 0 };
12043
+ let targetPosition = {};
12044
+ if (typeof target === "object") {
12045
+ if ("x" in target) {
12046
+ targetPosition.x = target.x;
12047
+ offset2.x = -screenCenterOffset.value.left;
12048
+ }
12049
+ if ("y" in target) {
12050
+ targetPosition.y = target.y;
12051
+ offset2.y = -screenCenterOffset.value.top;
12052
+ }
12053
+ } else {
12054
+ let aabb;
12055
+ if (Array.isArray(target)) {
12056
+ aabb = getAabb(target);
12057
+ } else {
12058
+ switch (target) {
12059
+ case "selection":
12060
+ aabb = selectionAabb.value;
12061
+ break;
12062
+ case "root":
12063
+ default:
12064
+ aabb = rootAabb.value;
12065
+ break;
12066
+ }
12067
+ }
12068
+ if (intoView && viewportAabb.value.contains(aabb)) {
12069
+ return;
12070
+ }
12071
+ targetPosition = { x: aabb.left + aabb.width / 2, y: aabb.top + aabb.height / 2 };
12072
+ offset2.x += -_screenCenter.x;
12073
+ offset2.y = -_screenCenter.y;
12074
+ }
12075
+ if (targetPosition.x !== void 0) {
12076
+ targetPosition.x *= zoom.x;
12077
+ targetPosition.x += offset2.x;
12078
+ }
12079
+ if (targetPosition.y !== void 0) {
12080
+ targetPosition.y *= zoom.y;
12081
+ targetPosition.y += offset2.y;
12082
+ }
12083
+ const position = {
12084
+ ...oldPosition,
12085
+ ...targetPosition
12086
+ };
12087
+ switch (behavior) {
12088
+ case "smooth":
12089
+ await new Promise((resolve) => {
12090
+ const positionDistance = {
12091
+ x: position.x - oldPosition.x,
12092
+ y: position.y - oldPosition.y
12093
+ };
12094
+ const startTime = performance.now();
12095
+ function step(now) {
12096
+ const elapsed = now - startTime;
12097
+ const progress = Math.min(elapsed / duration, 1);
12098
+ const ease = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress;
12099
+ _position.set(
12100
+ oldPosition.x + positionDistance.x * ease,
12101
+ oldPosition.y + positionDistance.y * ease
12102
+ );
12103
+ if (elapsed < duration) {
12104
+ requestAnimationFrame(step);
12105
+ } else {
12106
+ resolve();
12107
+ }
12108
+ }
12109
+ requestAnimationFrame(step);
12110
+ });
12111
+ break;
12112
+ case "instant":
12113
+ default:
12114
+ _position.set(position.x, position.y);
12115
+ break;
12116
+ }
12117
+ };
12118
+ return {
12119
+ name: "mce:scroll",
12120
+ commands: [
12121
+ { command: "scrollTo", handle: scrollTo },
12122
+ { command: "scrollToSelection", handle: (options) => scrollTo("selection", options) }
12123
+ ],
12124
+ components: [
12125
+ {
12126
+ type: "overlay",
12127
+ component: _sfc_main$n,
12128
+ ignore: () => !config.value.scrollbar
12129
+ }
12232
12130
  ]
12233
12131
  // setup: () => {
12234
12132
  // const {
@@ -12263,7 +12161,7 @@ const _scroll = definePlugin((editor) => {
12263
12161
  };
12264
12162
  });
12265
12163
  const _sfc_main$m = /* @__PURE__ */ defineComponent({
12266
- __name: "GoBackSelectedArea",
12164
+ __name: "ScrollToSelection",
12267
12165
  setup(__props) {
12268
12166
  const {
12269
12167
  selectionAabb,
@@ -12277,11 +12175,11 @@ const _sfc_main$m = /* @__PURE__ */ defineComponent({
12277
12175
  return (_ctx, _cache) => {
12278
12176
  return isActive.value ? (openBlock(), createElementBlock("div", {
12279
12177
  key: 0,
12280
- class: "mce-back-selected-aera",
12178
+ class: "mce-scroll-to-selection",
12281
12179
  onClick: _cache[0] || (_cache[0] = withModifiers(($event) => unref(exec)("scrollToSelection", { behavior: "smooth" }), ["prevent"]))
12282
12180
  }, [
12283
12181
  createVNode(unref(_sfc_main$D), { icon: "$gps" }),
12284
- createElementVNode("span", null, toDisplayString(unref(t)("goBackSelectedArea")), 1)
12182
+ createElementVNode("span", null, toDisplayString(unref(t)("scrollToSelection")), 1)
12285
12183
  ])) : createCommentVNode("", true);
12286
12184
  };
12287
12185
  }
@@ -12295,7 +12193,6 @@ const _selection = definePlugin((editor) => {
12295
12193
  getAabb,
12296
12194
  doc,
12297
12195
  root,
12298
- zoomTo,
12299
12196
  findSibling,
12300
12197
  inEditorIs,
12301
12198
  addElement,
@@ -12304,7 +12201,8 @@ const _selection = definePlugin((editor) => {
12304
12201
  setVisible,
12305
12202
  isVisible,
12306
12203
  setLock,
12307
- isLock
12204
+ isLock,
12205
+ exec
12308
12206
  } = editor;
12309
12207
  function select(target) {
12310
12208
  switch (target) {
@@ -12336,7 +12234,7 @@ const _selection = definePlugin((editor) => {
12336
12234
  const value = findSibling(target === "previousSibling" ? "previous" : "next");
12337
12235
  if (value) {
12338
12236
  selection.value = [value];
12339
- zoomTo("selection", {
12237
+ exec("zoomTo", "selection", {
12340
12238
  intoView: true,
12341
12239
  behavior: "smooth"
12342
12240
  });
@@ -12468,11 +12366,8 @@ const _selection = definePlugin((editor) => {
12468
12366
  { command: "showOrHideSelection", key: "Shift+CmdOrCtrl+H" },
12469
12367
  { command: "lockOrUnlockSelection", key: "Shift+CmdOrCtrl+L" }
12470
12368
  ],
12471
- components: [
12472
- { type: "overlay", component: _sfc_main$m }
12473
- ],
12474
12369
  events: {
12475
- selectionTransforming: ({ elements }) => {
12370
+ selectionTransform: ({ elements }) => {
12476
12371
  elements.forEach((el) => {
12477
12372
  el.findAncestor((ancestor) => {
12478
12373
  if (isElement(ancestor) && !inEditorIs(ancestor, "Frame")) {
@@ -12482,7 +12377,10 @@ const _selection = definePlugin((editor) => {
12482
12377
  });
12483
12378
  });
12484
12379
  }
12485
- }
12380
+ },
12381
+ components: [
12382
+ { type: "overlay", component: _sfc_main$m }
12383
+ ]
12486
12384
  };
12487
12385
  });
12488
12386
  function rotatePoint(center, point, angleRad) {
@@ -12748,11 +12646,11 @@ const _slice = definePlugin((editor) => {
12748
12646
  }
12749
12647
  }
12750
12648
  ],
12751
- hotkeys: [
12752
- { command: "setActiveDrawingTool:slice", key: "S" }
12753
- ],
12754
12649
  commands: [
12755
12650
  { command: "exportSlice", handle: exportSlice }
12651
+ ],
12652
+ hotkeys: [
12653
+ { command: "setActiveDrawingTool:slice", key: "S" }
12756
12654
  ]
12757
12655
  };
12758
12656
  });
@@ -14067,7 +13965,7 @@ const _smartGuides = definePlugin((editor) => {
14067
13965
  return {
14068
13966
  name: "mce:smartGuides",
14069
13967
  events: {
14070
- selectionTransforming: ({ handle }) => {
13968
+ selectionTransform: ({ handle }) => {
14071
13969
  if (handle === "move") {
14072
13970
  updateSmartGuides();
14073
13971
  }
@@ -14128,9 +14026,8 @@ const _hoisted_10$1 = {
14128
14026
  };
14129
14027
  const _sfc_main$k = /* @__PURE__ */ defineComponent({
14130
14028
  __name: "TransformControls",
14131
- props: {
14029
+ props: /* @__PURE__ */ mergeModels({
14132
14030
  tag: { default: "div" },
14133
- modelValue: {},
14134
14031
  color: {},
14135
14032
  movable: { type: Boolean, default: true },
14136
14033
  rotatable: { type: Boolean, default: true },
@@ -14141,7 +14038,6 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
14141
14038
  resizeStrategy: {},
14142
14039
  handleStrategy: {},
14143
14040
  handleShape: { default: "rect" },
14144
- hideUi: { type: Boolean },
14145
14041
  handles: { default: () => [
14146
14042
  "move",
14147
14043
  // resize
@@ -14164,14 +14060,21 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
14164
14060
  "rotate-bl",
14165
14061
  "rotate-br"
14166
14062
  ] },
14063
+ scale: { default: () => [1, 1] },
14064
+ offset: { default: () => [0, 0] },
14065
+ hideUi: { type: Boolean },
14167
14066
  initialSize: { type: Boolean },
14168
14067
  borderStyle: {},
14169
14068
  tipFormat: {}
14170
- },
14171
- emits: ["update:modelValue", "start", "move", "end"],
14069
+ }, {
14070
+ "modelValue": {},
14071
+ "modelModifiers": {}
14072
+ }),
14073
+ emits: /* @__PURE__ */ mergeModels(["start", "move", "end"], ["update:modelValue"]),
14172
14074
  setup(__props, { expose: __expose, emit: __emit }) {
14173
14075
  const props = __props;
14174
14076
  const emit = __emit;
14077
+ const _model = useModel(__props, "modelValue");
14175
14078
  const cursors = {
14176
14079
  "rotate-tl": (angle) => createCursor("rotate", 360 + angle),
14177
14080
  "rotate-tr": (angle) => createCursor("rotate", 90 + angle),
@@ -14186,17 +14089,43 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
14186
14089
  "resize-br": (angle) => createCursor("resizeBevel", 90 + angle),
14187
14090
  "resize-bl": (angle) => createCursor("resizeBevel", 180 + angle)
14188
14091
  };
14189
- const modelValue = useModel(props, "modelValue");
14190
14092
  const model = computed({
14191
14093
  get: () => {
14192
- let { left = 0, top = 0, width = 0, height = 0, rotate = 0, borderRadius = 0 } = modelValue.value ?? {};
14094
+ const scale = props.scale;
14095
+ const offset2 = props.offset;
14096
+ let {
14097
+ left = 0,
14098
+ top = 0,
14099
+ width = 0,
14100
+ height = 0,
14101
+ rotate = 0,
14102
+ borderRadius = 0
14103
+ } = _model.value ?? {};
14193
14104
  if (Number.isNaN(Number(width)))
14194
14105
  width = 0;
14195
14106
  if (Number.isNaN(Number(height)))
14196
14107
  height = 0;
14197
- return { left, top, width, height, rotate, borderRadius };
14108
+ return {
14109
+ left: left * scale[0] + offset2[0],
14110
+ top: top * scale[1] + offset2[1],
14111
+ width: width * scale[0],
14112
+ height: height * scale[1],
14113
+ rotate,
14114
+ borderRadius
14115
+ };
14198
14116
  },
14199
- set: (val) => modelValue.value = val
14117
+ set: (val) => {
14118
+ const scale = props.scale;
14119
+ const offset2 = props.offset;
14120
+ _model.value = {
14121
+ left: (val.left - offset2[0]) / scale[0],
14122
+ top: (val.top - offset2[1]) / scale[1],
14123
+ width: val.width / scale[0],
14124
+ height: val.height / scale[1],
14125
+ rotate: val.rotate,
14126
+ borderRadius: val.borderRadius
14127
+ };
14128
+ }
14200
14129
  });
14201
14130
  const transforming = ref(false);
14202
14131
  const activeHandle = ref();
@@ -14496,8 +14425,11 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
14496
14425
  updated.left = minX;
14497
14426
  updated.top = minY;
14498
14427
  }
14499
- if ("width" in updated && updated.width <= 0 || "height" in updated && updated.height <= 0) {
14500
- return;
14428
+ if ("width" in updated) {
14429
+ updated.width = Math.max(1, updated.width);
14430
+ }
14431
+ if ("height" in updated) {
14432
+ updated.height = Math.max(1, updated.height);
14501
14433
  }
14502
14434
  if (updated.borderRadius ?? borderRadius) {
14503
14435
  updated.borderRadius = Math.min(
@@ -14647,7 +14579,7 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
14647
14579
  }, {
14648
14580
  default: withCtx(() => [
14649
14581
  renderSlot(_ctx.$slots, "default", {
14650
- value: unref(modelValue),
14582
+ value: model.value,
14651
14583
  props: {
14652
14584
  onPointerdown: start
14653
14585
  },
@@ -14749,7 +14681,13 @@ const _hoisted_1$c = {
14749
14681
  const _hoisted_2$6 = ["onClick"];
14750
14682
  const _sfc_main$j = /* @__PURE__ */ defineComponent({
14751
14683
  __name: "SmartSelection",
14684
+ props: {
14685
+ "modelValue": {},
14686
+ "modelModifiers": {}
14687
+ },
14688
+ emits: ["update:modelValue"],
14752
14689
  setup(__props) {
14690
+ const currentElement = useModel(__props, "modelValue");
14753
14691
  const {
14754
14692
  elementSelection,
14755
14693
  getObb,
@@ -14757,19 +14695,13 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
14757
14695
  state,
14758
14696
  camera,
14759
14697
  resizeElement,
14760
- inEditorIs,
14761
- registerCommand
14698
+ inEditorIs
14762
14699
  } = useEditor();
14763
- const currentElement = ref();
14764
14700
  const info = ref({
14765
14701
  active: false,
14766
- spacing: void 0
14767
- });
14768
- registerCommand({
14769
- command: "setSmartSelectionCurrentElement",
14770
- handle: (el) => {
14771
- currentElement.value = el;
14772
- }
14702
+ spacing: void 0,
14703
+ xItems: [],
14704
+ yItems: []
14773
14705
  });
14774
14706
  function update() {
14775
14707
  if (currentElement.value) {
@@ -14778,6 +14710,8 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
14778
14710
  const els = elementSelection.value;
14779
14711
  let active = false;
14780
14712
  let spacing;
14713
+ let xItems = [];
14714
+ let yItems = [];
14781
14715
  if (state.value !== "transforming" && els.length > 1) {
14782
14716
  let prev;
14783
14717
  const items = els.map((el) => ({ el, aabb: getAabb(el) }));
@@ -14799,7 +14733,9 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
14799
14733
  }
14800
14734
  prev = cur;
14801
14735
  }
14802
- if (!active) {
14736
+ if (active) {
14737
+ yItems = sorted;
14738
+ } else {
14803
14739
  active = true;
14804
14740
  prev = void 0;
14805
14741
  spacing = void 0;
@@ -14820,11 +14756,16 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
14820
14756
  }
14821
14757
  prev = cur;
14822
14758
  }
14759
+ if (active) {
14760
+ xItems = sorted2;
14761
+ }
14823
14762
  }
14824
14763
  }
14825
14764
  info.value = {
14826
14765
  active,
14827
- spacing
14766
+ spacing,
14767
+ xItems,
14768
+ yItems
14828
14769
  };
14829
14770
  }
14830
14771
  watch(() => elementSelection.value.map((el) => getAabb(el)), update);
@@ -14842,32 +14783,19 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
14842
14783
  };
14843
14784
  });
14844
14785
  });
14845
- const _transform2 = computed(() => {
14846
- const { left, top, width, height, rotationDegrees } = getObb(currentElement.value, "drawboard");
14847
- return {
14848
- left,
14849
- top,
14850
- width,
14851
- height,
14852
- rotate: rotationDegrees
14853
- };
14854
- });
14855
14786
  const transform = computed({
14856
- get: () => _transform2.value,
14787
+ get: () => {
14788
+ const { left, top, width, height, rotationDegrees: rotate } = getObb(currentElement.value);
14789
+ return { left, top, width, height, rotate };
14790
+ },
14857
14791
  set: (val) => {
14858
- const zoom = camera.value.zoom;
14859
- const oldTransform = _transform2.value;
14860
- const transform2 = {
14861
- left: val.left / zoom.x,
14862
- top: val.top / zoom.y,
14863
- width: Math.max(1, val.width / zoom.x),
14864
- height: Math.max(1, val.height / zoom.y)
14865
- };
14792
+ const oldTransform = transform.value;
14866
14793
  const offsetStyle = {
14867
- left: transform2.left - oldTransform.left / zoom.x,
14868
- top: transform2.top - oldTransform.top / zoom.y,
14869
- width: transform2.width - oldTransform.width / zoom.x,
14870
- height: transform2.height - oldTransform.height / zoom.y
14794
+ left: val.left - oldTransform.left,
14795
+ top: val.top - oldTransform.top,
14796
+ width: val.width - oldTransform.width,
14797
+ height: val.height - oldTransform.height,
14798
+ rotate: val.rotate - oldTransform.rotate
14871
14799
  };
14872
14800
  const el = currentElement.value;
14873
14801
  const style = el.style;
@@ -14875,21 +14803,48 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
14875
14803
  left: style.left + offsetStyle.left,
14876
14804
  top: style.top + offsetStyle.top,
14877
14805
  width: style.width + offsetStyle.width,
14878
- height: style.height + offsetStyle.height
14806
+ height: style.height + offsetStyle.height,
14807
+ rotate: (style.rotate + offsetStyle.rotate + 360) % 360
14879
14808
  };
14880
- const newWidth = Math.max(1, newStyle.width);
14881
- const newHeight = Math.max(1, newStyle.height);
14809
+ const oldAabb = el.getGlobalAabb();
14882
14810
  const shape = el.shape;
14883
14811
  resizeElement(
14884
14812
  el,
14885
- newWidth,
14886
- newHeight,
14813
+ newStyle.width,
14814
+ newStyle.height,
14887
14815
  inEditorIs(el, "Frame") ? void 0 : shape.isValid() ? { deep: true } : { deep: true, textToFit: true }
14888
14816
  );
14889
14817
  newStyle.width = el.style.width;
14890
14818
  newStyle.height = el.style.height;
14891
- Object.assign(style, newStyle);
14819
+ Object.assign(el.style, newStyle);
14892
14820
  el.updateGlobalTransform();
14821
+ const aabb = el.getGlobalAabb();
14822
+ const offset2 = {
14823
+ left: aabb.left - oldAabb.left,
14824
+ top: aabb.top - oldAabb.top,
14825
+ right: aabb.right - oldAabb.right,
14826
+ bottom: aabb.bottom - oldAabb.bottom
14827
+ };
14828
+ let after = false;
14829
+ info.value.yItems.forEach((item) => {
14830
+ if (item.el.equal(el)) {
14831
+ after = true;
14832
+ } else if (after) {
14833
+ item.el.style.top += offset2.bottom;
14834
+ } else {
14835
+ item.el.style.top += offset2.top;
14836
+ }
14837
+ });
14838
+ after = false;
14839
+ info.value.xItems.forEach((item) => {
14840
+ if (item.el.equal(el)) {
14841
+ after = true;
14842
+ } else if (after) {
14843
+ item.el.style.left += offset2.right;
14844
+ } else {
14845
+ item.el.style.left += offset2.left;
14846
+ }
14847
+ });
14893
14848
  }
14894
14849
  });
14895
14850
  return (_ctx, _cache) => {
@@ -14914,19 +14869,31 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
14914
14869
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => transform.value = $event),
14915
14870
  handles: ["resize-l", "resize-r", "resize-t", "resize-b"],
14916
14871
  class: "mce-smart-selection__transform",
14917
- color: "#FF24BD"
14918
- }, null, 8, ["modelValue"])) : createCommentVNode("", true)
14872
+ color: "#FF24BD",
14873
+ scale: [unref(camera).zoom.x, unref(camera).zoom.y],
14874
+ offset: [-unref(camera).position.x, -unref(camera).position.y]
14875
+ }, null, 8, ["modelValue", "scale", "offset"])) : createCommentVNode("", true)
14919
14876
  ])) : createCommentVNode("", true);
14920
14877
  };
14921
14878
  }
14922
14879
  });
14923
14880
  const _smartSelection = definePlugin((_editor) => {
14881
+ const currentElement = ref();
14924
14882
  return {
14925
14883
  name: "mce:smartSelection",
14884
+ commands: [
14885
+ {
14886
+ command: "setSmartSelectionCurrentElement",
14887
+ handle: (el) => currentElement.value = el
14888
+ }
14889
+ ],
14926
14890
  components: [
14927
14891
  {
14928
14892
  type: "overlay",
14929
- component: _sfc_main$j
14893
+ component: () => h(_sfc_main$j, {
14894
+ "modelValue": currentElement.value,
14895
+ "onUpdate:modelValue": (el) => currentElement.value = el
14896
+ })
14930
14897
  }
14931
14898
  ]
14932
14899
  };
@@ -15760,12 +15727,14 @@ const _ui = definePlugin((editor) => {
15760
15727
  const { left = _left, top = _top } = drawboardDom.value?.getBoundingClientRect() ?? {};
15761
15728
  drawboardAabb.value = new Aabb2D(left, top, width, height);
15762
15729
  });
15763
- document.addEventListener("mousemove", (event) => {
15730
+ function onMouseMove(event) {
15764
15731
  drawboardPointer.value = new Vector2$1(
15765
15732
  event.clientX - drawboardAabb.value.left,
15766
15733
  event.clientY - drawboardAabb.value.top
15767
15734
  );
15768
- });
15735
+ }
15736
+ onMounted(() => document.addEventListener("mousemove", onMouseMove));
15737
+ onScopeDispose(() => document.removeEventListener("mousemove", onMouseMove));
15769
15738
  }
15770
15739
  };
15771
15740
  });
@@ -15814,13 +15783,127 @@ const _zoom = definePlugin((editor) => {
15814
15783
  const {
15815
15784
  registerConfig,
15816
15785
  camera,
15817
- zoomTo,
15818
15786
  exec,
15819
15787
  config,
15820
15788
  findFrame,
15821
- selection
15789
+ selection,
15790
+ drawboardAabb,
15791
+ selectionAabb,
15792
+ rootAabb,
15793
+ getAabb,
15794
+ screenCenterOffset,
15795
+ viewportAabb
15822
15796
  } = editor;
15823
15797
  registerConfig("zoomToFit", "contain");
15798
+ async function zoomTo(target, options = {}) {
15799
+ const {
15800
+ intoView,
15801
+ mode = "contain",
15802
+ duration = 500,
15803
+ behavior
15804
+ } = options;
15805
+ let aabb;
15806
+ if (Array.isArray(target) || typeof target === "object") {
15807
+ aabb = getAabb(target);
15808
+ } else {
15809
+ switch (target) {
15810
+ case "selection":
15811
+ aabb = selectionAabb.value;
15812
+ break;
15813
+ case "root":
15814
+ default:
15815
+ aabb = rootAabb.value;
15816
+ break;
15817
+ }
15818
+ }
15819
+ if (intoView && viewportAabb.value.contains(aabb)) {
15820
+ return;
15821
+ }
15822
+ const [sx, sy, sw, sh] = aabb.toArray();
15823
+ if (!sw || !sh) {
15824
+ return;
15825
+ }
15826
+ const offset2 = screenCenterOffset.value;
15827
+ const { width, height } = drawboardAabb.value;
15828
+ const tw = width - (offset2.left + offset2.right);
15829
+ const th = height - (offset2.top + offset2.bottom);
15830
+ const zw = tw / sw;
15831
+ const zh = th / sh;
15832
+ const _camera = camera.value;
15833
+ let targetZoom;
15834
+ if (typeof target === "number") {
15835
+ targetZoom = target;
15836
+ } else {
15837
+ switch (mode) {
15838
+ case "width":
15839
+ targetZoom = zw;
15840
+ break;
15841
+ case "height":
15842
+ targetZoom = zh;
15843
+ break;
15844
+ case "cover":
15845
+ targetZoom = Math.max(zw, zh);
15846
+ break;
15847
+ case "contain":
15848
+ default:
15849
+ targetZoom = Math.min(zw, zh);
15850
+ break;
15851
+ }
15852
+ }
15853
+ const oldZoom = Math.min(_camera.zoom.x, _camera.zoom.y);
15854
+ const newZoom = Math.min(
15855
+ clamp(targetZoom, _camera.minZoom.x, _camera.maxZoom.x),
15856
+ clamp(targetZoom, _camera.minZoom.y, _camera.maxZoom.y)
15857
+ );
15858
+ let x = offset2.left;
15859
+ let y = offset2.top;
15860
+ if (zw < zh) {
15861
+ y += (th - sh * newZoom) / 2;
15862
+ } else {
15863
+ x += (tw - sw * newZoom) / 2;
15864
+ }
15865
+ const oldPosition = {
15866
+ x: _camera.position.x,
15867
+ y: _camera.position.y
15868
+ };
15869
+ const newPosition = {
15870
+ x: sx * newZoom - x,
15871
+ y: sy * newZoom - y
15872
+ };
15873
+ switch (behavior) {
15874
+ case "smooth":
15875
+ await new Promise((resolve) => {
15876
+ const zoomDistance = newZoom - oldZoom;
15877
+ const positionDistance = {
15878
+ x: newPosition.x - oldPosition.x,
15879
+ y: newPosition.y - oldPosition.y
15880
+ };
15881
+ const startTime = performance.now();
15882
+ function step(now) {
15883
+ const elapsed = now - startTime;
15884
+ const progress = Math.min(elapsed / duration, 1);
15885
+ const ease = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress;
15886
+ _camera.zoom.set(oldZoom + zoomDistance * ease);
15887
+ _camera.position.set(
15888
+ oldPosition.x + positionDistance.x * ease,
15889
+ oldPosition.y + positionDistance.y * ease
15890
+ );
15891
+ if (elapsed < duration) {
15892
+ requestAnimationFrame(step);
15893
+ } else {
15894
+ resolve();
15895
+ }
15896
+ }
15897
+ requestAnimationFrame(step);
15898
+ });
15899
+ break;
15900
+ case "instant":
15901
+ default:
15902
+ _camera.zoom.set(newZoom);
15903
+ _camera.position.set(newPosition.x, newPosition.y);
15904
+ break;
15905
+ }
15906
+ }
15824
15907
  function zoomToFrame(type, options) {
15825
15908
  const value = findFrame(type);
15826
15909
  if (value) {
@@ -15833,7 +15916,8 @@ const _zoom = definePlugin((editor) => {
15833
15916
  commands: [
15834
15917
  { command: "zoomIn", handle: () => camera.value.addZoom(0.25) },
15835
15918
  { command: "zoomOut", handle: () => camera.value.addZoom(-0.25) },
15836
- { command: "zoomTo100", handle: () => camera.value.setZoom(1) },
15919
+ { command: "zoomTo", handle: zoomTo },
15920
+ { command: "zoomTo100", handle: () => zoomTo(1) },
15837
15921
  { command: "zoomToFit", handle: () => zoomTo("root", { mode: config.value.zoomToFit }) },
15838
15922
  { command: "zoomToSelection", handle: (options) => zoomTo("selection", options) },
15839
15923
  { command: "zoomToNextFrame", handle: (options) => zoomToFrame("next", options) },
@@ -15850,6 +15934,13 @@ const _zoom = definePlugin((editor) => {
15850
15934
  ],
15851
15935
  events: {
15852
15936
  setDoc: () => exec("zoomToFit")
15937
+ },
15938
+ setup: () => {
15939
+ watch(drawboardAabb, (_aabb, oldAabb) => {
15940
+ if (!oldAabb.width || !oldAabb.height) {
15941
+ exec("zoomToFit");
15942
+ }
15943
+ });
15853
15944
  }
15854
15945
  };
15855
15946
  });
@@ -15920,9 +16011,11 @@ class Editor extends Observable {
15920
16011
  this.emit = this.emit.bind(this);
15921
16012
  }
15922
16013
  getPlugins = (type) => {
15923
- return Array.from(this.plugins.values()).flatMap((p) => p.components?.filter((c) => {
15924
- return c.type === type && c.ignore?.() !== true;
15925
- }) ?? []);
16014
+ return Array.from(this.plugins.values()).flatMap((p) => {
16015
+ return p.components?.filter((c) => {
16016
+ return c.type === type && c.ignore?.() !== true;
16017
+ }) ?? [];
16018
+ });
15926
16019
  };
15927
16020
  log = (...args) => {
15928
16021
  if (this.debug.value) {
@@ -15942,7 +16035,7 @@ class Editor extends Observable {
15942
16035
  this.debug.value = debug;
15943
16036
  this.config = configCacheInLocal ? useLocalStorage("config", () => ({})) : ref({});
15944
16037
  this._setups = [];
15945
- this._useMixins(
16038
+ this.mixin(
15946
16039
  mixins,
15947
16040
  options
15948
16041
  );
@@ -15951,13 +16044,21 @@ class Editor extends Observable {
15951
16044
  ...plugins$1
15952
16045
  ], options);
15953
16046
  }
15954
- _useMixins(mixins2, options) {
15955
- const use = (mixin) => {
16047
+ mixin(mixin, options = {}) {
16048
+ if (Array.isArray(mixin)) {
16049
+ mixin.forEach((item) => {
16050
+ try {
16051
+ this.mixin(item, options);
16052
+ } catch (err) {
16053
+ console.error(`Failed to use mixin`, err);
16054
+ }
16055
+ });
16056
+ } else {
15956
16057
  const result = mixin(this, options);
15957
16058
  switch (typeof result) {
15958
16059
  case "object":
15959
16060
  if (Array.isArray(result)) {
15960
- result.map((v) => use(v));
16061
+ result.map((v) => this.mixin(v));
15961
16062
  } else {
15962
16063
  Object.assign(this, result);
15963
16064
  }
@@ -15969,11 +16070,18 @@ class Editor extends Observable {
15969
16070
  }
15970
16071
  break;
15971
16072
  }
15972
- };
15973
- mixins2.forEach(use);
16073
+ }
15974
16074
  }
15975
- use(plugins2, options) {
15976
- const use = (plugin) => {
16075
+ use(plugin, options) {
16076
+ if (Array.isArray(plugin)) {
16077
+ plugin.forEach((p) => {
16078
+ try {
16079
+ this.use(p, options);
16080
+ } catch (err) {
16081
+ console.error(`Failed to use plugin`, err);
16082
+ }
16083
+ });
16084
+ } else {
15977
16085
  let result;
15978
16086
  if (typeof plugin === "function") {
15979
16087
  result = plugin(this, options);
@@ -15999,19 +16107,13 @@ class Editor extends Observable {
15999
16107
  this.on(k, events[k]);
16000
16108
  }
16001
16109
  }
16002
- };
16003
- plugins2.forEach((p) => {
16004
- try {
16005
- use(p);
16006
- } catch (err) {
16007
- console.error(`Failed to use plugin`, err);
16008
- }
16009
- });
16110
+ }
16010
16111
  }
16011
- _setuped = false;
16112
+ _effectScope;
16012
16113
  setup = async () => {
16013
- if (!this._setuped) {
16014
- this._setuped = true;
16114
+ this._effectScope?.stop();
16115
+ const scope = effectScope();
16116
+ scope.run(async () => {
16015
16117
  await Promise.all([
16016
16118
  ...this._setups.map(async (setup) => {
16017
16119
  try {
@@ -16029,7 +16131,8 @@ class Editor extends Observable {
16029
16131
  })
16030
16132
  ]);
16031
16133
  this.emit("ready");
16032
- }
16134
+ });
16135
+ this._effectScope = scope;
16033
16136
  };
16034
16137
  install = (app) => {
16035
16138
  app.provide(Editor.injectionKey, this);
@@ -16261,11 +16364,11 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
16261
16364
  createVNode(_sfc_main$k, {
16262
16365
  modelValue: sourceTransform.value,
16263
16366
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => sourceTransform.value = $event),
16264
- class: "mce-cropper__transformable",
16367
+ class: "mce-cropper__transform",
16265
16368
  rotatable: false
16266
16369
  }, {
16267
16370
  default: withCtx(({ props: slotProps }) => [
16268
- createElementVNode("div", mergeProps({ class: "mce-cropper__transformable_rect" }, slotProps), null, 16)
16371
+ createElementVNode("div", mergeProps({ class: "mce-cropper__transform_rect" }, slotProps), null, 16)
16269
16372
  ]),
16270
16373
  _: 1
16271
16374
  }, 8, ["modelValue"]),
@@ -16323,7 +16426,6 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16323
16426
  selection,
16324
16427
  elementSelection,
16325
16428
  selectionObb,
16326
- selectionObbInDrawboard,
16327
16429
  camera,
16328
16430
  getObb,
16329
16431
  getAabb,
@@ -16378,15 +16480,8 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16378
16480
  });
16379
16481
  function snap(currentPos, type) {
16380
16482
  const points = getSnapPoints();
16381
- const zoom = camera.value.zoom;
16382
- const position = camera.value.position;
16383
16483
  let closest;
16384
16484
  let minDist = Infinity;
16385
- if (type === "x") {
16386
- currentPos += position.x / zoom.x;
16387
- } else {
16388
- currentPos += position.y / zoom.y;
16389
- }
16390
16485
  for (const pt of points[type]) {
16391
16486
  const dist = pt - currentPos;
16392
16487
  const absDist = Math.abs(dist);
@@ -16395,14 +16490,9 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16395
16490
  closest = pt;
16396
16491
  }
16397
16492
  }
16398
- if (minDist <= snapThreshold.value) {
16493
+ if (minDist < snapThreshold.value) {
16399
16494
  currentPos = closest ?? currentPos;
16400
16495
  }
16401
- if (type === "x") {
16402
- currentPos -= position.x / zoom.x;
16403
- } else {
16404
- currentPos -= position.y / zoom.y;
16405
- }
16406
16496
  return currentPos;
16407
16497
  }
16408
16498
  function createSelectionTransformContext() {
@@ -16440,42 +16530,32 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16440
16530
  emit("selectionTransformEnd", createSelectionTransformContext());
16441
16531
  }
16442
16532
  const _transform2 = computed(() => {
16443
- const zoom = camera.value.zoom;
16444
- const { left, top, width, height, rotationDegrees } = selectionObbInDrawboard.value;
16533
+ const { left, top, width, height, rotationDegrees } = selectionObb.value;
16445
16534
  return {
16446
16535
  left,
16447
16536
  top,
16448
16537
  width,
16449
16538
  height,
16450
16539
  rotate: rotationDegrees,
16451
- borderRadius: (elementSelection.value[0]?.style.borderRadius ?? 0) * zoom.x
16540
+ borderRadius: elementSelection.value[0]?.style.borderRadius ?? 0
16452
16541
  };
16453
16542
  });
16454
16543
  const transform = computed({
16455
16544
  get: () => _transform2.value,
16456
- set: (val) => {
16457
- const handle = transformable.value?.activeHandle ?? "move";
16458
- const zoom = camera.value.zoom;
16545
+ set: (transform2) => {
16459
16546
  const oldTransform = _transform2.value;
16460
- const transform2 = {
16461
- left: val.left / zoom.x,
16462
- top: val.top / zoom.y,
16463
- width: Math.max(1, val.width / zoom.x),
16464
- height: Math.max(1, val.height / zoom.y),
16465
- rotate: val.rotate ?? 0,
16466
- borderRadius: (val.borderRadius ?? 0) / zoom.y
16467
- };
16547
+ const handle = transformable.value?.activeHandle ?? "move";
16468
16548
  if (handle === "move") {
16469
16549
  transform2.left = snap(Math.round(transform2.left), "x");
16470
16550
  transform2.top = snap(Math.round(transform2.top), "y");
16471
16551
  }
16472
16552
  const offsetStyle = {
16473
- left: transform2.left - oldTransform.left / zoom.x,
16474
- top: transform2.top - oldTransform.top / zoom.y,
16475
- width: transform2.width - oldTransform.width / zoom.x,
16476
- height: transform2.height - oldTransform.height / zoom.y,
16477
- rotate: transform2.rotate - (oldTransform.rotate ?? 0),
16478
- borderRadius: transform2.borderRadius - (oldTransform.borderRadius ?? 0) / zoom.y
16553
+ left: transform2.left - oldTransform.left,
16554
+ top: transform2.top - oldTransform.top,
16555
+ width: transform2.width - oldTransform.width,
16556
+ height: transform2.height - oldTransform.height,
16557
+ rotate: transform2.rotate - oldTransform.rotate,
16558
+ borderRadius: transform2.borderRadius - oldTransform.borderRadius
16479
16559
  };
16480
16560
  const els = elementSelection.value;
16481
16561
  if (els.length > 1) {
@@ -16524,7 +16604,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16524
16604
  });
16525
16605
  }
16526
16606
  }
16527
- emit("selectionTransforming", createSelectionTransformContext());
16607
+ emit("selectionTransform", createSelectionTransformContext());
16528
16608
  }
16529
16609
  });
16530
16610
  const movable = computed(() => {
@@ -16599,6 +16679,8 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16599
16679
  "resize-strategy": props.resizeStrategy,
16600
16680
  class: "mce-selector__transform",
16601
16681
  "tip-format": tipFormat,
16682
+ scale: [unref(camera).zoom.x, unref(camera).zoom.y],
16683
+ offset: [-unref(camera).position.x, -unref(camera).position.y],
16602
16684
  onStart,
16603
16685
  onMove,
16604
16686
  onEnd
@@ -16610,7 +16692,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16610
16692
  ]),
16611
16693
  key: "0"
16612
16694
  } : void 0
16613
- ]), 1040, ["modelValue", "movable", "resizable", "rotatable", "roundable", "resize-strategy"])) : createCommentVNode("", true),
16695
+ ]), 1040, ["modelValue", "movable", "resizable", "rotatable", "roundable", "resize-strategy", "scale", "offset"])) : createCommentVNode("", true),
16614
16696
  transform.value.width && transform.value.height && _ctx.$slots.default ? (openBlock(), createElementBlock("div", {
16615
16697
  key: 3,
16616
16698
  class: "mce-selector__slot",