mce 0.12.1 → 0.12.3

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.
@@ -1,8 +1,6 @@
1
1
  type __VLS_Props = {
2
- zoom: number;
3
2
  length: number;
4
3
  vertical?: boolean;
5
- infinite?: boolean;
6
4
  size: number;
7
5
  offset: number;
8
6
  };
package/dist/index.d.ts CHANGED
@@ -17,4 +17,4 @@ export * from './plugins';
17
17
  export * from './types';
18
18
  export * from './utils';
19
19
  export type { Camera2D, Element2D, Engine } from 'modern-canvas';
20
- export type { Element, NormalizedElement } from 'modern-idoc';
20
+ export type { Document, Element, NormalizedElement } from 'modern-idoc';
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { merge, throttle, cloneDeep } from "lodash-es";
9
9
  import { measureText } from "modern-text";
10
10
  import { TextEditor } from "modern-text/web-components";
11
11
  import { useFloating, offset, flip, shift, autoUpdate } from "@floating-ui/vue";
12
- import { vResizeObserver, vOnLongPress } from "@vueuse/components";
12
+ import { vResizeObserver } from "@vueuse/components";
13
13
  const _0_command = defineMixin((editor) => {
14
14
  const {
15
15
  emit
@@ -124,26 +124,7 @@ const _0_config_base = defineMixin((editor, options) => {
124
124
  registerConfig("typographyStrategy", "autoHeight");
125
125
  registerConfig("handleShape", "rect");
126
126
  registerConfig("localDb", false);
127
- const screenCenterOffset = { left: 0, top: 0, bottom: 0, right: 0 };
128
- registerConfig("screenCenterOffset", { ...screenCenterOffset });
129
- const getScreenCenterOffset = () => {
130
- const offset2 = {
131
- ...screenCenterOffset,
132
- ...config.value.screenCenterOffset
133
- };
134
- if (config.value.scrollbar) {
135
- offset2.right += 8;
136
- offset2.bottom += 8;
137
- }
138
- if (config.value.ruler) {
139
- offset2.left += 16;
140
- offset2.top += 16;
141
- }
142
- return offset2;
143
- };
144
- Object.assign(editor, {
145
- getScreenCenterOffset
146
- });
127
+ registerConfig("screenCenterOffset", { left: 0, top: 0, bottom: 0, right: 0 });
147
128
  return () => {
148
129
  const {
149
130
  camera,
@@ -667,6 +648,10 @@ class Doc extends Model {
667
648
  this.reset();
668
649
  this.addElements(children);
669
650
  this.setProperties(props);
651
+ this._yProps.clear();
652
+ for (const key in props) {
653
+ this._yProps.set(key, props[key]);
654
+ }
670
655
  this._yProps.set("meta", new Y.Map(Object.entries(meta)));
671
656
  return this;
672
657
  }
@@ -998,6 +983,42 @@ const _0_font = defineMixin((editor, options) => {
998
983
  }
999
984
  };
1000
985
  });
986
+ const _0_helper = defineMixin((editor) => {
987
+ const block = ["top", "bottom"];
988
+ const inline = ["start", "end", "left", "right"];
989
+ function toPhysical(str, isRtl) {
990
+ if (str === "start")
991
+ return isRtl ? "right" : "left";
992
+ if (str === "end")
993
+ return isRtl ? "left" : "right";
994
+ return str;
995
+ }
996
+ const parseAnchor = (anchor, isRtl) => {
997
+ let [side, align] = anchor.split(" ");
998
+ if (!align) {
999
+ align = block.includes(side) ? "start" : inline.includes(side) ? "top" : "center";
1000
+ }
1001
+ return {
1002
+ side: toPhysical(side, isRtl),
1003
+ align: toPhysical(align, isRtl)
1004
+ };
1005
+ };
1006
+ function isFrame(node) {
1007
+ return node instanceof Element2D && node.meta?.inEditorIs === "Frame";
1008
+ }
1009
+ function isLocked(element) {
1010
+ return Boolean(element.meta.lock);
1011
+ }
1012
+ function setLock(element, lock) {
1013
+ element.meta.lock = lock;
1014
+ }
1015
+ Object.assign(editor, {
1016
+ parseAnchor,
1017
+ isFrame,
1018
+ isLocked,
1019
+ setLock
1020
+ });
1021
+ });
1001
1022
  const en = {
1002
1023
  "cancel": "Cancel",
1003
1024
  "constrainToAxis": "Constrain to axis",
@@ -1053,8 +1074,9 @@ const en = {
1053
1074
  "zoomToFit": "Zoom to fit",
1054
1075
  "zoomToSelection": "Zoom to selection",
1055
1076
  "object": "Object",
1056
- "frame/unframe": "Frame/Unframe",
1057
- "group/ungroup": "Group/Ungroup",
1077
+ "groupSelection": "Group Selection",
1078
+ "frameSelection": "Frame selection",
1079
+ "ungroup": "Ungroup",
1058
1080
  "flip": "Flip",
1059
1081
  "flipHorizontal": "Flip horizontal",
1060
1082
  "flipVertical": "Flip vertical",
@@ -1110,7 +1132,8 @@ const _0_locale = defineMixin((editor, options) => {
1110
1132
  });
1111
1133
  const _1_frame = defineMixin((editor) => {
1112
1134
  const {
1113
- root
1135
+ root,
1136
+ isFrame
1114
1137
  } = editor;
1115
1138
  const frames = computed(() => root.value.children.filter(isFrame) ?? []);
1116
1139
  const currentFrameIndex = ref(-1);
@@ -1120,9 +1143,6 @@ const _1_frame = defineMixin((editor) => {
1120
1143
  return { left, top, width, height };
1121
1144
  });
1122
1145
  const frameThumbs = ref([]);
1123
- function isFrame(node) {
1124
- return node instanceof Element2D && node.meta?.inEditorIs === "Frame";
1125
- }
1126
1146
  function getAncestorFrame(element) {
1127
1147
  return element?.findAncestor((node) => isFrame(node));
1128
1148
  }
@@ -1132,7 +1152,6 @@ const _1_frame = defineMixin((editor) => {
1132
1152
  currentFrameIndex,
1133
1153
  currentFrame,
1134
1154
  currentFrameAabb,
1135
- isFrame,
1136
1155
  getAncestorFrame
1137
1156
  });
1138
1157
  return () => {
@@ -1561,6 +1580,41 @@ const _1_hotkey = defineMixin((editor) => {
1561
1580
  );
1562
1581
  };
1563
1582
  });
1583
+ const _1_screen = defineMixin((editor) => {
1584
+ const {
1585
+ config,
1586
+ drawboardAabb
1587
+ } = editor;
1588
+ const getScreenCenterOffset = () => {
1589
+ const offset2 = {
1590
+ left: 0,
1591
+ top: 0,
1592
+ bottom: 0,
1593
+ right: 0,
1594
+ ...config.value.screenCenterOffset
1595
+ };
1596
+ if (config.value.scrollbar) {
1597
+ offset2.right += 8;
1598
+ offset2.bottom += 8;
1599
+ }
1600
+ if (config.value.ruler) {
1601
+ offset2.left += 16;
1602
+ offset2.top += 16;
1603
+ }
1604
+ return offset2;
1605
+ };
1606
+ const getScreenCenter = () => {
1607
+ const offset2 = getScreenCenterOffset();
1608
+ return {
1609
+ x: offset2.left + (drawboardAabb.value.width - offset2.left - offset2.right) / 2,
1610
+ y: offset2.top + (drawboardAabb.value.height - offset2.top - offset2.bottom) / 2
1611
+ };
1612
+ };
1613
+ Object.assign(editor, {
1614
+ getScreenCenterOffset,
1615
+ getScreenCenter
1616
+ });
1617
+ });
1564
1618
  const _1_timeline = defineMixin((editor) => {
1565
1619
  const {
1566
1620
  root,
@@ -2154,22 +2208,6 @@ const _4_0_text = defineMixin((editor) => {
2154
2208
  TextEditor.register();
2155
2209
  };
2156
2210
  });
2157
- const _4_1_lock = defineMixin((editor) => {
2158
- function isLock(element) {
2159
- return Boolean(element.meta.lock);
2160
- }
2161
- function lock(element) {
2162
- element.meta.lock = true;
2163
- }
2164
- function unlock(element) {
2165
- element.meta.lock = false;
2166
- }
2167
- Object.assign(editor, {
2168
- isLock,
2169
- lock,
2170
- unlock
2171
- });
2172
- });
2173
2211
  const _4_2_element = defineMixin((editor) => {
2174
2212
  const {
2175
2213
  doc,
@@ -2181,70 +2219,66 @@ const _4_2_element = defineMixin((editor) => {
2181
2219
  log,
2182
2220
  root,
2183
2221
  isFrame,
2184
- isLock,
2222
+ isLocked,
2185
2223
  getObbInDrawboard,
2186
2224
  config,
2187
2225
  getAncestorFrame,
2188
2226
  getAabb,
2189
2227
  getGlobalPointer,
2228
+ getScreenCenter,
2190
2229
  selection,
2191
- getScreenCenterOffset,
2192
2230
  camera,
2193
- drawboardAabb
2231
+ parseAnchor
2194
2232
  } = editor;
2195
2233
  function addElement(value, options = {}) {
2196
2234
  log("addElement", value, options);
2235
+ const {
2236
+ frameGap
2237
+ } = config.value;
2197
2238
  let {
2198
- frame,
2239
+ parent,
2240
+ index,
2199
2241
  sizeToFit,
2200
2242
  position,
2201
2243
  active,
2202
2244
  regenId
2203
2245
  } = options;
2204
- if (!frame) {
2246
+ if (!parent) {
2205
2247
  if (config.value.viewMode === "frame") {
2206
- frame = currentFrame.value;
2248
+ parent = currentFrame.value;
2207
2249
  } else {
2208
2250
  const element = selection.value[0];
2209
2251
  if (element) {
2210
2252
  if (isFrame(element)) {
2211
- frame = element;
2253
+ parent = element;
2212
2254
  } else {
2213
- frame = getAncestorFrame(element);
2255
+ parent = getAncestorFrame(element);
2214
2256
  }
2215
2257
  }
2216
2258
  }
2217
2259
  }
2218
- let initPos;
2219
- switch (position) {
2220
- case "screenCenter": {
2221
- const screenCenterOffset = getScreenCenterOffset();
2222
- const { zoom, position: position2 } = camera.value;
2223
- const centerOffset = {
2224
- x: position2.x + screenCenterOffset.left + (drawboardAabb.value.width - screenCenterOffset.left - screenCenterOffset.right) / 2,
2225
- y: position2.y + screenCenterOffset.top + (drawboardAabb.value.height - screenCenterOffset.top - screenCenterOffset.bottom) / 2
2226
- };
2227
- initPos = {
2228
- x: centerOffset.x * zoom.x,
2229
- y: centerOffset.y * zoom.y
2230
- };
2231
- break;
2232
- }
2233
- case "fit":
2234
- initPos = {
2235
- x: rootAabb.value.left + rootAabb.value.width + config.value.frameGap,
2236
- y: rootAabb.value.top
2237
- };
2238
- break;
2239
- }
2260
+ const parentAabb = parent ? getAabb(parent) : void 0;
2240
2261
  const isArray = Array.isArray(value);
2241
- let offsetX = 0;
2262
+ let offsetIndex = index;
2242
2263
  const elements = doc.value.transact(() => {
2243
2264
  const values = isArray ? value : [value];
2244
2265
  const elements2 = values.map((element) => {
2245
- const el = doc.value.addElement(element, { parentId: frame?.id, regenId });
2246
- if (frame) {
2247
- const { width, height } = frame.style;
2266
+ const el = doc.value.addElement(element, {
2267
+ parentId: parent?.id,
2268
+ index: offsetIndex,
2269
+ regenId
2270
+ });
2271
+ if (offsetIndex !== void 0) {
2272
+ offsetIndex++;
2273
+ }
2274
+ if (el.text.isValid()) {
2275
+ if (!el.style.width)
2276
+ el.style.width = el.text.base.boundingBox.width;
2277
+ if (!el.style.height)
2278
+ el.style.height = el.text.base.boundingBox.height;
2279
+ }
2280
+ if (parentAabb && parentAabb.width && parentAabb.height) {
2281
+ const { width, height } = parentAabb;
2248
2282
  const halfWidth = width / 2;
2249
2283
  const halfHeight = height / 2;
2250
2284
  if (!el.style.width)
@@ -2265,22 +2299,76 @@ const _4_2_element = defineMixin((editor) => {
2265
2299
  }
2266
2300
  );
2267
2301
  }
2268
- if (position === "fit") {
2269
- el.style.left = Math.round(width - el.style.width) / 2;
2270
- el.style.top = Math.round(height - el.style.height) / 2;
2271
- }
2272
- } else {
2273
- if (initPos) {
2274
- el.style.top = Math.round(initPos.x);
2275
- el.style.left = Math.round(initPos.y);
2276
- initPos.x += el.style.height + config.value.frameGap;
2277
- }
2278
2302
  }
2279
- el.style.left += offsetX;
2280
- offsetX += el.style.width;
2281
2303
  return el;
2282
2304
  });
2283
2305
  const aabb = getAabb(elements2);
2306
+ let globalPosition;
2307
+ if (typeof position === "string") {
2308
+ switch (position) {
2309
+ case "pointer":
2310
+ break;
2311
+ case "screenCenter":
2312
+ globalPosition = camera.value.toGlobal(getScreenCenter());
2313
+ break;
2314
+ default: {
2315
+ const _parentAabb = parentAabb ?? rootAabb.value;
2316
+ const anchor = parseAnchor(position);
2317
+ globalPosition = { x: 0, y: 0 };
2318
+ const map = {
2319
+ centerX: () => globalPosition.x = _parentAabb.left + _parentAabb.width / 2,
2320
+ centerY: () => globalPosition.y = _parentAabb.top + _parentAabb.height / 2
2321
+ };
2322
+ if (anchor.side === "center") {
2323
+ map.centerX();
2324
+ map.centerY();
2325
+ } else {
2326
+ if (anchor.side === "left" || anchor.side === "right") {
2327
+ switch (anchor.side) {
2328
+ case "left":
2329
+ globalPosition.x = _parentAabb.left - (aabb.width + frameGap);
2330
+ break;
2331
+ case "right":
2332
+ globalPosition.x = _parentAabb.left + _parentAabb.width + frameGap;
2333
+ break;
2334
+ }
2335
+ switch (anchor.align) {
2336
+ case "top":
2337
+ globalPosition.y = _parentAabb.top;
2338
+ break;
2339
+ case "bottom":
2340
+ globalPosition.y = _parentAabb.top + _parentAabb.height;
2341
+ break;
2342
+ case "center":
2343
+ map.centerY();
2344
+ break;
2345
+ }
2346
+ } else if (anchor.side === "top" || anchor.side === "bottom") {
2347
+ switch (anchor.side) {
2348
+ case "top":
2349
+ globalPosition.y = _parentAabb.top - (aabb.height + frameGap);
2350
+ break;
2351
+ case "bottom":
2352
+ globalPosition.y = _parentAabb.top + _parentAabb.height + frameGap;
2353
+ break;
2354
+ }
2355
+ switch (anchor.align) {
2356
+ case "left":
2357
+ globalPosition.x = _parentAabb.left;
2358
+ break;
2359
+ case "right":
2360
+ globalPosition.x = _parentAabb.left + _parentAabb.width;
2361
+ break;
2362
+ case "center":
2363
+ map.centerX();
2364
+ break;
2365
+ }
2366
+ }
2367
+ }
2368
+ break;
2369
+ }
2370
+ }
2371
+ }
2284
2372
  if (position === "pointer") {
2285
2373
  const pointer = getGlobalPointer();
2286
2374
  const diff = {
@@ -2291,6 +2379,16 @@ const _4_2_element = defineMixin((editor) => {
2291
2379
  el.style.left += diff.x;
2292
2380
  el.style.top += diff.y;
2293
2381
  });
2382
+ } else if (globalPosition) {
2383
+ elements2.forEach((el) => {
2384
+ el.style.left = Math.round(
2385
+ parentAabb ? parentAabb.left - globalPosition.x : globalPosition.x
2386
+ );
2387
+ el.style.top = Math.round(
2388
+ parentAabb ? parentAabb.top - globalPosition.y : globalPosition.y
2389
+ );
2390
+ globalPosition.x += el.style.width + frameGap;
2391
+ });
2294
2392
  }
2295
2393
  return elements2;
2296
2394
  });
@@ -2358,7 +2456,7 @@ const _4_2_element = defineMixin((editor) => {
2358
2456
  }
2359
2457
  return [node];
2360
2458
  }).filter((node) => {
2361
- return "isVisibleInTree" in node && node.isVisibleInTree() && isOverlappingObb(areaInDrawboard, getObbInDrawboard(node)) && !isLock(node);
2459
+ return "isVisibleInTree" in node && node.isVisibleInTree() && isOverlappingObb(areaInDrawboard, getObbInDrawboard(node)) && !isLocked(node);
2362
2460
  }) ?? [];
2363
2461
  selection.value = selected;
2364
2462
  return selected;
@@ -2503,17 +2601,18 @@ const _4_4_doc = defineMixin((editor, options) => {
2503
2601
  }
2504
2602
  const setDoc = async (source) => {
2505
2603
  let id;
2604
+ let _source = source;
2506
2605
  if (typeof source === "string") {
2507
2606
  id = source;
2508
2607
  } else if (source) {
2509
2608
  if (Array.isArray(source) && source.length === 1) {
2510
- source = source[0];
2609
+ _source = source[0];
2511
2610
  }
2512
2611
  if (!Array.isArray(source)) {
2513
2612
  if (source.meta?.inEditorIs === "Doc") {
2514
2613
  id = source.id;
2515
2614
  } else {
2516
- source = [source];
2615
+ _source = [source];
2517
2616
  }
2518
2617
  }
2519
2618
  }
@@ -2522,7 +2621,7 @@ const _4_4_doc = defineMixin((editor, options) => {
2522
2621
  try {
2523
2622
  await waitUntilFontLoad();
2524
2623
  clearDoc();
2525
- await initDoc(_doc, source);
2624
+ await initDoc(_doc, _source);
2526
2625
  doc.value = _doc;
2527
2626
  emit("setDoc", _doc);
2528
2627
  } finally {
@@ -2558,8 +2657,7 @@ const _scroll$1 = defineMixin((editor) => {
2558
2657
  getAabb,
2559
2658
  selectionAabb,
2560
2659
  viewAabb,
2561
- drawboardAabb,
2562
- getScreenCenterOffset
2660
+ getScreenCenter
2563
2661
  } = editor;
2564
2662
  const scrollTo = async (target, options = {}) => {
2565
2663
  const {
@@ -2567,7 +2665,7 @@ const _scroll$1 = defineMixin((editor) => {
2567
2665
  duration = 500
2568
2666
  } = options;
2569
2667
  const _camera = camera.value;
2570
- const screenCenterOffset = getScreenCenterOffset();
2668
+ const screenCenter = getScreenCenter();
2571
2669
  const offset2 = { x: 0, y: 0 };
2572
2670
  let position = { x: 0, y: 0 };
2573
2671
  if (typeof target === "object" && "x" in target && "y" in target) {
@@ -2589,10 +2687,8 @@ const _scroll$1 = defineMixin((editor) => {
2589
2687
  }
2590
2688
  }
2591
2689
  position = { x: aabb.left + aabb.width / 2, y: aabb.top + aabb.height / 2 };
2592
- offset2.x -= screenCenterOffset.left;
2593
- offset2.x -= (drawboardAabb.value.width - screenCenterOffset.left - screenCenterOffset.right) / 2;
2594
- offset2.y -= screenCenterOffset.top;
2595
- offset2.y -= (drawboardAabb.value.height - screenCenterOffset.top - screenCenterOffset.bottom) / 2;
2690
+ offset2.x += -screenCenter.x;
2691
+ offset2.y = -screenCenter.y;
2596
2692
  }
2597
2693
  position.x *= _camera.zoom.x;
2598
2694
  position.x += offset2.x;
@@ -2700,8 +2796,8 @@ const _snapshot = defineMixin((editor) => {
2700
2796
  const sh = aabb.height * zoom.y;
2701
2797
  ctx.drawImage(
2702
2798
  view,
2703
- (aabb.left * zoom.x + position.x) * pixelRatio,
2704
- (aabb.top * zoom.x + position.y) * pixelRatio,
2799
+ (aabb.left * zoom.x - position.x) * pixelRatio,
2800
+ (aabb.top * zoom.x - position.y) * pixelRatio,
2705
2801
  sw * pixelRatio,
2706
2802
  sh * pixelRatio,
2707
2803
  0,
@@ -2860,9 +2956,11 @@ const mixins = [
2860
2956
  _0_context,
2861
2957
  _0_element,
2862
2958
  _0_font,
2959
+ _0_helper,
2863
2960
  _0_locale,
2864
2961
  _1_frame,
2865
2962
  _1_hotkey,
2963
+ _1_screen,
2866
2964
  _1_timeline,
2867
2965
  _1_upload,
2868
2966
  _2_box,
@@ -2870,7 +2968,6 @@ const mixins = [
2870
2968
  _2_load,
2871
2969
  _3_view,
2872
2970
  _4_0_text,
2873
- _4_1_lock,
2874
2971
  _4_2_element,
2875
2972
  _4_3_frame,
2876
2973
  _4_4_doc,
@@ -4311,9 +4408,19 @@ const _clipboard = definePlugin((editor, options) => {
4311
4408
  }
4312
4409
  }
4313
4410
  };
4314
- async function duplicate() {
4315
- await copy();
4316
- await paste();
4411
+ function duplicate() {
4412
+ if (!selection.value.length) {
4413
+ return;
4414
+ }
4415
+ addElement(
4416
+ selection.value.map((v) => v.toJSON()),
4417
+ {
4418
+ parent: selection.value[0].parent,
4419
+ index: selection.value[0].getIndex(),
4420
+ active: true,
4421
+ regenId: true
4422
+ }
4423
+ );
4317
4424
  }
4318
4425
  Object.assign(editor, {
4319
4426
  copiedData
@@ -4427,82 +4534,6 @@ const _flip = definePlugin((editor) => {
4427
4534
  ]
4428
4535
  };
4429
4536
  });
4430
- const _frame = definePlugin((editor) => {
4431
- const {
4432
- deleteElement,
4433
- getAabb,
4434
- getObb,
4435
- selection,
4436
- addElement,
4437
- isFrame,
4438
- doc
4439
- } = editor;
4440
- function frame() {
4441
- const elements = selection.value;
4442
- if (elements.length === 0) {
4443
- return;
4444
- }
4445
- const aabb = getAabb(elements, "frame");
4446
- const children = elements.map((v) => {
4447
- const cloned = v.toJSON();
4448
- cloned.style.left = (cloned.style.left ?? 0) - aabb.left;
4449
- cloned.style.top = (cloned.style.top ?? 0) - aabb.top;
4450
- return cloned;
4451
- });
4452
- doc.value.transact(() => {
4453
- addElement({
4454
- style: { ...aabb },
4455
- children,
4456
- meta: {
4457
- inEditorIs: "Frame"
4458
- }
4459
- }, {
4460
- regenId: true,
4461
- active: true
4462
- });
4463
- elements.forEach((v) => deleteElement(v.id));
4464
- });
4465
- }
4466
- function unframe() {
4467
- const element = selection.value[0];
4468
- if (!element)
4469
- return;
4470
- const items = element.children.map((el) => {
4471
- const obb = getObb(el);
4472
- const cloned = el.toJSON();
4473
- cloned.style.left = obb.left;
4474
- cloned.style.top = obb.top;
4475
- return cloned;
4476
- });
4477
- doc.value.transact(() => {
4478
- deleteElement(element.id);
4479
- addElement(items, {
4480
- active: true,
4481
- regenId: true
4482
- });
4483
- });
4484
- }
4485
- function frameOrUnframe() {
4486
- if (selection.value.length === 1) {
4487
- if (isFrame(selection.value[0])) {
4488
- unframe();
4489
- }
4490
- } else if (selection.value.length > 1) {
4491
- frame();
4492
- }
4493
- }
4494
- return {
4495
- name: "mce:frame",
4496
- commands: [
4497
- { command: "frame", handle: frame },
4498
- { command: "unframe", handle: unframe },
4499
- { command: "frame/unframe", handle: frameOrUnframe }
4500
- ],
4501
- hotkeys: [
4502
- { command: "frame/unframe", key: "Alt+CmdOrCtrl+g" }
4503
- ]
4504
- };
4505
- });
4506
4537
  const _gif = definePlugin((editor, options) => {
4507
4538
  const {
4508
4539
  fonts,
@@ -4550,26 +4581,32 @@ const _group = definePlugin((editor) => {
4550
4581
  deleteElement,
4551
4582
  doc
4552
4583
  } = editor;
4553
- function group() {
4584
+ function group(inEditorIs) {
4554
4585
  const elements = selection.value;
4555
- if (elements.length === 0) {
4586
+ if (!elements.length) {
4556
4587
  return;
4557
4588
  }
4589
+ const element = elements[0];
4590
+ const parent = element.parent;
4558
4591
  const aabb = getAabb(elements, "parent");
4559
- const children = elements.map((v) => {
4560
- const cloned = v.toJSON();
4561
- cloned.style.left = (cloned.style.left ?? 0) - aabb.left;
4562
- cloned.style.top = (cloned.style.top ?? 0) - aabb.top;
4592
+ const children = elements.map((child) => {
4593
+ const cloned = child.toJSON();
4594
+ cloned.style.left = child.style.left - aabb.left;
4595
+ cloned.style.top = child.style.top - aabb.top;
4563
4596
  return cloned;
4564
4597
  });
4565
4598
  doc.value.transact(() => {
4566
4599
  addElement({
4600
+ name: inEditorIs === "Frame" ? "Frame" : "Group",
4567
4601
  style: { ...aabb },
4568
4602
  children,
4569
4603
  meta: {
4570
- inPptIs: "GroupShape"
4604
+ inPptIs: "GroupShape",
4605
+ inEditorIs
4571
4606
  }
4572
4607
  }, {
4608
+ parent,
4609
+ index: parent ? element.getIndex() : void 0,
4573
4610
  active: true,
4574
4611
  regenId: true
4575
4612
  });
@@ -4578,39 +4615,37 @@ const _group = definePlugin((editor) => {
4578
4615
  }
4579
4616
  function ungroup() {
4580
4617
  const element = selection.value[0];
4581
- if (!element)
4618
+ if (!element || !element.children.length)
4582
4619
  return;
4620
+ const parent = getObb(element, "parent");
4583
4621
  const items = element.children.map((child) => {
4584
- const obb = getObb(child, "frame");
4622
+ const obb = getObb(child, "parent");
4585
4623
  const cloned = child.toJSON();
4586
- cloned.style.left = obb.left;
4587
- cloned.style.top = obb.top;
4624
+ cloned.style.left = obb.left + parent.left;
4625
+ cloned.style.top = obb.top + parent.top;
4588
4626
  return cloned;
4589
4627
  });
4590
4628
  doc.value.transact(() => {
4591
4629
  addElement(items, {
4630
+ parent: element.parent,
4631
+ index: element.getIndex(),
4592
4632
  active: true,
4593
4633
  regenId: true
4594
4634
  });
4595
4635
  deleteElement(element.id);
4596
4636
  });
4597
4637
  }
4598
- function groupOrUngroup() {
4599
- if (selection.value.length === 1) {
4600
- ungroup();
4601
- } else if (selection.value.length > 1) {
4602
- group();
4603
- }
4604
- }
4605
4638
  return {
4606
4639
  name: "mce:group",
4607
4640
  commands: [
4608
- { command: "group", handle: group },
4609
- { command: "ungroup", handle: ungroup },
4610
- { command: "group/ungroup", handle: groupOrUngroup }
4641
+ { command: "groupSelection", handle: () => group("Element") },
4642
+ { command: "frameSelection", handle: () => group("Frame") },
4643
+ { command: "ungroup", handle: ungroup }
4611
4644
  ],
4612
4645
  hotkeys: [
4613
- { command: "group/ungroup", key: "CmdOrCtrl+g" }
4646
+ { command: "groupSelection", key: "CmdOrCtrl+g" },
4647
+ { command: "frameSelection", key: "Alt+CmdOrCtrl+g" },
4648
+ { command: "ungroup", key: "CmdOrCtrl+Backspace" }
4614
4649
  ]
4615
4650
  };
4616
4651
  });
@@ -4696,7 +4731,7 @@ const _image = definePlugin((editor) => {
4696
4731
  const insertImage = async (url, options) => {
4697
4732
  return addElement(await createImageElement(url), {
4698
4733
  sizeToFit: true,
4699
- position: "fit",
4734
+ position: "right",
4700
4735
  ...options
4701
4736
  });
4702
4737
  };
@@ -4775,7 +4810,7 @@ const _import = definePlugin((editor) => {
4775
4810
  return addElement((await Promise.all(files.map((file) => load(file)))).flat(), {
4776
4811
  ...options,
4777
4812
  sizeToFit: true,
4778
- position: "fit"
4813
+ position: "right"
4779
4814
  });
4780
4815
  };
4781
4816
  return {
@@ -4869,9 +4904,7 @@ const _json = definePlugin((editor) => {
4869
4904
  elements = selection.value;
4870
4905
  }
4871
4906
  if (elements.length === 0 && root.value) {
4872
- if (root.value.meta.id) {
4873
- id = root.value.meta.id;
4874
- }
4907
+ id = root.value.id;
4875
4908
  elements = root.value.children;
4876
4909
  }
4877
4910
  }
@@ -4898,6 +4931,7 @@ const _json = definePlugin((editor) => {
4898
4931
  }),
4899
4932
  meta: {
4900
4933
  inPptIs: "Pptx",
4934
+ inEditorIs: "Doc",
4901
4935
  inCanvasIs: "Element2D",
4902
4936
  ...getTimeRange(elements)
4903
4937
  }
@@ -5020,16 +5054,15 @@ const _layerPosition = definePlugin((editor) => {
5020
5054
  const _lock = definePlugin((editor) => {
5021
5055
  const {
5022
5056
  selection,
5023
- lock,
5024
- unlock,
5025
- isLock
5057
+ isLocked,
5058
+ setLock
5026
5059
  } = editor;
5027
5060
  return {
5028
5061
  name: "mce:lock",
5029
5062
  commands: [
5030
- { command: "lock", handle: () => selection.value.forEach(lock) },
5031
- { command: "unlock", handle: () => selection.value.forEach(unlock) },
5032
- { command: "lock/unlock", handle: () => selection.value.forEach((el) => isLock(el) ? unlock(el) : lock(el)) }
5063
+ { command: "lock", handle: () => selection.value.forEach((el) => setLock(el, true)) },
5064
+ { command: "unlock", handle: () => selection.value.forEach((el) => setLock(el, false)) },
5065
+ { command: "lock/unlock", handle: () => selection.value.forEach((el) => setLock(el, !isLocked(el))) }
5033
5066
  ],
5034
5067
  hotkeys: [
5035
5068
  { command: "lock/unlock", key: "Shift+CmdOrCtrl+l" }
@@ -5125,8 +5158,9 @@ const _menu = definePlugin((editor, options) => {
5125
5158
  ]
5126
5159
  }));
5127
5160
  const objectMenu1 = computed(() => [
5128
- { key: "group/ungroup", disabled: !hasSelected.value },
5129
- { key: "frame/unframe", disabled: !hasSelected.value }
5161
+ { key: "groupSelection", disabled: !hasSelected.value },
5162
+ { key: "frameSelection", disabled: !hasSelected.value },
5163
+ { key: "ungroup", disabled: !(hasSelected.value && selection.value[0]?.children.length) }
5130
5164
  ]);
5131
5165
  const layerOrderMenu = computed(() => ({
5132
5166
  key: "layerOrder",
@@ -5411,7 +5445,7 @@ const _text = definePlugin((editor) => {
5411
5445
  const { style, ...restOptions } = options;
5412
5446
  return addElement(createTextElement(content, style), {
5413
5447
  sizeToFit: true,
5414
- position: "fit",
5448
+ position: "right",
5415
5449
  ...restOptions
5416
5450
  });
5417
5451
  };
@@ -5602,7 +5636,6 @@ const plugins = [
5602
5636
  _copyAs,
5603
5637
  _delete,
5604
5638
  _flip,
5605
- _frame,
5606
5639
  _gif,
5607
5640
  _group,
5608
5641
  _history,
@@ -6364,7 +6397,7 @@ const _sfc_main$v = /* @__PURE__ */ defineComponent({
6364
6397
  const style = computed(() => {
6365
6398
  return {
6366
6399
  ...floatingStyles.value,
6367
- zIndex: 2e3 + overlayItem.index.value
6400
+ zIndex: 1500 + overlayItem.index.value
6368
6401
  };
6369
6402
  });
6370
6403
  const activatorProps = computed(() => {
@@ -7279,15 +7312,11 @@ const _hoisted_1$a = {
7279
7312
  ref: "trackTplRef",
7280
7313
  class: "mce-scrollbar__track"
7281
7314
  };
7282
- const AMOUNT_STEP = 50;
7283
- const AMOUNT_REPEAR_DELAY = 50;
7284
7315
  const _sfc_main$j = /* @__PURE__ */ defineComponent({
7285
7316
  __name: "Scrollbar",
7286
7317
  props: /* @__PURE__ */ mergeModels({
7287
- zoom: {},
7288
7318
  length: {},
7289
7319
  vertical: { type: Boolean },
7290
- infinite: { type: Boolean },
7291
7320
  size: {},
7292
7321
  offset: {}
7293
7322
  }, {
@@ -7298,66 +7327,65 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
7298
7327
  setup(__props, { emit: __emit }) {
7299
7328
  const props = __props;
7300
7329
  const emit = __emit;
7301
- const lerp = (a, b, t) => a * (1 - t) + b * t;
7302
- const thumbToTrack = (thumbLength2, thumbPosition2) => lerp(thumbLength2 / 2, 1 - thumbLength2 / 2, thumbPosition2);
7303
- const offset2 = useModel(__props, "modelValue");
7330
+ const position = useModel(__props, "modelValue");
7304
7331
  const track = useTemplateRef("trackTplRef");
7305
7332
  const thumb = useTemplateRef("thumbTplRef");
7306
7333
  const trackLength = ref(0);
7307
- const contentLength = computed(
7308
- () => props.infinite ? props.length * props.zoom + trackLength.value + Math.abs(offset2.value) * 2 : offset2.value > 0 ? offset2.value + props.length * props.zoom : Math.max(trackLength.value - offset2.value, props.length * props.zoom)
7309
- );
7310
- const scrollOffset = computed(
7311
- () => props.infinite ? Math.abs(offset2.value) - offset2.value : offset2.value > 0 ? 0 : -offset2.value
7312
- );
7334
+ const contentLength = computed(() => {
7335
+ return props.length + trackLength.value + Math.abs(position.value) * 2;
7336
+ });
7313
7337
  const thumbLength = computed(() => {
7314
7338
  return Math.max(0.05, Math.min(1, trackLength.value / contentLength.value));
7315
7339
  });
7316
- const thumbPosition = computed(() => scrollOffset.value / (contentLength.value - trackLength.value) * (1 - thumbLength.value));
7340
+ const thumbPosition = computed(() => {
7341
+ return (Math.abs(position.value) + position.value) / (contentLength.value - trackLength.value) * (1 - thumbLength.value);
7342
+ });
7317
7343
  const resize = useDebounceFn(() => {
7318
7344
  const box = track.value?.getBoundingClientRect() ?? { width: 0, height: 0 };
7319
7345
  trackLength.value = props.vertical ? box.height : box.width;
7320
7346
  }, 50);
7321
- const start = computed(() => props.infinite ? thumbToTrack(thumbLength.value, thumbPosition.value) : thumbPosition.value);
7347
+ const lerp = (a, b, t) => a * (1 - t) + b * t;
7348
+ const thumbToTrack = (thumbLength2, thumbPosition2) => lerp(thumbLength2 / 2, 1 - thumbLength2 / 2, thumbPosition2);
7349
+ const start = computed(() => thumbToTrack(thumbLength.value, thumbPosition.value));
7322
7350
  const end = computed(() => 1 - start.value - thumbLength.value);
7323
7351
  const thumbTop = computed(() => props.vertical ? `${start.value * 100}%` : "0%");
7324
7352
  const thumbBottom = computed(() => props.vertical ? `${end.value * 100}%` : "50%");
7325
7353
  const thumbLeft = computed(() => props.vertical ? "0%" : `${start.value * 100}%`);
7326
7354
  const thumbRight = computed(() => props.vertical ? "50%" : `${end.value * 100}%`);
7327
7355
  function update(val) {
7328
- emit("scroll", val - offset2.value);
7329
- offset2.value = val;
7356
+ emit("scroll", val - position.value);
7357
+ position.value = val;
7330
7358
  }
7331
7359
  function amount(val) {
7332
- update(offset2.value + val);
7333
- }
7334
- const actived = ref(false);
7335
- let clearId;
7336
- function startAmount(e) {
7337
- const el = e.target;
7338
- let direction = 0;
7339
- if (thumb.value?.contains(el)) {
7340
- stopAmount();
7341
- return;
7342
- } else if (track.value?.contains(el)) {
7343
- const point = (props.vertical ? e.offsetY : e.offsetX) / trackLength.value;
7344
- if (point < start.value) {
7345
- direction = 1;
7346
- } else if (point > 1 - end.value) {
7347
- direction = -1;
7348
- } else {
7349
- stopAmount();
7360
+ update(position.value + val);
7361
+ }
7362
+ const isActive = ref(false);
7363
+ watch(track, (track2, oldTrack) => {
7364
+ function onMousedown(event) {
7365
+ if (!thumb.value?.contains(event.target)) {
7350
7366
  return;
7351
7367
  }
7368
+ isActive.value = true;
7369
+ let last = event;
7370
+ event.stopPropagation();
7371
+ function onMousemove(event2) {
7372
+ const offset2 = {
7373
+ x: last.clientX - event2.clientX,
7374
+ y: last.clientY - event2.clientY
7375
+ };
7376
+ last = event2;
7377
+ amount((props.vertical ? offset2.y : offset2.x) / (trackLength.value * (1 - thumbLength.value)) * contentLength.value * -1);
7378
+ }
7379
+ function onMouseup() {
7380
+ isActive.value = false;
7381
+ window.removeEventListener("mousemove", onMousemove);
7382
+ window.removeEventListener("mouseup", onMouseup);
7383
+ }
7384
+ window.addEventListener("mousemove", onMousemove);
7385
+ window.addEventListener("mouseup", onMouseup);
7352
7386
  }
7353
- amount(AMOUNT_STEP * direction);
7354
- clearId = setTimeout(() => startAmount(e), AMOUNT_REPEAR_DELAY);
7355
- }
7356
- function stopAmount() {
7357
- clearTimeout(clearId);
7358
- }
7359
- onBeforeUnmount(() => {
7360
- stopAmount();
7387
+ oldTrack?.removeEventListener("mousedown", onMousedown);
7388
+ track2?.addEventListener("mousedown", onMousedown);
7361
7389
  });
7362
7390
  return (_ctx, _cache) => {
7363
7391
  return withDirectives((openBlock(), createElementBlock("div", {
@@ -7372,10 +7400,10 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
7372
7400
  })
7373
7401
  }, [
7374
7402
  createElementVNode("div", _hoisted_1$a, [
7375
- withDirectives(createElementVNode("div", {
7403
+ createElementVNode("div", {
7376
7404
  ref: "thumbTplRef",
7377
7405
  class: normalizeClass(["mce-scrollbar__thumb", {
7378
- "mce-scrollbar__thumb--active": actived.value
7406
+ "mce-scrollbar__thumb--active": isActive.value
7379
7407
  }]),
7380
7408
  style: normalizeStyle({
7381
7409
  top: thumbTop.value,
@@ -7383,13 +7411,10 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
7383
7411
  left: thumbLeft.value,
7384
7412
  right: thumbRight.value
7385
7413
  })
7386
- }, null, 6), [
7387
- [vShow, props.infinite || thumbLength.value < 1]
7388
- ])
7414
+ }, null, 6)
7389
7415
  ], 512)
7390
7416
  ], 6)), [
7391
- [unref(vResizeObserver), unref(resize)],
7392
- [unref(vOnLongPress), [startAmount, { delay: AMOUNT_REPEAR_DELAY, onMouseUp: stopAmount }]]
7417
+ [unref(vResizeObserver), unref(resize)]
7393
7418
  ]);
7394
7419
  };
7395
7420
  }
@@ -7415,16 +7440,14 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
7415
7440
  createVNode(_sfc_main$j, mergeProps(props, {
7416
7441
  modelValue: unref(camera).position.y,
7417
7442
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(camera).position.y = $event),
7418
- zoom: unref(camera).zoom.y,
7419
7443
  vertical: "",
7420
- length: unref(viewAabb).height
7421
- }), null, 16, ["modelValue", "zoom", "length"]),
7444
+ length: unref(viewAabb).height * unref(camera).zoom.y
7445
+ }), null, 16, ["modelValue", "length"]),
7422
7446
  createVNode(_sfc_main$j, mergeProps(props, {
7423
7447
  modelValue: unref(camera).position.x,
7424
7448
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => unref(camera).position.x = $event),
7425
- zoom: unref(camera).zoom.x,
7426
- length: unref(viewAabb).width
7427
- }), null, 16, ["modelValue", "zoom", "length"])
7449
+ length: unref(viewAabb).width * unref(camera).zoom.x
7450
+ }), null, 16, ["modelValue", "length"])
7428
7451
  ], 64);
7429
7452
  };
7430
7453
  }
@@ -7909,7 +7932,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
7909
7932
  registerCommand,
7910
7933
  unregisterCommand,
7911
7934
  isFrame,
7912
- isLock,
7935
+ isLocked,
7913
7936
  config
7914
7937
  } = useEditor();
7915
7938
  const transformable = useTemplateRef("transformableRef");
@@ -8032,7 +8055,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8032
8055
  modelValue: selectionObb.value,
8033
8056
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectionObb.value = $event),
8034
8057
  visibility: unref(state) !== "selecting" ? "auto" : "none",
8035
- moveable: unref(selection)[0] && !unref(isLock)(unref(selection)[0]),
8058
+ moveable: unref(selection)[0] && !unref(isLocked)(unref(selection)[0]),
8036
8059
  "resize-strategy": props.resizeStrategy,
8037
8060
  "handle-shape": unref(config).handleShape,
8038
8061
  class: "mce-selection-obb",
@@ -8323,7 +8346,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
8323
8346
  const { zoom, position } = camera.value;
8324
8347
  return {
8325
8348
  transformOrigin: "left top",
8326
- transform: `translate(${position.x}px, ${position.y}px) scale(${zoom.x}, ${zoom.y})`
8349
+ transform: `translate(${-position.x}px, ${-position.y}px) scale(${zoom.x}, ${zoom.y})`
8327
8350
  };
8328
8351
  });
8329
8352
  const textEditorStyle = computed(() => {
@@ -8726,7 +8749,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
8726
8749
  isFrame,
8727
8750
  selectArea,
8728
8751
  exec,
8729
- isLock,
8752
+ isLocked,
8730
8753
  selection,
8731
8754
  getAabbInDrawboard,
8732
8755
  drawboardAabb,
@@ -8911,7 +8934,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
8911
8934
  }
8912
8935
  selection.value = selected;
8913
8936
  if (ctxState) {
8914
- if (selected[0] && !isLock(selected[0])) {
8937
+ if (selected[0] && !isLocked(selected[0])) {
8915
8938
  switch (ctxState) {
8916
8939
  case "typing": {
8917
8940
  await exec("startTyping", _event);
@@ -9047,7 +9070,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9047
9070
  root,
9048
9071
  selection,
9049
9072
  exec,
9050
- zoomTo
9073
+ zoomTo,
9074
+ isFrame
9051
9075
  } = useEditor();
9052
9076
  const rootRef = ref();
9053
9077
  const hover = ref();
@@ -9091,9 +9115,16 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9091
9115
  function onClickExpand() {
9092
9116
  opened.value = !opened.value;
9093
9117
  }
9094
- function onClickContent() {
9118
+ function onClickContent(e) {
9095
9119
  if (props.node instanceof Element2D) {
9096
- selection.value = [props.node];
9120
+ if (e.shiftKey) {
9121
+ selection.value = [
9122
+ ...selection.value.filter((v) => !v.equal(props.node)),
9123
+ props.node
9124
+ ];
9125
+ } else {
9126
+ selection.value = [props.node];
9127
+ }
9097
9128
  }
9098
9129
  }
9099
9130
  function onDblclickThumbnail(e) {
@@ -9113,10 +9144,18 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9113
9144
  dom: itemRef.value
9114
9145
  };
9115
9146
  }
9147
+ function onContextmenu(e) {
9148
+ if (props.node instanceof Element2D) {
9149
+ if (!selection.value.some((v) => v.equal(props.node))) {
9150
+ selection.value = [props.node];
9151
+ }
9152
+ exec("openContextMenu", e);
9153
+ }
9154
+ }
9116
9155
  return () => {
9117
9156
  function thumbnail() {
9118
9157
  const node = props.node;
9119
- if (node.meta.inEditorIs === "Frame") {
9158
+ if (isFrame(node)) {
9120
9159
  return createVNode(_sfc_main$w, { icon: "$frame" });
9121
9160
  }
9122
9161
  if (node.children.length > 0) {
@@ -9149,12 +9188,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9149
9188
  },
9150
9189
  ref: itemRef,
9151
9190
  onMouseenter,
9152
- onContextmenu: (e) => {
9153
- if (props.node instanceof Element2D) {
9154
- selection.value = [props.node];
9155
- exec("openContextMenu", e);
9156
- }
9157
- }
9191
+ onContextmenu
9158
9192
  }, [
9159
9193
  createElementVNode("div", {
9160
9194
  class: "mce-layer-item__expand",
@@ -53,8 +53,9 @@ declare const _default: {
53
53
  zoomToFit: string;
54
54
  zoomToSelection: string;
55
55
  object: string;
56
- 'frame/unframe': string;
57
- 'group/ungroup': string;
56
+ groupSelection: string;
57
+ frameSelection: string;
58
+ ungroup: string;
58
59
  flip: string;
59
60
  flipHorizontal: string;
60
61
  flipVertical: string;
@@ -30,9 +30,6 @@ declare global {
30
30
  localDb: boolean;
31
31
  screenCenterOffset: ScreenCenterOffset;
32
32
  }
33
- interface Editor {
34
- getScreenCenterOffset: () => Required<ScreenCenterOffset>;
35
- }
36
33
  }
37
34
  }
38
35
  declare const _default: import("../..").Mixin;
@@ -0,0 +1,27 @@
1
+ import type { Node } from 'modern-canvas';
2
+ import { Element2D } from 'modern-canvas';
3
+ declare global {
4
+ namespace Mce {
5
+ type Tblock = 'top' | 'bottom';
6
+ type Tinline = 'start' | 'end' | 'left' | 'right';
7
+ type Anchor = Tblock | Tinline | 'center' | 'center center' | `${Tblock} ${Tinline | 'center'}` | `${Tinline} ${Tblock | 'center'}`;
8
+ type ParsedAnchor = {
9
+ side: 'center';
10
+ align: 'center';
11
+ } | {
12
+ side: Tblock;
13
+ align: 'left' | 'right' | 'center';
14
+ } | {
15
+ side: 'left' | 'right';
16
+ align: Tblock | 'center';
17
+ };
18
+ interface Editor {
19
+ parseAnchor: (anchor: Anchor, isRtl?: boolean) => ParsedAnchor;
20
+ isFrame: (node: Node) => node is Element2D;
21
+ isLocked: (element: Element2D) => boolean;
22
+ setLock: (element: Element2D, lock: boolean) => void;
23
+ }
24
+ }
25
+ }
26
+ declare const _default: import("..").Mixin;
27
+ export default _default;
@@ -1,7 +1,6 @@
1
- import type { Node } from 'modern-canvas';
1
+ import type { Element2D } from 'modern-canvas';
2
2
  import type { ComputedRef, Ref } from 'vue';
3
3
  import type { AxisAlignedBoundingBox } from '../types';
4
- import { Element2D } from 'modern-canvas';
5
4
  declare global {
6
5
  namespace Mce {
7
6
  interface FrameThumb {
@@ -15,7 +14,6 @@ declare global {
15
14
  currentFrameIndex: Ref<number>;
16
15
  currentFrame: ComputedRef<Element2D | undefined>;
17
16
  currentFrameAabb: ComputedRef<AxisAlignedBoundingBox>;
18
- isFrame: (node: Node) => node is Element2D;
19
17
  getAncestorFrame: (element?: Element2D) => Element2D | undefined;
20
18
  }
21
19
  }
@@ -0,0 +1,13 @@
1
+ declare global {
2
+ namespace Mce {
3
+ interface Editor {
4
+ getScreenCenterOffset: () => Required<ScreenCenterOffset>;
5
+ getScreenCenter: () => {
6
+ x: number;
7
+ y: number;
8
+ };
9
+ }
10
+ }
11
+ }
12
+ declare const _default: import("..").Mixin;
13
+ export default _default;
@@ -1,12 +1,14 @@
1
- import type { Element2D, Vector2Data } from 'modern-canvas';
1
+ import type { Element2D, Node, Vector2Data } from 'modern-canvas';
2
2
  import type { Element } from 'modern-idoc';
3
3
  import type { AxisAlignedBoundingBox } from '../types';
4
4
  declare global {
5
5
  namespace Mce {
6
+ type AddElementPosition = Vector2Data | Anchor | 'screenCenter' | 'pointer';
6
7
  interface AddElementOptions {
7
- frame?: Element2D;
8
+ position?: AddElementPosition;
9
+ parent?: Node;
10
+ index?: number;
8
11
  sizeToFit?: boolean;
9
- position?: Vector2Data | 'fit' | 'screenCenter' | 'pointer';
10
12
  active?: boolean;
11
13
  regenId?: boolean;
12
14
  }
@@ -2,14 +2,22 @@ import type { Document, Element } from 'modern-idoc';
2
2
  import { Doc } from '../models';
3
3
  declare global {
4
4
  namespace Mce {
5
+ interface InternalDocument extends Document {
6
+ id: string;
7
+ meta: {
8
+ [key: string]: any;
9
+ inEditorIs: 'Doc';
10
+ };
11
+ }
12
+ type DocumentSource = InternalDocument | Element[] | string;
5
13
  interface Editor {
6
14
  getDoc: () => JsonData;
7
- setDoc: (doc: Document | Element[] | string) => Promise<Doc>;
15
+ setDoc: (doc: DocumentSource) => Promise<Doc>;
8
16
  loadDoc: (source: any) => Promise<Doc>;
9
17
  clearDoc: () => void;
10
18
  }
11
19
  interface Options {
12
- doc?: Document | string;
20
+ doc?: DocumentSource;
13
21
  }
14
22
  interface Events {
15
23
  setDoc: [doc: Doc];
@@ -12,7 +12,7 @@ declare global {
12
12
  copy: (data?: any) => Promise<void>;
13
13
  cut: () => Promise<void>;
14
14
  paste: (source?: PasteSource) => Promise<void>;
15
- duplicate: () => Promise<void>;
15
+ duplicate: () => void;
16
16
  }
17
17
  interface Editor {
18
18
  copiedData: Ref<any | undefined>;
@@ -1,12 +1,14 @@
1
1
  declare global {
2
2
  namespace Mce {
3
3
  interface Commands {
4
- 'group': () => void;
5
- 'ungroup': () => void;
6
- 'group/ungroup': () => void;
4
+ groupSelection: () => void;
5
+ frameSelection: () => void;
6
+ ungroup: () => void;
7
7
  }
8
8
  interface Hotkeys {
9
- 'group/ungroup': [event: KeyboardEvent];
9
+ groupSelection: [event: KeyboardEvent];
10
+ frameSelection: [event: KeyboardEvent];
11
+ ungroup: [event: KeyboardEvent];
10
12
  }
11
13
  }
12
14
  }
@@ -12,7 +12,8 @@ declare global {
12
12
  children: NormalizedElement[];
13
13
  meta: {
14
14
  inPptIs: 'Pptx';
15
- inCanvasIs: 'Node2D';
15
+ inEditorIs: 'Doc';
16
+ inCanvasIs: 'Element2D';
16
17
  startTime: number;
17
18
  endTime: number;
18
19
  };
@@ -8,9 +8,11 @@ import './mixins/0.config/base'
8
8
  import './mixins/0.context'
9
9
  import './mixins/0.element'
10
10
  import './mixins/0.font'
11
+ import './mixins/0.helper'
11
12
  import './mixins/0.locale'
12
13
  import './mixins/1.frame'
13
14
  import './mixins/1.hotkey'
15
+ import './mixins/1.screen'
14
16
  import './mixins/1.timeline'
15
17
  import './mixins/1.upload'
16
18
  import './mixins/2.box'
@@ -18,7 +20,6 @@ import './mixins/2.export'
18
20
  import './mixins/2.load'
19
21
  import './mixins/3.view'
20
22
  import './mixins/4.0.text'
21
- import './mixins/4.1.lock'
22
23
  import './mixins/4.2.element'
23
24
  import './mixins/4.3.frame'
24
25
  import './mixins/4.4.doc'
@@ -30,7 +31,6 @@ import './plugins/clipboard'
30
31
  import './plugins/copyAs'
31
32
  import './plugins/delete'
32
33
  import './plugins/flip'
33
- import './plugins/frame'
34
34
  import './plugins/gif'
35
35
  import './plugins/group'
36
36
  import './plugins/history'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mce",
3
3
  "type": "module",
4
- "version": "0.12.1",
4
+ "version": "0.12.3",
5
5
  "description": "The headless canvas editor framework. only the ESM.",
6
6
  "author": "wxm",
7
7
  "license": "MIT",
@@ -1,12 +0,0 @@
1
- import type { Element2D } from 'modern-canvas';
2
- declare global {
3
- namespace Mce {
4
- interface Editor {
5
- isLock: (element: Element2D) => boolean;
6
- lock: (element: Element2D) => void;
7
- unlock: (element: Element2D) => void;
8
- }
9
- }
10
- }
11
- declare const _default: import("..").Mixin;
12
- export default _default;
@@ -1,14 +0,0 @@
1
- declare global {
2
- namespace Mce {
3
- interface Commands {
4
- 'frame': () => void;
5
- 'unframe': () => void;
6
- 'frame/unframe': () => void;
7
- }
8
- interface Hotkeys {
9
- 'frame/unframe': [event: KeyboardEvent];
10
- }
11
- }
12
- }
13
- declare const _default: import("..").Plugin;
14
- export default _default;