mce 0.15.20 → 0.15.21

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/README.md CHANGED
@@ -45,7 +45,6 @@ npm i mce
45
45
  svg(),
46
46
  ],
47
47
  theme: 'system',
48
- viewMode: 'edgeless',
49
48
  watermark: '/example.jpg',
50
49
  checkerboard: true,
51
50
  checkerboardStyle: 'grid',
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, onBeforeUnmount, defineComponent, createElementBlock, createCommentVNode, unref, openBlock, normalizeStyle as normalizeStyle$1, toDisplayString, createVNode, useAttrs, createBlock, resolveDynamicComponent, normalizeClass, mergeProps, createElementVNode, inject, toValue, getCurrentInstance, provide, useId, readonly, toRef, onMounted, onDeactivated, onActivated, onScopeDispose, useModel, useTemplateRef, withDirectives, withModifiers, vShow, vModelText, 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, warn, shallowRef, onBeforeUnmount, defineComponent, createElementBlock, createCommentVNode, unref, openBlock, normalizeStyle as normalizeStyle$1, toDisplayString, 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";
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";
@@ -113,7 +113,6 @@ const _0_config_base = defineMixin((editor, options) => {
113
113
  config
114
114
  } = editor;
115
115
  registerConfig("theme", "system");
116
- registerConfig("viewMode", "edgeless");
117
116
  registerConfig("watermark", void 0);
118
117
  registerConfig("msaa", false);
119
118
  registerConfig("checkerboard", false);
@@ -942,7 +941,7 @@ const _0_context = defineMixin((editor) => {
942
941
  function isFrame(value) {
943
942
  return isElement(value) && value.meta.inEditorIs === "Frame";
944
943
  }
945
- function isTopLevelFrame(value) {
944
+ function isTopFrame(value) {
946
945
  return isFrame(value) && Boolean(value.parent?.equal(root.value));
947
946
  }
948
947
  function isVisible(node) {
@@ -986,7 +985,7 @@ const _0_context = defineMixin((editor) => {
986
985
  isRoot,
987
986
  isElement,
988
987
  isFrame,
989
- isTopLevelFrame,
988
+ isTopFrame,
990
989
  isVisible,
991
990
  setVisible,
992
991
  isLock,
@@ -1123,8 +1122,8 @@ const en = {
1123
1122
  "selectAll": "Select all",
1124
1123
  "deselectAll": "Deselect all",
1125
1124
  "selectParent": "Select parent",
1126
- "previousSelection": "Previous selection",
1127
- "nextSelection": "Next selection",
1125
+ "selectPreviousSibling": "Select previous sibling",
1126
+ "selectNextSibling": "Select next sibling",
1128
1127
  "view": "View",
1129
1128
  "view:checkerboard": "Checkerboard",
1130
1129
  "view:pixelGrid": "Pixel grid",
@@ -1148,6 +1147,8 @@ const en = {
1148
1147
  "zoomTo100": "Zoom to 100%",
1149
1148
  "zoomToFit": "Zoom to fit",
1150
1149
  "zoomToSelection": "Zoom to selection",
1150
+ "zoomToNextFrame": "Zoom to next frame",
1151
+ "zoomToPreviousFrame": "Zoom to previous frame",
1151
1152
  "object": "Object",
1152
1153
  "groupSelection": "Group Selection",
1153
1154
  "frameSelection": "Frame selection",
@@ -1232,8 +1233,8 @@ const zhHans = {
1232
1233
  "selectAll": "选择全部",
1233
1234
  "deselectAll": "反选全部",
1234
1235
  "selectParent": "选择父元素",
1235
- "previousSelection": "选择前一个",
1236
- "nextSelection": "选择后一个",
1236
+ "selectPreviousSibling": "选择前一个",
1237
+ "selectNextSibling": "选择后一个",
1237
1238
  "view": "视图",
1238
1239
  "view:checkerboard": "棋盘",
1239
1240
  "view:pixelGrid": "像素网格",
@@ -1257,6 +1258,8 @@ const zhHans = {
1257
1258
  "zoomTo100": "缩放到100%",
1258
1259
  "zoomToFit": "缩放到合适",
1259
1260
  "zoomToSelection": "缩放到选区",
1261
+ "zoomToNextFrame": "缩放到下个画板",
1262
+ "zoomToPreviousFrame": "缩放到上个画板",
1260
1263
  "object": "对象",
1261
1264
  "groupSelection": "组合选区",
1262
1265
  "frameSelection": "组合选区为画板",
@@ -1317,39 +1320,20 @@ const _0_locale = defineMixin((editor, options) => {
1317
1320
  const _1_frame = defineMixin((editor) => {
1318
1321
  const {
1319
1322
  root,
1320
- isFrame
1323
+ isFrame,
1324
+ isTopFrame
1321
1325
  } = editor;
1322
1326
  const frames = computed(() => root.value.children.filter(isFrame) ?? []);
1323
- const currentFrameIndex = ref(-1);
1324
- const currentFrame = computed(() => frames.value[currentFrameIndex.value]);
1325
- const currentFrameAabb = computed(() => {
1326
- const { left = 0, top = 0, width = 0, height = 0 } = currentFrame.value?.style ?? {};
1327
- return { left, top, width, height };
1328
- });
1329
1327
  const frameThumbs = ref([]);
1330
- function getAncestorFrame(node) {
1331
- return node?.findAncestor((node2) => isFrame(node2));
1328
+ function getAncestorFrame(node, isTop) {
1329
+ const when = isTop ? isTopFrame : isFrame;
1330
+ return node?.findAncestor((node2) => when(node2));
1332
1331
  }
1333
1332
  Object.assign(editor, {
1334
1333
  frames,
1335
1334
  frameThumbs,
1336
- currentFrameIndex,
1337
- currentFrame,
1338
- currentFrameAabb,
1339
1335
  getAncestorFrame
1340
1336
  });
1341
- return () => {
1342
- const {
1343
- selection
1344
- } = editor;
1345
- watch(() => {
1346
- return selection.value.length === 1 && selection.value[0];
1347
- }, (node) => {
1348
- if (node && isFrame(node)) {
1349
- currentFrameIndex.value = frames.value.findIndex((v) => v.equal(node));
1350
- }
1351
- });
1352
- };
1353
1337
  });
1354
1338
  function boundingBoxToStyle(box) {
1355
1339
  const style = {
@@ -1460,6 +1444,8 @@ async function createImageElement(image) {
1460
1444
  }
1461
1445
  };
1462
1446
  }
1447
+ function noop(..._args) {
1448
+ }
1463
1449
  function isClickInsideElement(event, targetDiv) {
1464
1450
  const mouseX = event.clientX;
1465
1451
  const mouseY = event.clientY;
@@ -1832,15 +1818,14 @@ const _1_upload = defineMixin((editor, options) => {
1832
1818
  upload
1833
1819
  });
1834
1820
  });
1835
- function noop(..._args) {
1836
- }
1837
1821
  const _2_box = defineMixin((editor) => {
1838
1822
  const {
1839
1823
  isElement,
1840
1824
  camera,
1841
1825
  root,
1842
1826
  selection,
1843
- getAncestorFrame
1827
+ getAncestorFrame,
1828
+ drawboardAabb
1844
1829
  } = editor;
1845
1830
  function obbToFit(element) {
1846
1831
  const min = {
@@ -1913,7 +1898,7 @@ const _2_box = defineMixin((editor) => {
1913
1898
  }
1914
1899
  } else if (isElement(node)) {
1915
1900
  const style = node.style;
1916
- noop([style.left, style.top, style.width, style.height, style.rotate]);
1901
+ noop(style.left, style.top, style.width, style.height, style.rotate);
1917
1902
  obb = node.getGlobalObb();
1918
1903
  } else {
1919
1904
  obb = new Obb2D();
@@ -2022,6 +2007,23 @@ const _2_box = defineMixin((editor) => {
2022
2007
  _aabb.top -= position.y;
2023
2008
  return _aabb;
2024
2009
  }
2010
+ const viewportAabb = computed(() => {
2011
+ noop(
2012
+ camera.value.position.x,
2013
+ camera.value.position.y,
2014
+ camera.value.zoom.x,
2015
+ camera.value.zoom.y
2016
+ );
2017
+ const { width, height } = drawboardAabb.value;
2018
+ const p1 = camera.value.toGlobal({ x: 0, y: 0 });
2019
+ const p2 = camera.value.toGlobal({ x: width, y: height });
2020
+ return new Aabb2D({
2021
+ x: p1.x,
2022
+ y: p1.y,
2023
+ width: p2.x,
2024
+ height: p2.y
2025
+ });
2026
+ });
2025
2027
  const rootAabb = computed(() => getAabb(root.value.children));
2026
2028
  const selectionAabb = computed(() => getAabb(selection.value));
2027
2029
  const selectionAabbInDrawboard = computed(() => getAabb(selection.value, "drawboard"));
@@ -2032,6 +2034,7 @@ const _2_box = defineMixin((editor) => {
2032
2034
  getObb,
2033
2035
  getAabb,
2034
2036
  aabbToDrawboardAabb,
2037
+ viewportAabb,
2035
2038
  rootAabb,
2036
2039
  selectionAabb,
2037
2040
  selectionAabbInDrawboard,
@@ -2161,14 +2164,8 @@ const _2_load = defineMixin((editor) => {
2161
2164
  });
2162
2165
  const _3_view = defineMixin((editor) => {
2163
2166
  const {
2164
- renderEngine,
2165
- rootAabb,
2166
- currentFrameAabb,
2167
- config
2167
+ renderEngine
2168
2168
  } = editor;
2169
- const viewAabb = computed(() => {
2170
- return config.value.viewMode === "frame" ? currentFrameAabb.value : rootAabb.value;
2171
- });
2172
2169
  function bindRenderCanvas(canvas, eventTarget) {
2173
2170
  function onRendered() {
2174
2171
  const target = renderEngine.value.view;
@@ -2198,46 +2195,38 @@ const _3_view = defineMixin((editor) => {
2198
2195
  return unbind;
2199
2196
  }
2200
2197
  Object.assign(editor, {
2201
- viewAabb,
2202
2198
  bindRenderCanvas
2203
2199
  });
2204
- return () => {
2205
- const {
2206
- isElement,
2207
- root,
2208
- currentFrame,
2209
- on,
2210
- exec
2211
- } = editor;
2212
- function onViewMode() {
2213
- switch (config.value.viewMode) {
2214
- case "frame":
2215
- root.value.children.forEach((child) => {
2216
- if (isElement(child)) {
2217
- child.visible = child.equal(currentFrame.value);
2218
- }
2219
- });
2220
- break;
2221
- case "edgeless":
2222
- root.value.children.forEach((child) => {
2223
- if (isElement(child)) {
2224
- child.visible = true;
2225
- }
2226
- });
2227
- break;
2228
- }
2229
- exec("zoomToFit");
2230
- }
2231
- watch(() => config.value.viewMode, onViewMode);
2232
- on("setCurrentFrame", onViewMode);
2233
- on("setDoc", onViewMode);
2234
- };
2235
2200
  });
2236
2201
  const _4_0_node = defineMixin((editor) => {
2237
2202
  const {
2238
2203
  doc,
2239
2204
  selection
2240
2205
  } = editor;
2206
+ function findSibling(target) {
2207
+ const node = selection.value[0];
2208
+ if (node) {
2209
+ let value;
2210
+ switch (target) {
2211
+ case "previous":
2212
+ value = node.nextSibling;
2213
+ if (!value && node.parent) {
2214
+ value = node.parent.children[0];
2215
+ }
2216
+ break;
2217
+ case "next":
2218
+ value = node.previousSibling;
2219
+ if (!value && node.parent) {
2220
+ value = node.parent.children[node.parent.children.length - 1];
2221
+ }
2222
+ break;
2223
+ }
2224
+ if (value && !node.equal(value)) {
2225
+ return value;
2226
+ }
2227
+ }
2228
+ return void 0;
2229
+ }
2241
2230
  function addNode(value, options = {}) {
2242
2231
  const {
2243
2232
  parent,
@@ -2256,6 +2245,7 @@ const _4_0_node = defineMixin((editor) => {
2256
2245
  return node;
2257
2246
  }
2258
2247
  Object.assign(editor, {
2248
+ findSibling,
2259
2249
  addNode
2260
2250
  });
2261
2251
  });
@@ -2402,7 +2392,7 @@ class TextEditor extends HTMLElement {
2402
2392
  </style>
2403
2393
 
2404
2394
  <div class="container">
2405
- <textarea></textarea>
2395
+ <textarea name="text-content"></textarea>
2406
2396
  <div class="selection"></div>
2407
2397
  <div class="cursor blink"></div>
2408
2398
  </div>
@@ -2723,18 +2713,18 @@ class TextEditor extends HTMLElement {
2723
2713
  } else {
2724
2714
  const { selectionStart, selectionEnd } = this._textarea;
2725
2715
  let count2 = 0;
2726
- const _selection = [-1, -1];
2716
+ const _selection2 = [-1, -1];
2727
2717
  this._chars.forEach((char, index) => {
2728
2718
  if (count2 <= selectionStart) {
2729
- _selection[0] = index;
2719
+ _selection2[0] = index;
2730
2720
  }
2731
2721
  if (count2 <= selectionEnd) {
2732
- _selection[1] = index;
2722
+ _selection2[1] = index;
2733
2723
  }
2734
2724
  count2 += char.content.length;
2735
2725
  });
2736
2726
  const oldSelection = this.selection;
2737
- this.selection = _selection;
2727
+ this.selection = _selection2;
2738
2728
  this._prevSelection = oldSelection;
2739
2729
  }
2740
2730
  }
@@ -3315,27 +3305,39 @@ const _4_1_text = defineMixin((editor) => {
3315
3305
  const _4_2_frame = defineMixin((editor) => {
3316
3306
  const {
3317
3307
  root,
3318
- currentFrameIndex,
3319
- emit,
3320
- selection,
3321
3308
  frames,
3322
- config,
3323
- isTopLevelFrame
3309
+ isTopFrame,
3310
+ exec,
3311
+ selection,
3312
+ getAncestorFrame
3324
3313
  } = editor;
3325
- function setCurrentFrame(index = currentFrameIndex.value) {
3326
- index = Math.max(0, Math.min(frames.value.length - 1, index));
3327
- const oldIndex = currentFrameIndex.value;
3328
- currentFrameIndex.value = index;
3329
- if (config.value.viewMode === "edgeless") {
3330
- selection.value = [frames.value[index]];
3331
- } else {
3332
- selection.value = [];
3314
+ function findFrame(target) {
3315
+ let current;
3316
+ const node = selection.value[0];
3317
+ if (node) {
3318
+ current = isTopFrame(node) ? node : getAncestorFrame(node, true);
3319
+ }
3320
+ const last = frames.value.length - 1;
3321
+ let index = frames.value.findIndex((node2) => node2.equal(current));
3322
+ switch (target) {
3323
+ case "next":
3324
+ index--;
3325
+ if (index < 0) {
3326
+ index = last;
3327
+ }
3328
+ break;
3329
+ case "previous":
3330
+ index++;
3331
+ if (index > last) {
3332
+ index = 0;
3333
+ }
3334
+ break;
3333
3335
  }
3334
- emit("setCurrentFrame", index, oldIndex);
3336
+ return frames.value[index];
3335
3337
  }
3336
- function handleElementInsideFrame(element, context) {
3337
- const pointer = context?.pointer;
3338
- const frame1 = element.findAncestor((node) => isTopLevelFrame(node));
3338
+ function handleDragOutReparent(element, options) {
3339
+ const pointer = options?.pointer;
3340
+ const frame1 = element.findAncestor((node) => isTopFrame(node));
3339
3341
  const aabb1 = element.getGlobalAabb();
3340
3342
  const area1 = aabb1.getArea();
3341
3343
  let flag = true;
@@ -3346,15 +3348,16 @@ const _4_2_frame = defineMixin((editor) => {
3346
3348
  }
3347
3349
  const aabb2 = frame2.getGlobalAabb();
3348
3350
  if (aabb2) {
3349
- if (pointer && aabb2.containsPoint(pointer) || aabb1 && aabb1.getIntersectionRect(aabb2).getArea() > area1 * 0.5) {
3351
+ if (pointer ? aabb2.contains(pointer) : aabb1 && aabb1.getIntersectionRect(aabb2).getArea() > area1 * 0.5) {
3350
3352
  if (!frame2.equal(frame1)) {
3351
3353
  let index = frame2.children.length;
3352
- if (frame2.equal(context?.parent)) {
3353
- index = context.index;
3354
+ if (frame2.equal(options?.parent)) {
3355
+ index = options.index;
3354
3356
  }
3355
- frame2.moveChild(element, index);
3356
3357
  element.style.left = aabb1.x - aabb2.x;
3357
3358
  element.style.top = aabb1.y - aabb2.y;
3359
+ frame2.moveChild(element, index);
3360
+ exec("layerScrollIntoView");
3358
3361
  }
3359
3362
  flag = false;
3360
3363
  break;
@@ -3362,14 +3365,19 @@ const _4_2_frame = defineMixin((editor) => {
3362
3365
  }
3363
3366
  }
3364
3367
  if (flag && frame1) {
3365
- root.value.moveChild(element, root.value.children.length);
3366
3368
  element.style.left = aabb1.x;
3367
3369
  element.style.top = aabb1.y;
3370
+ let index = root.value.children.length;
3371
+ if (root.value.equal(options?.parent)) {
3372
+ index = options.index;
3373
+ }
3374
+ root.value.moveChild(element, index);
3375
+ exec("layerScrollIntoView");
3368
3376
  }
3369
3377
  }
3370
3378
  Object.assign(editor, {
3371
- setCurrentFrame,
3372
- handleElementInsideFrame
3379
+ findFrame,
3380
+ handleDragOutReparent
3373
3381
  });
3374
3382
  });
3375
3383
  const _4_3_element = defineMixin((editor) => {
@@ -3391,7 +3399,7 @@ const _4_3_element = defineMixin((editor) => {
3391
3399
  selection,
3392
3400
  camera,
3393
3401
  parseAnchor,
3394
- handleElementInsideFrame
3402
+ handleDragOutReparent
3395
3403
  } = editor;
3396
3404
  function addElement(value, options = {}) {
3397
3405
  log("addElement", value, options);
@@ -3534,13 +3542,12 @@ const _4_3_element = defineMixin((editor) => {
3534
3542
  });
3535
3543
  } else if (globalPosition) {
3536
3544
  elements2.forEach((el) => {
3537
- el.style.left = Math.round(
3545
+ el.style.left += Math.round(
3538
3546
  parentAabb ? parentAabb.left - globalPosition.x : globalPosition.x
3539
3547
  );
3540
- el.style.top = Math.round(
3548
+ el.style.top += Math.round(
3541
3549
  parentAabb ? parentAabb.top - globalPosition.y : globalPosition.y
3542
3550
  );
3543
- globalPosition.x += el.style.width + frameGap;
3544
3551
  });
3545
3552
  }
3546
3553
  return elements2;
@@ -3550,7 +3557,7 @@ const _4_3_element = defineMixin((editor) => {
3550
3557
  selection.value = elements;
3551
3558
  }
3552
3559
  if (!isArray && !parent) {
3553
- handleElementInsideFrame(elements[0]);
3560
+ handleDragOutReparent(elements[0]);
3554
3561
  }
3555
3562
  return isArray ? elements : elements[0];
3556
3563
  }
@@ -3585,7 +3592,7 @@ const _4_3_element = defineMixin((editor) => {
3585
3592
  }
3586
3593
  return [node];
3587
3594
  }).filter((node) => {
3588
- return "isVisibleInTree" in node && node.isVisibleInTree() && getObb(node, "drawboard").overlapsOnAxis(area2) && !isLock(node) && !node.findAncestor((ancestor) => isLock(ancestor));
3595
+ return "isVisibleInTree" in node && node.isVisibleInTree() && getObb(node, "drawboard").overlap(area2) && !isLock(node) && !node.findAncestor((ancestor) => isLock(ancestor));
3589
3596
  }) ?? [];
3590
3597
  selection.value = selected;
3591
3598
  return selected;
@@ -3750,11 +3757,13 @@ const _scroll$1 = defineMixin((editor) => {
3750
3757
  camera,
3751
3758
  getAabb,
3752
3759
  selectionAabb,
3753
- viewAabb,
3760
+ rootAabb,
3761
+ viewportAabb,
3754
3762
  screenCenter
3755
3763
  } = editor;
3756
3764
  const scrollTo = async (target, options = {}) => {
3757
3765
  const {
3766
+ intoView,
3758
3767
  behavior,
3759
3768
  duration = 500
3760
3769
  } = options;
@@ -3776,10 +3785,13 @@ const _scroll$1 = defineMixin((editor) => {
3776
3785
  break;
3777
3786
  case "root":
3778
3787
  default:
3779
- aabb = viewAabb.value;
3788
+ aabb = rootAabb.value;
3780
3789
  break;
3781
3790
  }
3782
3791
  }
3792
+ if (intoView && viewportAabb.value.contains(aabb)) {
3793
+ return;
3794
+ }
3783
3795
  position = { x: aabb.left + aabb.width / 2, y: aabb.top + aabb.height / 2 };
3784
3796
  offset2.x += -_screenCenter.x;
3785
3797
  offset2.y = -_screenCenter.y;
@@ -3827,10 +3839,7 @@ const _scroll$1 = defineMixin((editor) => {
3827
3839
  const _snapshot = defineMixin((editor) => {
3828
3840
  const {
3829
3841
  isElement,
3830
- renderEngine,
3831
3842
  frames,
3832
- currentFrameAabb,
3833
- camera,
3834
3843
  frameThumbs,
3835
3844
  log,
3836
3845
  fonts,
@@ -3879,39 +3888,10 @@ const _snapshot = defineMixin((editor) => {
3879
3888
  log("captureFrameScreenshot", index);
3880
3889
  }
3881
3890
  }
3882
- function renderFrameThumb(target) {
3883
- const view = renderEngine.value.view;
3884
- const aabb = currentFrameAabb.value;
3885
- const pixelRatio = renderEngine.value.pixelRatio ?? 1;
3886
- if (!view)
3887
- return;
3888
- const ctx = target.getContext("2d");
3889
- if (!ctx)
3890
- return;
3891
- ctx.fillStyle = "rgba(0, 0, 0, 0)";
3892
- ctx.clearRect(0, 0, target.width, target.height);
3893
- const { zoom, position } = camera.value;
3894
- target.width = aabb.width;
3895
- target.height = aabb.height;
3896
- const sw = aabb.width * zoom.x;
3897
- const sh = aabb.height * zoom.y;
3898
- ctx.drawImage(
3899
- view,
3900
- (aabb.left * zoom.x - position.x) * pixelRatio,
3901
- (aabb.top * zoom.x - position.y) * pixelRatio,
3902
- sw * pixelRatio,
3903
- sh * pixelRatio,
3904
- 0,
3905
- 0,
3906
- target.width,
3907
- target.height
3908
- );
3909
- }
3910
3891
  Object.assign(editor, {
3911
3892
  snapshot,
3912
3893
  captureElementScreenshot,
3913
- captureFrameScreenshot,
3914
- renderFrameThumb
3894
+ captureFrameScreenshot
3915
3895
  });
3916
3896
  return () => {
3917
3897
  const {
@@ -3946,11 +3926,6 @@ const _snapshot = defineMixin((editor) => {
3946
3926
  doc.root.on("addChild", onAddChild);
3947
3927
  doc.root.on("removeChild", onRemoveChild);
3948
3928
  });
3949
- on("setCurrentFrame", (_index, oldIndex) => {
3950
- if (config.value.frameScreenshot) {
3951
- captureFrameScreenshot(oldIndex);
3952
- }
3953
- });
3954
3929
  };
3955
3930
  });
3956
3931
  const _zoom$1 = defineMixin((editor) => {
@@ -3958,18 +3933,20 @@ const _zoom$1 = defineMixin((editor) => {
3958
3933
  camera,
3959
3934
  drawboardAabb,
3960
3935
  selectionAabb,
3961
- viewAabb,
3936
+ rootAabb,
3962
3937
  getAabb,
3963
- screenCenterOffset
3938
+ screenCenterOffset,
3939
+ viewportAabb
3964
3940
  } = editor;
3965
3941
  const zoomTo = async (target, options = {}) => {
3966
3942
  const {
3943
+ intoView,
3967
3944
  mode = "contain",
3968
3945
  duration = 500,
3969
3946
  behavior
3970
3947
  } = options;
3971
3948
  let aabb;
3972
- if (Array.isArray(target)) {
3949
+ if (Array.isArray(target) || typeof target === "object") {
3973
3950
  aabb = getAabb(target);
3974
3951
  } else {
3975
3952
  switch (target) {
@@ -3978,10 +3955,13 @@ const _zoom$1 = defineMixin((editor) => {
3978
3955
  break;
3979
3956
  case "root":
3980
3957
  default:
3981
- aabb = viewAabb.value;
3958
+ aabb = rootAabb.value;
3982
3959
  break;
3983
3960
  }
3984
3961
  }
3962
+ if (intoView && viewportAabb.value.contains(aabb)) {
3963
+ return;
3964
+ }
3985
3965
  const offset2 = screenCenterOffset.value;
3986
3966
  const { width, height } = drawboardAabb.value;
3987
3967
  const tw = width - (offset2.left + offset2.right);
@@ -5187,8 +5167,8 @@ const _sfc_main$B = /* @__PURE__ */ defineComponent({
5187
5167
  const editing = ref(false);
5188
5168
  async function onDblclick() {
5189
5169
  editing.value = true;
5170
+ await nextTick();
5190
5171
  if (input.value) {
5191
- await nextTick();
5192
5172
  input.value.focus();
5193
5173
  input.value.select();
5194
5174
  }
@@ -5221,14 +5201,15 @@ const _sfc_main$B = /* @__PURE__ */ defineComponent({
5221
5201
  onPointerleave: _cache[3] || (_cache[3] = ($event) => !unref(state) && !unref(isLock)(frame.value) && (hoverElement.value = void 0))
5222
5202
  }, [
5223
5203
  createElementVNode("div", null, toDisplayString(frame.value.name), 1),
5224
- withDirectives(createElementVNode("input", {
5204
+ editing.value ? withDirectives((openBlock(), createElementBlock("input", {
5205
+ key: 0,
5225
5206
  ref: "inputTpl",
5226
5207
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => frame.value.name = $event),
5208
+ name: "frame-name",
5227
5209
  onBlur: _cache[1] || (_cache[1] = ($event) => editing.value = false)
5228
- }, null, 544), [
5229
- [vShow, editing.value],
5210
+ }, null, 544)), [
5230
5211
  [vModelText, frame.value.name]
5231
- ])
5212
+ ]) : createCommentVNode("", true)
5232
5213
  ], 32)
5233
5214
  ], 6)), [
5234
5215
  [vShow, frame.value.visible]
@@ -5625,8 +5606,16 @@ const _import = definePlugin((editor) => {
5625
5606
  } = editor;
5626
5607
  const _import2 = async (options = {}) => {
5627
5608
  const files = await openFileDialog({ multiple: true });
5628
- return addElements((await Promise.all(files.map((file) => load(file)))).flat(), {
5629
- sizeToFit: true,
5609
+ return addElements((await Promise.all(files.map(async (file) => {
5610
+ const items = await load(file);
5611
+ return items.flatMap((item) => {
5612
+ if (item.meta?.inEditorIs === "Doc" && item.children) {
5613
+ return item.children;
5614
+ }
5615
+ return [item];
5616
+ });
5617
+ }))).flat(), {
5618
+ position: "right",
5630
5619
  ...options
5631
5620
  });
5632
5621
  };
@@ -6043,20 +6032,20 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6043
6032
  }
6044
6033
  });
6045
6034
  if (min !== void 0 && max !== void 0) {
6046
- let _selection = nodes.value.slice(min, max + 1);
6047
- const result = new Set(_selection.map((node) => node.id));
6035
+ let _selection2 = nodes.value.slice(min, max + 1);
6036
+ const result = new Set(_selection2.map((node) => node.id));
6048
6037
  const parents = /* @__PURE__ */ new Set();
6049
- _selection.forEach((node) => node.parent && parents.add(node.parent));
6038
+ _selection2.forEach((node) => node.parent && parents.add(node.parent));
6050
6039
  parents.forEach((parent) => {
6051
6040
  if (parent.children.every((ch) => result.has(ch.id))) {
6052
6041
  const ids = new Set(parent.children.map((ch) => ch.id));
6053
- _selection = [
6054
- ..._selection.filter((v) => !ids.has(v.id)),
6042
+ _selection2 = [
6043
+ ..._selection2.filter((v) => !ids.has(v.id)),
6055
6044
  parent
6056
6045
  ];
6057
6046
  }
6058
6047
  });
6059
- selection.value = _selection;
6048
+ selection.value = _selection2;
6060
6049
  }
6061
6050
  } else if (e.ctrlKey || e.metaKey) {
6062
6051
  const filtered = selection.value.filter((v) => !v.equal(props.node));
@@ -6159,10 +6148,12 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6159
6148
  class: "mce-layer__name",
6160
6149
  onDblclick: onDblclickName
6161
6150
  }, [
6162
- withDirectives(createElementVNode("input", {
6151
+ editing.value ? withDirectives((openBlock(), createElementBlock("input", {
6152
+ key: 0,
6163
6153
  ref_key: "inputDom",
6164
6154
  ref: inputDom,
6165
6155
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => editValue.value = $event),
6156
+ name: "layer-name",
6166
6157
  type: "text",
6167
6158
  class: "mce-layer__input",
6168
6159
  spellcheck: "false",
@@ -6170,10 +6161,9 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6170
6161
  autocorrect: "off",
6171
6162
  autofocus: "",
6172
6163
  onBlur: onInputBlur
6173
- }, null, 544), [
6174
- [vShow, editing.value],
6164
+ }, null, 544)), [
6175
6165
  [vModelText, editValue.value]
6176
- ]),
6166
+ ]) : createCommentVNode("", true),
6177
6167
  createElementVNode("div", {
6178
6168
  style: normalizeStyle$1({ visibility: editing.value ? "hidden" : void 0 })
6179
6169
  }, toDisplayString(editValue.value || thumbnailName.value), 5)
@@ -6237,7 +6227,8 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
6237
6227
  const {
6238
6228
  root,
6239
6229
  selection,
6240
- state
6230
+ state,
6231
+ registerCommand
6241
6232
  } = useEditor();
6242
6233
  const {
6243
6234
  selecting,
@@ -6245,12 +6236,10 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
6245
6236
  domItems,
6246
6237
  getIdByNode
6247
6238
  } = createLayer();
6248
- watch(selection, (selection2) => {
6249
- if (state.value === "selecting" || selecting.value) {
6250
- return;
6251
- }
6239
+ registerCommand({ command: "layerScrollIntoView", handle: layerScrollIntoView });
6240
+ function layerScrollIntoView() {
6252
6241
  let last;
6253
- selection2.forEach((node) => {
6242
+ selection.value.forEach((node) => {
6254
6243
  node.findAncestor((ancestor) => {
6255
6244
  const opened = openedItems.get(getIdByNode(ancestor) ?? "");
6256
6245
  if (opened) {
@@ -6268,6 +6257,12 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
6268
6257
  });
6269
6258
  });
6270
6259
  }
6260
+ }
6261
+ watch(selection, () => {
6262
+ if (state.value === "selecting" || selecting.value) {
6263
+ return;
6264
+ }
6265
+ layerScrollIntoView();
6271
6266
  });
6272
6267
  return (_ctx, _cache) => {
6273
6268
  return openBlock(), createElementBlock("div", _hoisted_1$k, [
@@ -6833,8 +6828,8 @@ const _menu = definePlugin((editor, options) => {
6833
6828
  { key: "selectAll" },
6834
6829
  { key: "deselectAll", disabled: !hasSelected.value },
6835
6830
  { key: "selectParent", disabled: !hasSelected.value },
6836
- { key: "previousSelection", disabled: !hasSelected.value },
6837
- { key: "nextSelection", disabled: !hasSelected.value }
6831
+ { key: "selectPreviousSibling", disabled: !hasSelected.value },
6832
+ { key: "selectNextSibling", disabled: !hasSelected.value }
6838
6833
  ]
6839
6834
  }));
6840
6835
  const editMenu = computed(() => ({
@@ -6854,7 +6849,9 @@ const _menu = definePlugin((editor, options) => {
6854
6849
  { key: "zoomOut" },
6855
6850
  { key: "zoomTo100" },
6856
6851
  { key: "zoomToFit" },
6857
- { key: "zoomToSelection", disabled: !hasSelected.value }
6852
+ { key: "zoomToSelection", disabled: !hasSelected.value },
6853
+ { key: "zoomToNextFrame", disabled: !hasSelected.value },
6854
+ { key: "zoomToPreviousFrame", disabled: !hasSelected.value }
6858
6855
  ]
6859
6856
  }));
6860
6857
  const panelsMenu = computed(() => ({
@@ -11937,7 +11934,7 @@ const _sfc_main$m = /* @__PURE__ */ defineComponent({
11937
11934
  const props = __props;
11938
11935
  const {
11939
11936
  camera,
11940
- viewAabb
11937
+ rootAabb
11941
11938
  } = useEditor();
11942
11939
  return (_ctx, _cache) => {
11943
11940
  return openBlock(), createElementBlock(Fragment, null, [
@@ -11945,12 +11942,12 @@ const _sfc_main$m = /* @__PURE__ */ defineComponent({
11945
11942
  modelValue: unref(camera).position.y,
11946
11943
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(camera).position.y = $event),
11947
11944
  vertical: "",
11948
- length: unref(viewAabb).height * unref(camera).zoom.y
11945
+ length: unref(rootAabb).height * unref(camera).zoom.y
11949
11946
  }), null, 16, ["modelValue", "length"]),
11950
11947
  createVNode(_sfc_main$n, mergeProps(props, {
11951
11948
  modelValue: unref(camera).position.x,
11952
11949
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => unref(camera).position.x = $event),
11953
- length: unref(viewAabb).width * unref(camera).zoom.x
11950
+ length: unref(rootAabb).width * unref(camera).zoom.x
11954
11951
  }), null, 16, ["modelValue", "length"])
11955
11952
  ], 64);
11956
11953
  };
@@ -11982,16 +11979,11 @@ const _sfc_main$l = /* @__PURE__ */ defineComponent({
11982
11979
  setup(__props) {
11983
11980
  const {
11984
11981
  selectionAabb,
11985
- drawboardAabb,
11986
- aabbToDrawboardAabb,
11982
+ viewportAabb,
11987
11983
  t,
11988
11984
  exec
11989
11985
  } = useEditor();
11990
- const isActive = computed(() => {
11991
- return selectionAabb.value.width && selectionAabb.value.height && !drawboardAabb.value.overlapsOnAxis(
11992
- aabbToDrawboardAabb(selectionAabb.value)
11993
- );
11994
- });
11986
+ const isActive = computed(() => !viewportAabb.value.overlap(selectionAabb.value));
11995
11987
  return (_ctx, _cache) => {
11996
11988
  return isActive.value ? (openBlock(), createElementBlock("div", {
11997
11989
  key: 0,
@@ -12004,11 +11996,13 @@ const _sfc_main$l = /* @__PURE__ */ defineComponent({
12004
11996
  };
12005
11997
  }
12006
11998
  });
12007
- const _select = definePlugin((editor) => {
11999
+ const _selection = definePlugin((editor) => {
12008
12000
  const {
12009
12001
  isElement,
12010
12002
  selection,
12011
- root
12003
+ root,
12004
+ scrollTo,
12005
+ findSibling
12012
12006
  } = editor;
12013
12007
  function selectAll() {
12014
12008
  selection.value = [...root.value.children];
@@ -12022,39 +12016,30 @@ const _select = definePlugin((editor) => {
12022
12016
  selection.value = [parent];
12023
12017
  }
12024
12018
  }
12025
- function previousSelection() {
12026
- const node = selection.value[0];
12027
- if (node) {
12028
- const previousSibling = node.previousSibling;
12029
- if (previousSibling && !node.equal(previousSibling)) {
12030
- selection.value = [previousSibling];
12031
- }
12032
- }
12033
- }
12034
- function nextSelection() {
12035
- const node = selection.value[0];
12036
- if (node) {
12037
- const nextSibling = node.nextSibling;
12038
- if (nextSibling && node.equal(nextSibling)) {
12039
- selection.value = [nextSibling];
12040
- }
12019
+ function selectSibling(type) {
12020
+ const value = findSibling(type);
12021
+ if (value) {
12022
+ selection.value = [value];
12023
+ scrollTo("selection", {
12024
+ intoView: true
12025
+ });
12041
12026
  }
12042
12027
  }
12043
12028
  return {
12044
- name: "mce:select",
12029
+ name: "mce:selection",
12045
12030
  commands: [
12046
12031
  { command: "selectAll", handle: selectAll },
12047
12032
  { command: "deselectAll", handle: deselectAll },
12048
12033
  { command: "selectParent", handle: selectParent },
12049
- { command: "previousSelection", handle: previousSelection },
12050
- { command: "nextSelection", handle: nextSelection }
12034
+ { command: "selectPreviousSibling", handle: () => selectSibling("previous") },
12035
+ { command: "selectNextSibling", handle: () => selectSibling("next") }
12051
12036
  ],
12052
12037
  hotkeys: [
12053
12038
  { command: "selectAll", key: "CmdOrCtrl+a" },
12054
12039
  { command: "deselectAll", key: "Shift+CmdOrCtrl+a" },
12055
12040
  { command: "selectParent", key: "Alt+\\" },
12056
- { command: "previousSelection", key: "Alt+[" },
12057
- { command: "nextSelection", key: "Alt+]" }
12041
+ { command: "selectPreviousSibling", key: "Shift+Tab" },
12042
+ { command: "selectNextSibling", key: "Tab" }
12058
12043
  ],
12059
12044
  components: [
12060
12045
  { type: "overlay", component: _sfc_main$l }
@@ -13256,8 +13241,8 @@ const _smartGuides = definePlugin((editor) => {
13256
13241
  return line.box?.id === -1;
13257
13242
  }
13258
13243
  function findLines(targets, source) {
13259
- const axis = ["vt", "vb"].includes(source.type) ? "vertical" : "horizontal";
13260
- const flippedAxis = axis === "vertical" ? "horizontal" : "vertical";
13244
+ const axis = ["vt", "vb"].includes(source.type) ? "y" : "x";
13245
+ const flippedAxis = axis === "y" ? "x" : "y";
13261
13246
  const isLeftTop = isLeftTopLine(source);
13262
13247
  let type = flipType(source.type);
13263
13248
  if (parentBox.value) {
@@ -13284,9 +13269,9 @@ const _smartGuides = definePlugin((editor) => {
13284
13269
  const isCanvas = isCanvasLine(target);
13285
13270
  if (type !== target.type && !isCanvas)
13286
13271
  return;
13287
- if (!toBoundingBox(source).overlapsOnAxis(toBoundingBox(target), flippedAxis))
13272
+ if (!toBoundingBox(source).overlap(toBoundingBox(target), flippedAxis))
13288
13273
  return;
13289
- if (!isCanvas && prev && prev.box.id !== target.box.id && toBoundingBox(prev).overlapsOnAxis(toBoundingBox(target), axis)) {
13274
+ if (!isCanvas && prev && prev.box.id !== target.box.id && toBoundingBox(prev).overlap(toBoundingBox(target), axis)) {
13290
13275
  return;
13291
13276
  }
13292
13277
  prev = target;
@@ -14430,9 +14415,18 @@ const _zoom = definePlugin((editor) => {
14430
14415
  zoomTo,
14431
14416
  elementSelection,
14432
14417
  exec,
14433
- config
14418
+ config,
14419
+ findFrame,
14420
+ selection
14434
14421
  } = editor;
14435
14422
  registerConfig("zoomToFit", "contain");
14423
+ function zoomToFrame(type, options) {
14424
+ const value = findFrame(type);
14425
+ if (value) {
14426
+ selection.value = [value];
14427
+ zoomTo(value, options);
14428
+ }
14429
+ }
14436
14430
  return {
14437
14431
  name: "mce:zoom",
14438
14432
  commands: [
@@ -14441,14 +14435,18 @@ const _zoom = definePlugin((editor) => {
14441
14435
  { command: "zoomTo100", handle: () => camera.value.setZoom(1) },
14442
14436
  { command: "zoomToCover", handle: () => zoomTo("root", { mode: "cover" }) },
14443
14437
  { command: "zoomToFit", handle: () => zoomTo("root", { mode: config.value.zoomToFit }) },
14444
- { command: "zoomToSelection", handle: (options) => zoomTo("selection", options) }
14438
+ { command: "zoomToSelection", handle: (options) => zoomTo("selection", options) },
14439
+ { command: "zoomToNextFrame", handle: (options) => zoomToFrame("next", options) },
14440
+ { command: "zoomToPreviousFrame", handle: (options) => zoomToFrame("previous", options) }
14445
14441
  ],
14446
14442
  hotkeys: [
14447
14443
  { command: "zoomIn", key: "CmdOrCtrl+=" },
14448
14444
  { command: "zoomOut", key: "CmdOrCtrl+-" },
14449
- { command: "zoomTo100", key: "CmdOrCtrl" },
14450
- { command: "zoomToFit", key: "Shift" },
14451
- { command: "zoomToSelection", key: "Shift+™" }
14445
+ { command: "zoomTo100", key: "CmdOrCtrl+0" },
14446
+ { command: "zoomToFit", key: "Shift+!" },
14447
+ { command: "zoomToSelection", key: "Shift+@" },
14448
+ { command: "zoomToNextFrame", key: "n" },
14449
+ { command: "zoomToPreviousFrame", key: "Shift+N" }
14452
14450
  ],
14453
14451
  events: {
14454
14452
  setDoc: () => exec("zoomToFit"),
@@ -14462,10 +14460,8 @@ const _zoom = definePlugin((editor) => {
14462
14460
  },
14463
14461
  setup: () => {
14464
14462
  const {
14465
- drawboardDom,
14466
- config: config2
14463
+ drawboardDom
14467
14464
  } = editor;
14468
- watch(() => config2.value.viewMode, () => exec("zoomToFit"));
14469
14465
  useResizeObserver$1(drawboardDom, (entries) => {
14470
14466
  const { left: _left, top: _top, width, height } = entries[0].contentRect;
14471
14467
  const { left = _left, top = _top } = drawboardDom.value?.getBoundingClientRect() ?? {};
@@ -14508,7 +14504,7 @@ const plugins = [
14508
14504
  _ruler,
14509
14505
  _saveAs,
14510
14506
  _scroll,
14511
- _select,
14507
+ _selection,
14512
14508
  _shape,
14513
14509
  _smartGuides,
14514
14510
  _state,
@@ -15544,7 +15540,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
15544
15540
  config,
15545
15541
  snapThreshold,
15546
15542
  getSnapPoints,
15547
- handleElementInsideFrame,
15543
+ handleDragOutReparent,
15548
15544
  getGlobalPointer
15549
15545
  } = useEditor();
15550
15546
  const transformable = useTemplateRef("transformableTpl");
@@ -15681,7 +15677,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
15681
15677
  }
15682
15678
  return false;
15683
15679
  });
15684
- handleElementInsideFrame(
15680
+ handleDragOutReparent(
15685
15681
  element,
15686
15682
  {
15687
15683
  ...startContext.value[element.instanceId],
@@ -16114,7 +16110,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
16114
16110
  const {
16115
16111
  pluginsComponents,
16116
16112
  isElement,
16117
- isTopLevelFrame,
16113
+ isTopFrame,
16118
16114
  config,
16119
16115
  drawboardDom,
16120
16116
  renderEngine,
@@ -16174,7 +16170,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
16174
16170
  function onHover(event) {
16175
16171
  let cursor;
16176
16172
  let hovered;
16177
- if (elementSelection.value.length > 1 && selectionAabbInDrawboard.value.containsPoint({
16173
+ if (elementSelection.value.length > 1 && selectionAabbInDrawboard.value.contains({
16178
16174
  x: event.clientX,
16179
16175
  y: event.clientY
16180
16176
  })) {
@@ -16193,7 +16189,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
16193
16189
  hovered = result;
16194
16190
  }
16195
16191
  }
16196
- if (!(isElement(hovered) && !isLock(hovered) && !hovered.findAncestor((ancestor) => isLock(ancestor)) && !isTopLevelFrame(hovered))) {
16192
+ if (!(isElement(hovered) && !isLock(hovered) && !hovered.findAncestor((ancestor) => isLock(ancestor)) && !isTopFrame(hovered))) {
16197
16193
  hovered = void 0;
16198
16194
  cursor = void 0;
16199
16195
  }
@@ -16208,7 +16204,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
16208
16204
  allowRootFrame = false
16209
16205
  } = options;
16210
16206
  function isIncluded(node) {
16211
- return isElement(node) && !isLock(node) && (allowRootFrame || !isTopLevelFrame(node)) && !node.findAncestor((ancestor) => isLock(ancestor));
16207
+ return isElement(node) && !isLock(node) && (allowRootFrame || !isTopFrame(node)) && !node.findAncestor((ancestor) => isLock(ancestor));
16212
16208
  }
16213
16209
  const drawing = state.value === "drawing";
16214
16210
  const hand = state.value === "hand";
@@ -16221,7 +16217,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
16221
16217
  let isUp = false;
16222
16218
  let selected = [];
16223
16219
  let ctxState;
16224
- const inSelection = selectionAabbInDrawboard.value.containsPoint({
16220
+ const inSelection = selectionAabbInDrawboard.value.contains({
16225
16221
  x: start.x - drawboardAabb.value.left,
16226
16222
  y: start.y - drawboardAabb.value.top
16227
16223
  });
@@ -16407,8 +16403,10 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
16407
16403
  }
16408
16404
  onHover(event);
16409
16405
  }
16410
- function onPointerover() {
16411
- drawboardPointer.value = void 0;
16406
+ function onPointerover(event) {
16407
+ if (event.srcElement !== drawboardDom.value) {
16408
+ return;
16409
+ }
16412
16410
  hoverElement.value = void 0;
16413
16411
  }
16414
16412
  function onScroll() {
@@ -16655,6 +16653,7 @@ export {
16655
16653
  makeMceOverlayProps,
16656
16654
  makeMceStrategyProps,
16657
16655
  mixins,
16656
+ noop,
16658
16657
  plugins,
16659
16658
  propsFactory,
16660
16659
  provideOverlay,
@@ -58,8 +58,8 @@ declare const _default: {
58
58
  selectAll: string;
59
59
  deselectAll: string;
60
60
  selectParent: string;
61
- previousSelection: string;
62
- nextSelection: string;
61
+ selectPreviousSibling: string;
62
+ selectNextSibling: string;
63
63
  view: string;
64
64
  'view:checkerboard': string;
65
65
  'view:pixelGrid': string;
@@ -83,6 +83,8 @@ declare const _default: {
83
83
  zoomTo100: string;
84
84
  zoomToFit: string;
85
85
  zoomToSelection: string;
86
+ zoomToNextFrame: string;
87
+ zoomToPreviousFrame: string;
86
88
  object: string;
87
89
  groupSelection: string;
88
90
  frameSelection: string;
@@ -59,8 +59,8 @@ declare const _default: {
59
59
  selectAll: string;
60
60
  deselectAll: string;
61
61
  selectParent: string;
62
- previousSelection: string;
63
- nextSelection: string;
62
+ selectPreviousSibling: string;
63
+ selectNextSibling: string;
64
64
  view: string;
65
65
  'view:checkerboard': string;
66
66
  'view:pixelGrid': string;
@@ -84,6 +84,8 @@ declare const _default: {
84
84
  zoomTo100: string;
85
85
  zoomToFit: string;
86
86
  zoomToSelection: string;
87
+ zoomToNextFrame: string;
88
+ zoomToPreviousFrame: string;
87
89
  object: string;
88
90
  groupSelection: string;
89
91
  frameSelection: string;
@@ -4,7 +4,6 @@ declare global {
4
4
  interface Options extends Partial<Config> {
5
5
  }
6
6
  type Theme = 'system' | 'light' | 'dark';
7
- type ViewMode = 'frame' | 'edgeless';
8
7
  type TypographyStrategy = 'autoHeight' | 'autoWidth' | 'fixedWidthHeight' | 'autoFontSize';
9
8
  type HandleShape = 'rect' | 'circle';
10
9
  interface ScreenCenterOffset {
@@ -15,7 +14,6 @@ declare global {
15
14
  }
16
15
  interface Config {
17
16
  theme: Theme;
18
- viewMode: ViewMode;
19
17
  watermark?: string;
20
18
  msaa: boolean;
21
19
  checkerboard: boolean;
@@ -47,7 +47,7 @@ declare global {
47
47
  isRoot: (value: any) => value is Node;
48
48
  isElement: (value: any) => value is Element2D;
49
49
  isFrame: (value: any) => value is Element2D;
50
- isTopLevelFrame: (value: any) => value is Element2D;
50
+ isTopFrame: (value: any) => value is Element2D;
51
51
  isVisible: (node: Node) => boolean;
52
52
  setVisible: (node: Node, visible: boolean) => void;
53
53
  isLock: (node: Node) => boolean;
@@ -1,6 +1,5 @@
1
1
  import type { Element2D, Node } from 'modern-canvas';
2
2
  import type { ComputedRef, Ref } from 'vue';
3
- import type { AxisAlignedBoundingBox } from '../types';
4
3
  declare global {
5
4
  namespace Mce {
6
5
  interface FrameThumb {
@@ -12,10 +11,7 @@ declare global {
12
11
  interface Editor {
13
12
  frameThumbs: Ref<FrameThumb[]>;
14
13
  frames: ComputedRef<Element2D[]>;
15
- currentFrameIndex: Ref<number>;
16
- currentFrame: ComputedRef<Element2D | undefined>;
17
- currentFrameAabb: ComputedRef<AxisAlignedBoundingBox>;
18
- getAncestorFrame: (node?: Node) => Element2D | undefined;
14
+ getAncestorFrame: (node?: Node, isTop?: boolean) => Element2D | undefined;
19
15
  }
20
16
  }
21
17
  }
@@ -8,6 +8,7 @@ declare global {
8
8
  getObb: (node: Node | Node[] | undefined, inTarget?: 'drawboard' | 'frame' | 'parent') => Obb2D;
9
9
  getAabb: (node: Node | Node[] | undefined, inTarget?: 'drawboard' | 'frame' | 'parent') => Aabb2D;
10
10
  aabbToDrawboardAabb: (aabb: Aabb2D) => Aabb2D;
11
+ viewportAabb: ComputedRef<Aabb2D>;
11
12
  rootAabb: ComputedRef<Aabb2D>;
12
13
  selectionAabb: ComputedRef<Aabb2D>;
13
14
  selectionAabbInDrawboard: ComputedRef<Aabb2D>;
@@ -1,9 +1,6 @@
1
- import type { ComputedRef } from 'vue';
2
- import type { AxisAlignedBoundingBox } from '../types';
3
1
  declare global {
4
2
  namespace Mce {
5
3
  interface Editor {
6
- viewAabb: ComputedRef<AxisAlignedBoundingBox>;
7
4
  bindRenderCanvas: (canvas: HTMLCanvasElement, setEventTarget?: HTMLElement) => () => void;
8
5
  }
9
6
  }
@@ -9,6 +9,7 @@ declare global {
9
9
  regenId?: boolean;
10
10
  }
11
11
  interface Editor {
12
+ findSibling: (target: 'previous' | 'next') => Node | undefined;
12
13
  addNode: (value: Element, options?: AddNodeOptions) => Node;
13
14
  }
14
15
  }
@@ -1,12 +1,14 @@
1
- import type { Element2D } from 'modern-canvas';
1
+ import type { Element2D, Vector2Like } from 'modern-canvas';
2
2
  declare global {
3
3
  namespace Mce {
4
- interface Editor {
5
- setCurrentFrame: (index?: number) => void;
6
- handleElementInsideFrame: (element: Element2D, context?: Record<string, any>) => void;
4
+ interface HandleDragOutReparentOptions {
5
+ pointer: Vector2Like;
6
+ parent: Element2D;
7
+ index: number;
7
8
  }
8
- interface Events {
9
- setCurrentFrame: [index: number, oldIndex: number];
9
+ interface Editor {
10
+ findFrame: (target: 'next' | 'previous') => Element2D | undefined;
11
+ handleDragOutReparent: (element: Element2D, context?: HandleDragOutReparentOptions) => void;
10
12
  }
11
13
  }
12
14
  }
@@ -6,6 +6,7 @@ declare global {
6
6
  y: number;
7
7
  } | Element2D[];
8
8
  interface ScrollToOptions {
9
+ intoView?: boolean;
9
10
  duration?: number;
10
11
  behavior?: 'smooth' | 'instant';
11
12
  }
@@ -8,8 +8,7 @@ declare global {
8
8
  interface Editor {
9
9
  snapshot: () => void;
10
10
  captureElementScreenshot: (element: Element | Element2D) => Promise<HTMLCanvasElement>;
11
- captureFrameScreenshot: (pageIndex: number) => void;
12
- renderFrameThumb: (target: HTMLCanvasElement) => void;
11
+ captureFrameScreenshot: (index: number) => void;
13
12
  }
14
13
  }
15
14
  }
@@ -1,9 +1,10 @@
1
1
  import type { Element2D } from 'modern-canvas';
2
2
  declare global {
3
3
  namespace Mce {
4
- type ZoomTarget = 'root' | 'selection' | Element2D[] | number;
4
+ type ZoomTarget = 'root' | 'selection' | Element2D | Element2D[] | number;
5
5
  type ZoomToMode = 'contain' | 'cover';
6
6
  interface ZoomToOptions {
7
+ intoView?: boolean;
7
8
  mode?: ZoomToMode;
8
9
  duration?: number;
9
10
  behavior?: 'smooth' | 'instant';
@@ -4,15 +4,15 @@ declare global {
4
4
  selectAll: [event: KeyboardEvent];
5
5
  deselectAll: [event: KeyboardEvent];
6
6
  selectParent: [event: KeyboardEvent];
7
- previousSelection: [event: KeyboardEvent];
8
- nextSelection: [event: KeyboardEvent];
7
+ selectPreviousSibling: [event: KeyboardEvent];
8
+ selectNextSibling: [event: KeyboardEvent];
9
9
  }
10
10
  interface Commands {
11
11
  selectAll: () => void;
12
12
  deselectAll: () => void;
13
13
  selectParent: () => void;
14
- previousSelection: () => void;
15
- nextSelection: () => void;
14
+ selectPreviousSibling: () => void;
15
+ selectNextSibling: () => void;
16
16
  }
17
17
  }
18
18
  }
@@ -10,6 +10,7 @@ declare global {
10
10
  startTyping: (e?: MouseEvent | PointerEvent) => Promise<boolean>;
11
11
  startTransform: (e?: MouseEvent | PointerEvent) => boolean;
12
12
  openContextMenu: (e?: MouseEvent | PointerEvent) => boolean;
13
+ layerScrollIntoView: () => boolean;
13
14
  }
14
15
  interface Events {
15
16
  setTransform: [value: {
@@ -58,7 +58,7 @@ import './plugins/rotate'
58
58
  import './plugins/ruler'
59
59
  import './plugins/saveAs'
60
60
  import './plugins/scroll'
61
- import './plugins/select'
61
+ import './plugins/selection'
62
62
  import './plugins/shape'
63
63
  import './plugins/smartGuides'
64
64
  import './plugins/state'
@@ -1,4 +1,5 @@
1
1
  import type { ComponentInternalInstance, ComponentPublicInstance, InjectionKey, VNodeChild } from 'vue';
2
+ export declare function noop(..._args: any): void;
2
3
  export declare function isClickInsideElement(event: MouseEvent, targetDiv: HTMLElement): boolean;
3
4
  export interface TemplateRef {
4
5
  (target: Element | ComponentPublicInstance | null): void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mce",
3
3
  "type": "module",
4
- "version": "0.15.20",
4
+ "version": "0.15.21",
5
5
  "description": "The headless canvas editor framework. only the ESM.",
6
6
  "author": "wxm",
7
7
  "license": "MIT",
@@ -58,10 +58,10 @@
58
58
  "@floating-ui/vue": "^1.1.9",
59
59
  "@vueuse/components": "^14.1.0",
60
60
  "@vueuse/core": "^14.1.0",
61
- "diff": "^8.0.2",
61
+ "diff": "^8.0.3",
62
62
  "file-saver": "^2.0.5",
63
63
  "lodash-es": "^4.17.22",
64
- "modern-canvas": "^0.14.35",
64
+ "modern-canvas": "^0.14.36",
65
65
  "modern-font": "^0.4.4",
66
66
  "modern-idoc": "^0.10.9",
67
67
  "modern-text": "^1.10.15",