mce 0.13.5 → 0.13.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Node as Node$1, Element2D, Timeline, Engine, Camera2D, DrawboardEffect, IN_BROWSER, clamp, assets, TimelineNode, Transform2D, DEG_TO_RAD, render, Animation } from "modern-canvas";
2
- import { ref, computed, watch, markRaw, reactive, warn, shallowRef, onBeforeUnmount, onMounted, inject, provide, defineComponent, createVNode, mergeProps, createElementVNode, toValue, getCurrentInstance, onScopeDispose, createElementBlock, openBlock, Fragment, renderList, unref, normalizeStyle, normalizeClass, readonly, toRef, useId, onDeactivated, onActivated, useAttrs, createBlock, resolveDynamicComponent, useTemplateRef, renderSlot, Teleport, createCommentVNode, mergeModels, useModel, resolveComponent, withCtx, createTextVNode, toDisplayString, createSlots, normalizeProps, guardReactiveProps, onBeforeMount, withDirectives, vShow, vModelText, nextTick, withModifiers, h, isRef } from "vue";
3
- import { useFileDialog, useEventListener, isClient, useResizeObserver as useResizeObserver$1, useLocalStorage, onClickOutside, useMouse, useDebounceFn } from "@vueuse/core";
4
- import { getObjectValueByPath, setObjectValueByPath, Observable, Reactivable, idGenerator, property, normalizeElement, normalizeTextContent } from "modern-idoc";
2
+ import { ref, computed, watch, markRaw, reactive, warn, shallowRef, onBeforeUnmount, onMounted, inject, getCurrentInstance, defineComponent, createVNode, mergeProps, createElementVNode, toValue, onScopeDispose, provide, createElementBlock, openBlock, Fragment, renderList, unref, normalizeStyle, normalizeClass, readonly, toRef, useId, onDeactivated, onActivated, useAttrs, createBlock, resolveDynamicComponent, useTemplateRef, renderSlot, Teleport, createCommentVNode, mergeModels, useModel, resolveComponent, withCtx, createTextVNode, toDisplayString, createSlots, normalizeProps, guardReactiveProps, onBeforeMount, nextTick, h, withDirectives, vShow, vModelText, withModifiers, isRef } from "vue";
3
+ import { useFileDialog, useEventListener, isClient, useResizeObserver as useResizeObserver$1, useLocalStorage, onClickOutside, useMouse, useImage, useDebounceFn } from "@vueuse/core";
4
+ import { getObjectValueByPath, setObjectValueByPath, Observable, Reactivable, idGenerator, property, normalizeElement, normalizeTextContent, normalizeCRLF, isEqualObject } from "modern-idoc";
5
5
  import { saveAs } from "file-saver";
6
6
  import { Fonts } from "modern-font";
7
7
  import * as Y from "yjs";
@@ -902,7 +902,7 @@ const _0_context = defineMixin((editor) => {
902
902
  const nodeIndexMap = reactive(/* @__PURE__ */ new Map());
903
903
  const selection = ref([]);
904
904
  const elementSelection = computed({
905
- get: () => selection.value.filter((v) => v instanceof Element2D),
905
+ get: () => selection.value.filter((v) => isElement(v)),
906
906
  set: (val) => selection.value = val
907
907
  });
908
908
  const textSelection = ref();
@@ -930,6 +930,48 @@ const _0_context = defineMixin((editor) => {
930
930
  y: y - drawboardAabb.value.top
931
931
  }, { x: 0, y: 0 });
932
932
  }
933
+ const block = ["top", "bottom"];
934
+ const inline = ["start", "end", "left", "right"];
935
+ function toPhysical(str, isRtl) {
936
+ if (str === "start")
937
+ return isRtl ? "right" : "left";
938
+ if (str === "end")
939
+ return isRtl ? "left" : "right";
940
+ return str;
941
+ }
942
+ const parseAnchor = (anchor, isRtl) => {
943
+ let [side, align] = anchor.split(" ");
944
+ if (!align) {
945
+ align = block.includes(side) ? "start" : inline.includes(side) ? "top" : "center";
946
+ }
947
+ return {
948
+ side: toPhysical(side, isRtl),
949
+ align: toPhysical(align, isRtl)
950
+ };
951
+ };
952
+ function isRoot(value) {
953
+ return value instanceof Node$1 && root.value.equal(value);
954
+ }
955
+ function isElement(value) {
956
+ return value instanceof Element2D;
957
+ }
958
+ function isFrame(value) {
959
+ return isElement(value) && value.meta.inEditorIs === "Frame";
960
+ }
961
+ function isVisible(node) {
962
+ return isElement(node) && node.style.visibility === "visible";
963
+ }
964
+ function setVisible(node, visible) {
965
+ if (isElement(node)) {
966
+ node.style.visibility = visible ? "visible" : "hidden";
967
+ }
968
+ }
969
+ function isLock(node) {
970
+ return Boolean(node.meta.lock);
971
+ }
972
+ function setLock(node, lock) {
973
+ node.meta.lock = lock;
974
+ }
933
975
  Object.assign(editor, {
934
976
  fonts,
935
977
  renderEngine,
@@ -951,7 +993,15 @@ const _0_context = defineMixin((editor) => {
951
993
  setState,
952
994
  setCursor,
953
995
  drawboardPointer,
954
- getGlobalPointer
996
+ getGlobalPointer,
997
+ parseAnchor,
998
+ isRoot,
999
+ isElement,
1000
+ isFrame,
1001
+ isVisible,
1002
+ setVisible,
1003
+ isLock,
1004
+ setLock
955
1005
  });
956
1006
  return () => {
957
1007
  const {
@@ -1025,63 +1075,6 @@ const _0_font = defineMixin((editor, options) => {
1025
1075
  }
1026
1076
  };
1027
1077
  });
1028
- const _0_helper = defineMixin((editor) => {
1029
- const {
1030
- root
1031
- } = editor;
1032
- const block = ["top", "bottom"];
1033
- const inline = ["start", "end", "left", "right"];
1034
- function toPhysical(str, isRtl) {
1035
- if (str === "start")
1036
- return isRtl ? "right" : "left";
1037
- if (str === "end")
1038
- return isRtl ? "left" : "right";
1039
- return str;
1040
- }
1041
- const parseAnchor = (anchor, isRtl) => {
1042
- let [side, align] = anchor.split(" ");
1043
- if (!align) {
1044
- align = block.includes(side) ? "start" : inline.includes(side) ? "top" : "center";
1045
- }
1046
- return {
1047
- side: toPhysical(side, isRtl),
1048
- align: toPhysical(align, isRtl)
1049
- };
1050
- };
1051
- function isRoot(value) {
1052
- return value instanceof Node$1 && root.value.equal(value);
1053
- }
1054
- function isElement(value) {
1055
- return value instanceof Element2D;
1056
- }
1057
- function isFrame(value) {
1058
- return isElement(value) && value.meta.inEditorIs === "Frame";
1059
- }
1060
- function isVisible(node) {
1061
- return isElement(node) && node.style.visibility === "visible";
1062
- }
1063
- function setVisible(node, visible) {
1064
- if (isElement(node)) {
1065
- node.style.visibility = visible ? "visible" : "hidden";
1066
- }
1067
- }
1068
- function isLock(node) {
1069
- return Boolean(node.meta.lock);
1070
- }
1071
- function setLock(node, lock) {
1072
- node.meta.lock = lock;
1073
- }
1074
- Object.assign(editor, {
1075
- parseAnchor,
1076
- isRoot,
1077
- isElement,
1078
- isFrame,
1079
- isVisible,
1080
- setVisible,
1081
- isLock,
1082
- setLock
1083
- });
1084
- });
1085
1078
  const en = {
1086
1079
  "cancel": "Cancel",
1087
1080
  "constrainToAxis": "Constrain to axis",
@@ -1866,7 +1859,7 @@ const _2_box = defineMixin((editor) => {
1866
1859
  };
1867
1860
  let flag = false;
1868
1861
  element.children.forEach((child) => {
1869
- if (child instanceof Element2D) {
1862
+ if (isElement(child)) {
1870
1863
  const _minmax = child.getAabb().toMinmax();
1871
1864
  minmax.minX = Math.min(minmax.minX, _minmax.minX);
1872
1865
  minmax.minY = Math.min(minmax.minY, _minmax.minY);
@@ -1884,7 +1877,7 @@ const _2_box = defineMixin((editor) => {
1884
1877
  };
1885
1878
  const aabbs = {};
1886
1879
  element.children.forEach((child, index) => {
1887
- if (child instanceof Element2D) {
1880
+ if (isElement(child)) {
1888
1881
  aabbs[index] = child.getGlobalAabb();
1889
1882
  }
1890
1883
  });
@@ -1894,7 +1887,7 @@ const _2_box = defineMixin((editor) => {
1894
1887
  element.style.height = box.height;
1895
1888
  element.updateGlobalTransform();
1896
1889
  element.children.forEach((child, index) => {
1897
- if (child instanceof Element2D) {
1890
+ if (isElement(child)) {
1898
1891
  child.updateGlobalTransform();
1899
1892
  const oldAabb = aabbs[index];
1900
1893
  const localCenter = child.toLocal({
@@ -1949,7 +1942,7 @@ const _2_box = defineMixin((editor) => {
1949
1942
  obb.top -= position.y;
1950
1943
  } else if (inTarget === "frame") {
1951
1944
  const first = Array.isArray(node) ? node[0] : node;
1952
- if (first instanceof Element2D) {
1945
+ if (isElement(first)) {
1953
1946
  const frame = getAncestorFrame(first);
1954
1947
  if (frame) {
1955
1948
  obb.left -= frame.style.left;
@@ -1958,8 +1951,8 @@ const _2_box = defineMixin((editor) => {
1958
1951
  }
1959
1952
  } else if (inTarget === "parent") {
1960
1953
  const first = Array.isArray(node) ? node[0] : node;
1961
- if (first instanceof Element2D) {
1962
- const parent = first.findAncestor((el) => el instanceof Element2D);
1954
+ if (isElement(first)) {
1955
+ const parent = first.findAncestor((el) => isElement(el));
1963
1956
  if (parent) {
1964
1957
  const parentBox = getAabb(parent);
1965
1958
  obb.left -= parentBox.left;
@@ -1969,9 +1962,6 @@ const _2_box = defineMixin((editor) => {
1969
1962
  }
1970
1963
  return obb;
1971
1964
  }
1972
- function getObbInDrawboard(node) {
1973
- return getObb(node, "drawboard");
1974
- }
1975
1965
  function getAabb(node, inTarget) {
1976
1966
  let aabb;
1977
1967
  if (Array.isArray(node) && node.length > 0) {
@@ -1985,7 +1975,7 @@ const _2_box = defineMixin((editor) => {
1985
1975
  maxY: Number.MIN_SAFE_INTEGER
1986
1976
  };
1987
1977
  node.forEach((child) => {
1988
- if (child instanceof Element2D) {
1978
+ if (isElement(child)) {
1989
1979
  const aabb2 = getAabb(child);
1990
1980
  minmax.minX = Math.min(minmax.minX, aabb2.left);
1991
1981
  minmax.minY = Math.min(minmax.minY, aabb2.top);
@@ -2017,7 +2007,7 @@ const _2_box = defineMixin((editor) => {
2017
2007
  aabb = aabbToDrawboardAabb(aabb);
2018
2008
  } else if (inTarget === "frame") {
2019
2009
  const first = Array.isArray(node) ? node[0] : node;
2020
- if (first instanceof Element2D) {
2010
+ if (isElement(first)) {
2021
2011
  const frame = getAncestorFrame(first);
2022
2012
  if (frame) {
2023
2013
  aabb.left -= frame.style.left;
@@ -2026,8 +2016,8 @@ const _2_box = defineMixin((editor) => {
2026
2016
  }
2027
2017
  } else if (inTarget === "parent") {
2028
2018
  const first = Array.isArray(node) ? node[0] : node;
2029
- if (first instanceof Element2D) {
2030
- const parent = first.findAncestor((el) => el instanceof Element2D);
2019
+ if (isElement(first)) {
2020
+ const parent = first.findAncestor((el) => isElement(el));
2031
2021
  if (parent) {
2032
2022
  const parentBox = getAabb(parent);
2033
2023
  aabb.left -= parentBox.left;
@@ -2037,9 +2027,6 @@ const _2_box = defineMixin((editor) => {
2037
2027
  }
2038
2028
  return aabb;
2039
2029
  }
2040
- function getAabbInDrawboard(node) {
2041
- return getAabb(node, "drawboard");
2042
- }
2043
2030
  function aabbToDrawboardAabb(aabb) {
2044
2031
  const _aabb = { ...aabb };
2045
2032
  const zoom = camera.value.zoom;
@@ -2054,15 +2041,19 @@ const _2_box = defineMixin((editor) => {
2054
2041
  }
2055
2042
  const rootAabb = computed(() => getAabb(root.value.children));
2056
2043
  const selectionAabb = computed(() => getAabb(selection.value));
2044
+ const selectionAabbInDrawboard = computed(() => getAabb(selection.value, "drawboard"));
2045
+ const selectionObb = computed(() => getObb(selection.value));
2046
+ const selectionObbInDrawboard = computed(() => getObb(selection.value, "drawboard"));
2057
2047
  Object.assign(editor, {
2058
2048
  obbToFit,
2059
2049
  getObb,
2060
- getObbInDrawboard,
2061
2050
  getAabb,
2062
- getAabbInDrawboard,
2063
2051
  aabbToDrawboardAabb,
2064
2052
  rootAabb,
2065
- selectionAabb
2053
+ selectionAabb,
2054
+ selectionAabbInDrawboard,
2055
+ selectionObb,
2056
+ selectionObbInDrawboard
2066
2057
  });
2067
2058
  });
2068
2059
  const _2_export = defineMixin((editor) => {
@@ -2227,6 +2218,7 @@ const _3_view = defineMixin((editor) => {
2227
2218
  });
2228
2219
  return () => {
2229
2220
  const {
2221
+ isElement,
2230
2222
  root,
2231
2223
  currentFrame,
2232
2224
  on,
@@ -2236,14 +2228,14 @@ const _3_view = defineMixin((editor) => {
2236
2228
  switch (config.value.viewMode) {
2237
2229
  case "frame":
2238
2230
  root.value.children.forEach((child) => {
2239
- if (child instanceof Element2D) {
2231
+ if (isElement(child)) {
2240
2232
  child.visible = child.equal(currentFrame.value);
2241
2233
  }
2242
2234
  });
2243
2235
  break;
2244
2236
  case "edgeless":
2245
2237
  root.value.children.forEach((child) => {
2246
- if (child instanceof Element2D) {
2238
+ if (isElement(child)) {
2247
2239
  child.visible = true;
2248
2240
  }
2249
2241
  });
@@ -2258,12 +2250,15 @@ const _3_view = defineMixin((editor) => {
2258
2250
  });
2259
2251
  const _4_0_text = defineMixin((editor) => {
2260
2252
  const {
2261
- config
2253
+ isElement,
2254
+ config,
2255
+ elementSelection,
2256
+ textSelection
2262
2257
  } = editor;
2263
- function textFontSizeToFit(element, scale) {
2264
- function _handle(element2) {
2258
+ function textFontSizeToFit(element2, scale) {
2259
+ function _handle(element3) {
2265
2260
  if (!scale) {
2266
- const chars = element2.text.base.characters;
2261
+ const chars = element3.text.base.characters;
2267
2262
  let pos = 0;
2268
2263
  let char;
2269
2264
  chars.forEach((_char) => {
@@ -2284,7 +2279,7 @@ const _4_0_text = defineMixin((editor) => {
2284
2279
  }).join("");
2285
2280
  const { boundingBox } = measureText({
2286
2281
  style: {
2287
- ...element2.style.toJSON(),
2282
+ ...element3.style.toJSON(),
2288
2283
  width: "auto"
2289
2284
  },
2290
2285
  content: [
@@ -2295,8 +2290,8 @@ const _4_0_text = defineMixin((editor) => {
2295
2290
  }
2296
2291
  ]
2297
2292
  });
2298
- const fontSize = (element2.style.fontSize || 12) / 2;
2299
- scale = (element2.style.width ?? 0) / (boundingBox.width + fontSize);
2293
+ const fontSize = (element3.style.fontSize || 12) / 2;
2294
+ scale = (element3.style.width ?? 0) / (boundingBox.width + fontSize);
2300
2295
  }
2301
2296
  function _scaleStyle(style) {
2302
2297
  if (style.fontSize)
@@ -2304,38 +2299,38 @@ const _4_0_text = defineMixin((editor) => {
2304
2299
  if (style.letterSpacing)
2305
2300
  style.letterSpacing = style.letterSpacing * scale;
2306
2301
  }
2307
- _scaleStyle(element2.style);
2308
- if (element2.text?.isValid?.() && Array.isArray(element2.text?.content)) {
2309
- element2.text.content.forEach((p) => {
2302
+ _scaleStyle(element3.style);
2303
+ if (element3.text?.isValid?.() && Array.isArray(element3.text?.content)) {
2304
+ element3.text.content.forEach((p) => {
2310
2305
  _scaleStyle(p);
2311
2306
  p.fragments.forEach((f) => {
2312
2307
  _scaleStyle(f);
2313
2308
  });
2314
2309
  });
2315
2310
  }
2316
- element2.requestRedraw();
2311
+ element3.requestRedraw();
2317
2312
  }
2318
- _handle(element);
2319
- element.findOne((descendant) => {
2320
- if (descendant instanceof Element2D) {
2313
+ _handle(element2);
2314
+ element2.findOne((descendant) => {
2315
+ if (isElement(descendant)) {
2321
2316
  _handle(descendant);
2322
2317
  }
2323
2318
  return false;
2324
2319
  });
2325
2320
  }
2326
- function textToFit(element, typography) {
2321
+ function textToFit(element2, typography) {
2327
2322
  const strategy = typography ?? config.value.typographyStrategy;
2328
2323
  if (strategy === "fixedWidthHeight") {
2329
2324
  return;
2330
2325
  } else if (strategy === "autoFontSize") {
2331
- textFontSizeToFit(element);
2326
+ textFontSizeToFit(element2);
2332
2327
  return;
2333
2328
  }
2334
- function _handle(element2) {
2335
- if (!element2.text?.isValid?.() || typeof element2.text?.content !== "object") {
2329
+ function _handle(element3) {
2330
+ if (!element3.text?.isValid?.() || typeof element3.text?.content !== "object") {
2336
2331
  return;
2337
2332
  }
2338
- const style = element2.style.toJSON();
2333
+ const style = element3.style.toJSON();
2339
2334
  switch (strategy) {
2340
2335
  case "autoWidth":
2341
2336
  style.width = "auto";
@@ -2346,25 +2341,205 @@ const _4_0_text = defineMixin((editor) => {
2346
2341
  }
2347
2342
  const { boundingBox } = measureText({
2348
2343
  style,
2349
- content: element2.text.content
2344
+ content: element3.text.content
2350
2345
  });
2351
- if (element2.style.width !== boundingBox.width || element2.style.height !== boundingBox.height) {
2352
- element2.style.width = boundingBox.width;
2353
- element2.style.height = boundingBox.height;
2354
- element2.requestRedraw();
2346
+ if (element3.style.width !== boundingBox.width || element3.style.height !== boundingBox.height) {
2347
+ element3.style.width = boundingBox.width;
2348
+ element3.style.height = boundingBox.height;
2349
+ element3.requestRedraw();
2355
2350
  }
2356
2351
  }
2357
- _handle(element);
2358
- element.findOne((descendant) => {
2359
- if (descendant instanceof Element2D) {
2352
+ _handle(element2);
2353
+ element2.findOne((descendant) => {
2354
+ if (isElement(descendant)) {
2360
2355
  _handle(descendant);
2361
2356
  }
2362
2357
  return false;
2363
2358
  });
2364
2359
  }
2360
+ const element = computed(() => elementSelection.value[0]);
2361
+ const hasSelectionRange = computed(() => {
2362
+ return (textSelection.value?.length ?? 0) > 1 && textSelection.value[0] !== textSelection.value[1];
2363
+ });
2364
+ function handleSelection([start, end], cb) {
2365
+ let flag = true;
2366
+ element.value?.text?.content.forEach((p, pIndex, pItems) => {
2367
+ if (!flag)
2368
+ return;
2369
+ p.fragments.forEach((f, fIndex, fItems) => {
2370
+ if (!flag)
2371
+ return;
2372
+ const { content, ...fStyle } = f;
2373
+ Array.from(normalizeCRLF(content)).forEach((c, cIndex, cItems) => {
2374
+ flag = cb({
2375
+ selected: (pIndex > start.paragraphIndex || pIndex === start.paragraphIndex && fIndex > start.fragmentIndex || pIndex === start.paragraphIndex && fIndex === start.fragmentIndex && cIndex >= start.charIndex) && (pIndex < end.paragraphIndex || pIndex === end.paragraphIndex && fIndex < end.fragmentIndex || pIndex === end.paragraphIndex && fIndex === end.fragmentIndex && (end.isLastSelected ? cIndex <= end.charIndex : cIndex < end.charIndex)),
2376
+ p,
2377
+ pIndex,
2378
+ pLength: pItems.length,
2379
+ f,
2380
+ fIndex,
2381
+ fStyle,
2382
+ fLength: fItems.length,
2383
+ c,
2384
+ cLength: cItems.length,
2385
+ cIndex
2386
+ });
2387
+ });
2388
+ });
2389
+ });
2390
+ }
2391
+ function getTextStyle(key) {
2392
+ if (!element.value) {
2393
+ return void 0;
2394
+ }
2395
+ let value = element.value.style[key];
2396
+ const content = element.value.text.content;
2397
+ if (hasSelectionRange.value) {
2398
+ const selection = textSelection.value;
2399
+ if (selection && selection[0] && selection[1]) {
2400
+ handleSelection(selection, ({ selected, fStyle }) => {
2401
+ if (selected && fStyle[key]) {
2402
+ value = fStyle[key];
2403
+ return false;
2404
+ }
2405
+ return true;
2406
+ });
2407
+ }
2408
+ } else {
2409
+ switch (key) {
2410
+ case "fontSize":
2411
+ return content?.reduce((prev, p) => {
2412
+ return p.fragments.reduce((prev2, f) => {
2413
+ return ~~Math.max(prev2, f[key] ?? 0);
2414
+ }, prev);
2415
+ }, value) ?? value;
2416
+ default:
2417
+ if (content.length === 1 && content[0].fragments.length === 1 && content[0].fragments[0][key]) {
2418
+ return content[0].fragments[0][key];
2419
+ }
2420
+ }
2421
+ }
2422
+ return value;
2423
+ }
2424
+ function setTextStyle(key, value) {
2425
+ if (!element.value) {
2426
+ return;
2427
+ }
2428
+ let isAllSelected = false;
2429
+ if (hasSelectionRange.value) {
2430
+ const selection = textSelection.value;
2431
+ if (selection && selection[0] && selection[1]) {
2432
+ if (selection[0].isFirst && selection[1].isLast && selection[1].isLastSelected) {
2433
+ isAllSelected = true;
2434
+ } else {
2435
+ const newContent = [];
2436
+ let newParagraph = { fragments: [] };
2437
+ let newFragment;
2438
+ handleSelection(selection, ({ selected, fIndex, fStyle, fLength, c, cIndex, cLength }) => {
2439
+ if (fIndex === 0 && cIndex === 0) {
2440
+ newParagraph = { fragments: [] };
2441
+ newFragment = void 0;
2442
+ }
2443
+ const style = { ...fStyle };
2444
+ if (selected) {
2445
+ style[key] = value;
2446
+ }
2447
+ if (newFragment) {
2448
+ const { content: _, ..._style } = newFragment;
2449
+ if (isEqualObject(style, _style)) {
2450
+ newFragment.content += c;
2451
+ } else {
2452
+ newParagraph.fragments.push(newFragment);
2453
+ newFragment = { ...style, content: c };
2454
+ }
2455
+ } else {
2456
+ newFragment = { ...style, content: c };
2457
+ }
2458
+ if (fIndex === fLength - 1 && cIndex === cLength - 1) {
2459
+ if (newFragment) {
2460
+ newParagraph.fragments.push(newFragment);
2461
+ }
2462
+ if (newParagraph.fragments.length) {
2463
+ newContent.push(newParagraph);
2464
+ newParagraph = { fragments: [] };
2465
+ }
2466
+ }
2467
+ return true;
2468
+ });
2469
+ if (newContent.length) {
2470
+ element.value.text.content = newContent;
2471
+ }
2472
+ }
2473
+ }
2474
+ } else {
2475
+ isAllSelected = true;
2476
+ }
2477
+ if (isAllSelected) {
2478
+ const el = element.value;
2479
+ switch (key) {
2480
+ case "fill":
2481
+ case "outline":
2482
+ el.text[key] = value;
2483
+ break;
2484
+ default:
2485
+ el.style[key] = value;
2486
+ break;
2487
+ }
2488
+ const content = element.value.text.content;
2489
+ content.forEach((p) => {
2490
+ delete p[key];
2491
+ p.fragments.forEach((f) => {
2492
+ delete f[key];
2493
+ });
2494
+ });
2495
+ el.text.content = content;
2496
+ }
2497
+ element.value.requestRedraw();
2498
+ textToFit(element.value);
2499
+ }
2500
+ function getTextFill() {
2501
+ if (!element.value) {
2502
+ return void 0;
2503
+ }
2504
+ let fill;
2505
+ if (hasSelectionRange.value) {
2506
+ fill = getTextStyle("fill");
2507
+ if (!fill) {
2508
+ const color = getTextStyle("color");
2509
+ fill = { color };
2510
+ }
2511
+ }
2512
+ fill = fill ?? element.value.text.fill ?? { color: element.value.style.color };
2513
+ return fill;
2514
+ }
2515
+ function setTextFill(value) {
2516
+ if (!element.value) {
2517
+ return;
2518
+ }
2519
+ if (hasSelectionRange.value && value?.color) {
2520
+ setTextStyle("fill", value);
2521
+ } else {
2522
+ element.value.text.fill = value;
2523
+ if (value?.color) {
2524
+ element.value.style.color = value.color;
2525
+ }
2526
+ element.value.text.content.forEach((p) => {
2527
+ delete p.fill;
2528
+ delete p.color;
2529
+ p.fragments.forEach((f) => {
2530
+ delete f.fill;
2531
+ delete f.color;
2532
+ });
2533
+ });
2534
+ }
2535
+ }
2365
2536
  Object.assign(editor, {
2366
2537
  textFontSizeToFit,
2367
- textToFit
2538
+ textToFit,
2539
+ setTextStyle,
2540
+ getTextStyle,
2541
+ getTextFill,
2542
+ setTextFill
2368
2543
  });
2369
2544
  return () => {
2370
2545
  TextEditor.register();
@@ -2382,7 +2557,7 @@ const _4_2_element = defineMixin((editor) => {
2382
2557
  root,
2383
2558
  isFrame,
2384
2559
  isLock,
2385
- getObbInDrawboard,
2560
+ getObb,
2386
2561
  config,
2387
2562
  getAncestorFrame,
2388
2563
  getAabb,
@@ -2603,7 +2778,7 @@ const _4_2_element = defineMixin((editor) => {
2603
2778
  }
2604
2779
  return [node];
2605
2780
  }).filter((node) => {
2606
- return "isVisibleInTree" in node && node.isVisibleInTree() && isOverlappingObb(areaInDrawboard, getObbInDrawboard(node)) && !isLock(node);
2781
+ return "isVisibleInTree" in node && node.isVisibleInTree() && isOverlappingObb(areaInDrawboard, getObb(node, "drawboard")) && !isLock(node);
2607
2782
  }) ?? [];
2608
2783
  selection.value = selected;
2609
2784
  return selected;
@@ -2878,6 +3053,7 @@ const _scroll$1 = defineMixin((editor) => {
2878
3053
  });
2879
3054
  const _snapshot = defineMixin((editor) => {
2880
3055
  const {
3056
+ isElement,
2881
3057
  renderEngine,
2882
3058
  frames,
2883
3059
  currentFrameAabb,
@@ -2897,7 +3073,7 @@ const _snapshot = defineMixin((editor) => {
2897
3073
  async function captureElementScreenshot(element) {
2898
3074
  await editor.waitUntilFontLoad();
2899
3075
  let data;
2900
- if (element instanceof Element2D) {
3076
+ if (isElement(element)) {
2901
3077
  data = element.toJSON();
2902
3078
  } else {
2903
3079
  data = { ...element };
@@ -3101,7 +3277,6 @@ const mixins = [
3101
3277
  _0_config_base,
3102
3278
  _0_context,
3103
3279
  _0_font,
3104
- _0_helper,
3105
3280
  _0_locale,
3106
3281
  _1_frame,
3107
3282
  _1_hotkey,
@@ -4083,10 +4258,11 @@ function isLeftTopLine(line) {
4083
4258
  }
4084
4259
  const _auxiliary = definePlugin((editor) => {
4085
4260
  const {
4261
+ isElement,
4086
4262
  currentFrame,
4087
4263
  elementSelection,
4088
4264
  state,
4089
- getObbInDrawboard,
4265
+ getObb,
4090
4266
  root
4091
4267
  } = editor;
4092
4268
  function createBox(node) {
@@ -4099,7 +4275,7 @@ const _auxiliary = definePlugin((editor) => {
4099
4275
  let width;
4100
4276
  if (node.instanceId) {
4101
4277
  box.id = node.instanceId;
4102
- ({ top, left, height, width } = getObbInDrawboard(node));
4278
+ ({ top, left, height, width } = getObb(node, "drawboard"));
4103
4279
  } else {
4104
4280
  box.id = Math.random();
4105
4281
  ({ top, left, height, width } = node);
@@ -4128,7 +4304,7 @@ const _auxiliary = definePlugin((editor) => {
4128
4304
  });
4129
4305
  const parnet = computed(() => {
4130
4306
  const p = elementSelection.value[0].parent;
4131
- return p instanceof Element2D ? p : void 0;
4307
+ return isElement(p) ? p : void 0;
4132
4308
  });
4133
4309
  const parentBox = computed(() => createBox(
4134
4310
  parnet.value ?? { left: 0, top: 0, width: 0, height: 0 }
@@ -4903,9 +5079,11 @@ const _image = definePlugin((editor) => {
4903
5079
  onBefore: (engine) => {
4904
5080
  engine.root.append(
4905
5081
  new DrawboardEffect({
5082
+ ...drawboardEffect.value.getProperties(),
4906
5083
  internalMode: "back",
4907
5084
  effectMode: "before",
4908
- ...drawboardEffect.value.getProperties()
5085
+ checkerboard: false,
5086
+ pixelGrid: false
4909
5087
  })
4910
5088
  );
4911
5089
  }
@@ -5615,6 +5793,7 @@ const _scroll = definePlugin((editor) => {
5615
5793
  });
5616
5794
  const _select = definePlugin((editor) => {
5617
5795
  const {
5796
+ isElement,
5618
5797
  selection,
5619
5798
  root
5620
5799
  } = editor;
@@ -5626,7 +5805,7 @@ const _select = definePlugin((editor) => {
5626
5805
  }
5627
5806
  function selectParent() {
5628
5807
  const parent = selection.value[0]?.parent;
5629
- if (parent instanceof Element2D) {
5808
+ if (isElement(parent)) {
5630
5809
  selection.value = [parent];
5631
5810
  }
5632
5811
  }
@@ -5722,15 +5901,14 @@ const _text = definePlugin((editor) => {
5722
5901
  });
5723
5902
  const _ui = definePlugin((editor) => {
5724
5903
  const {
5725
- selection,
5726
- getAabbInDrawboard,
5904
+ selectionAabbInDrawboard,
5727
5905
  emit
5728
5906
  } = editor;
5729
5907
  return {
5730
5908
  name: "mce:ui",
5731
5909
  setup: () => {
5732
5910
  watch(
5733
- () => getAabbInDrawboard(selection.value),
5911
+ selectionAabbInDrawboard,
5734
5912
  (aabb) => emit("setTransform", { aabb }),
5735
5913
  { deep: true }
5736
5914
  );
@@ -5896,6 +6074,7 @@ const plugins = [
5896
6074
  class Editor extends Observable {
5897
6075
  static injectionKey = Symbol.for("EditorKey");
5898
6076
  debug = ref(false);
6077
+ showMadeWith = ref(false);
5899
6078
  onEmit;
5900
6079
  plugins = /* @__PURE__ */ new Map();
5901
6080
  _setups = [];
@@ -5922,10 +6101,12 @@ class Editor extends Observable {
5922
6101
  _setupOptions(options) {
5923
6102
  const {
5924
6103
  debug = false,
6104
+ showMadeWith = false,
5925
6105
  plugins: plugins$1 = [],
5926
6106
  configCacheInLocal
5927
6107
  } = options;
5928
6108
  this.debug.value = debug;
6109
+ this.showMadeWith.value = showMadeWith;
5929
6110
  this.config = configCacheInLocal ? useLocalStorage("config", () => ({})) : ref({});
5930
6111
  this._setups = [];
5931
6112
  this._useMixins(
@@ -6026,10 +6207,13 @@ function defineMixin(cb) {
6026
6207
  return cb;
6027
6208
  }
6028
6209
  function useEditor() {
6029
- return inject(Editor.injectionKey);
6030
- }
6031
- function provideEditor(editor = new Editor()) {
6032
- provide(Editor.injectionKey, editor);
6210
+ let editor = inject(Editor.injectionKey, null);
6211
+ if (!editor) {
6212
+ const _editor = getCurrentInstance()?.proxy?.editor;
6213
+ if (_editor instanceof Editor) {
6214
+ editor = _editor;
6215
+ }
6216
+ }
6033
6217
  return editor;
6034
6218
  }
6035
6219
  function makeIconProps() {
@@ -6231,7 +6415,7 @@ const defaultActiveStrategy = (context) => {
6231
6415
  const { isRoot, isFrame, isElement, elementSelection } = editor;
6232
6416
  const activeElement = elementSelection.value[0];
6233
6417
  const cb = (node) => {
6234
- if (isElement(node) && (node.equal(activeElement) || node.parent?.equal(activeElement) || node.parent?.equal(activeElement?.parent) || isFrame(node.parent) && isRoot(node.parent.parent) || isRoot(node.parent) && !isFrame(node))) {
6418
+ if (isElement(node) && (node.equal(activeElement) || node.parent?.equal(activeElement) || node.parent?.equal(activeElement?.parent) || isFrame(node.parent) && isRoot(node.parent.parent) || isRoot(node.parent))) {
6235
6419
  return true;
6236
6420
  }
6237
6421
  return false;
@@ -6258,7 +6442,7 @@ const defaultHoverStrategy = (context) => {
6258
6442
  const { isRoot, isFrame, isElement, elementSelection } = editor;
6259
6443
  const activeElement = elementSelection.value[0];
6260
6444
  const cb = (node) => {
6261
- if (isElement(node) && (node.equal(activeElement) || node.parent?.equal(activeElement) || node.parent?.equal(activeElement?.parent) || isFrame(node.parent) && isRoot(node.parent.parent) || isRoot(node.parent) && !isFrame(node))) {
6445
+ if (isElement(node) && (node.equal(activeElement) || node.parent?.equal(activeElement) || node.parent?.equal(activeElement?.parent) || isFrame(node.parent) && isRoot(node.parent.parent) || isRoot(node.parent))) {
6262
6446
  return true;
6263
6447
  }
6264
6448
  return false;
@@ -6268,13 +6452,13 @@ const defaultHoverStrategy = (context) => {
6268
6452
  }
6269
6453
  return element.findAncestor(cb);
6270
6454
  };
6271
- const _hoisted_1$l = { class: "mce-auxiliary" };
6272
- const _sfc_main$A = /* @__PURE__ */ defineComponent({
6455
+ const _hoisted_1$n = { class: "mce-auxiliary" };
6456
+ const _sfc_main$C = /* @__PURE__ */ defineComponent({
6273
6457
  __name: "Auxiliary",
6274
6458
  setup(__props) {
6275
6459
  const { auxiliaryLines } = useEditor();
6276
6460
  return (_ctx, _cache) => {
6277
- return openBlock(), createElementBlock("div", _hoisted_1$l, [
6461
+ return openBlock(), createElementBlock("div", _hoisted_1$n, [
6278
6462
  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(auxiliaryLines), (item, key) => {
6279
6463
  return openBlock(), createElementBlock("div", {
6280
6464
  key,
@@ -6628,7 +6812,7 @@ function createLayout(props) {
6628
6812
  };
6629
6813
  }
6630
6814
  const MceMenuSymbol = Symbol.for("MceMenuSymbol");
6631
- const _sfc_main$z = /* @__PURE__ */ defineComponent({
6815
+ const _sfc_main$B = /* @__PURE__ */ defineComponent({
6632
6816
  __name: "Icon",
6633
6817
  props: {
6634
6818
  disabled: Boolean,
@@ -6653,7 +6837,7 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
6653
6837
  };
6654
6838
  }
6655
6839
  });
6656
- const _sfc_main$y = /* @__PURE__ */ defineComponent({
6840
+ const _sfc_main$A = /* @__PURE__ */ defineComponent({
6657
6841
  ...{
6658
6842
  inheritAttrs: false
6659
6843
  },
@@ -6766,7 +6950,7 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
6766
6950
  };
6767
6951
  }
6768
6952
  });
6769
- const _hoisted_1$k = ["onMouseenter"];
6953
+ const _hoisted_1$m = ["onMouseenter"];
6770
6954
  const _hoisted_2$a = ["onClick"];
6771
6955
  const _hoisted_3$7 = {
6772
6956
  key: 0,
@@ -6777,7 +6961,7 @@ const _hoisted_5$3 = {
6777
6961
  key: 1,
6778
6962
  class: "mce-list-item__append"
6779
6963
  };
6780
- const _sfc_main$x = /* @__PURE__ */ defineComponent({
6964
+ const _sfc_main$z = /* @__PURE__ */ defineComponent({
6781
6965
  ...{
6782
6966
  name: "MceMenu"
6783
6967
  },
@@ -6856,7 +7040,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6856
7040
  });
6857
7041
  return (_ctx, _cache) => {
6858
7042
  const _component_MceMenu = resolveComponent("MceMenu");
6859
- return openBlock(), createBlock(_sfc_main$y, {
7043
+ return openBlock(), createBlock(_sfc_main$A, {
6860
7044
  ref: "overlayTpl",
6861
7045
  modelValue: isActive.value,
6862
7046
  "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => isActive.value = $event),
@@ -6900,7 +7084,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6900
7084
  onClick: (e) => onClickItem(item, index, e)
6901
7085
  }, [
6902
7086
  hasPrepend.value ? (openBlock(), createElementBlock("div", _hoisted_3$7, [
6903
- item.checked ? (openBlock(), createBlock(_sfc_main$z, {
7087
+ item.checked ? (openBlock(), createBlock(_sfc_main$B, {
6904
7088
  key: 0,
6905
7089
  icon: "$check"
6906
7090
  })) : createCommentVNode("", true)
@@ -6911,10 +7095,10 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6911
7095
  ])
6912
7096
  ]),
6913
7097
  item.children?.length ? (openBlock(), createElementBlock("div", _hoisted_5$3, [
6914
- createVNode(_sfc_main$z, { icon: "$arrowRight" })
7098
+ createVNode(_sfc_main$B, { icon: "$arrowRight" })
6915
7099
  ])) : createCommentVNode("", true)
6916
7100
  ], 10, _hoisted_2$a)
6917
- ], 40, _hoisted_1$k))
7101
+ ], 40, _hoisted_1$m))
6918
7102
  ], 64);
6919
7103
  }), 128)),
6920
7104
  opened.value > -1 && __props.items?.[opened.value]?.children?.length ? (openBlock(), createBlock(_component_MceMenu, {
@@ -6944,12 +7128,12 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6944
7128
  };
6945
7129
  }
6946
7130
  });
6947
- const _hoisted_1$j = { class: "mce-context-menu__title" };
7131
+ const _hoisted_1$l = { class: "mce-context-menu__title" };
6948
7132
  const _hoisted_2$9 = {
6949
7133
  key: 0,
6950
7134
  class: "mce-context-menu__kbd"
6951
7135
  };
6952
- const _sfc_main$w = /* @__PURE__ */ defineComponent({
7136
+ const _sfc_main$y = /* @__PURE__ */ defineComponent({
6953
7137
  __name: "ContextMenu",
6954
7138
  props: {
6955
7139
  "modelValue": { type: Boolean },
@@ -7007,7 +7191,7 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
7007
7191
  updateLocation
7008
7192
  });
7009
7193
  return (_ctx, _cache) => {
7010
- return openBlock(), createBlock(_sfc_main$x, {
7194
+ return openBlock(), createBlock(_sfc_main$z, {
7011
7195
  ref: "menuTplRef",
7012
7196
  modelValue: model.value,
7013
7197
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
@@ -7022,7 +7206,7 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
7022
7206
  "onClick:item": onClickItem
7023
7207
  }, {
7024
7208
  title: withCtx(({ item }) => [
7025
- createElementVNode("span", _hoisted_1$j, toDisplayString(unref(t)(item.key)), 1),
7209
+ createElementVNode("span", _hoisted_1$l, toDisplayString(unref(t)(item.key)), 1),
7026
7210
  unref(hotkeys).has(item.key) ? (openBlock(), createElementBlock("span", _hoisted_2$9, toDisplayString(unref(getKbd)(item.key)), 1)) : createCommentVNode("", true)
7027
7211
  ]),
7028
7212
  _: 1
@@ -7030,11 +7214,11 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
7030
7214
  };
7031
7215
  }
7032
7216
  });
7033
- const _hoisted_1$i = {
7217
+ const _hoisted_1$k = {
7034
7218
  key: 0,
7035
7219
  class: "mce-drawing__content"
7036
7220
  };
7037
- const _sfc_main$v = /* @__PURE__ */ defineComponent({
7221
+ const _sfc_main$x = /* @__PURE__ */ defineComponent({
7038
7222
  __name: "Drawing",
7039
7223
  setup(__props) {
7040
7224
  const {
@@ -7064,16 +7248,15 @@ const _sfc_main$v = /* @__PURE__ */ defineComponent({
7064
7248
  }),
7065
7249
  onMousedown
7066
7250
  }, [
7067
- unref(stateContext)?.content ? (openBlock(), createElementBlock("div", _hoisted_1$i, toDisplayString(unref(t)(unref(stateContext).content)), 1)) : createCommentVNode("", true)
7251
+ unref(stateContext)?.content ? (openBlock(), createElementBlock("div", _hoisted_1$k, toDisplayString(unref(t)(unref(stateContext).content)), 1)) : createCommentVNode("", true)
7068
7252
  ], 36)) : createCommentVNode("", true);
7069
7253
  };
7070
7254
  }
7071
7255
  });
7072
- const _sfc_main$u = /* @__PURE__ */ defineComponent({
7256
+ const _sfc_main$w = /* @__PURE__ */ defineComponent({
7073
7257
  __name: "Floatbar",
7074
7258
  props: {
7075
7259
  ...makeMceOverlayProps({
7076
- location: "top-start",
7077
7260
  middlewares: ["offset", "shift"],
7078
7261
  offset: 8
7079
7262
  })
@@ -7081,27 +7264,46 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
7081
7264
  setup(__props, { expose: __expose }) {
7082
7265
  const props = __props;
7083
7266
  const {
7084
- getAabbInDrawboard,
7085
7267
  selection,
7268
+ selectionAabbInDrawboard,
7086
7269
  isFrame
7087
7270
  } = useEditor();
7088
7271
  const overlay = useTemplateRef("overlayTpl");
7272
+ const style = computed(() => {
7273
+ const location = props.location;
7274
+ const aabb = selectionAabbInDrawboard.value;
7275
+ if (location?.startsWith("top") || location?.startsWith("bottom")) {
7276
+ return {
7277
+ width: `${aabb.width}px`
7278
+ };
7279
+ } else if (location?.startsWith("left") || location?.startsWith("right")) {
7280
+ return {
7281
+ height: `${aabb.height}px`
7282
+ };
7283
+ }
7284
+ return {};
7285
+ });
7286
+ const offset2 = computed(() => {
7287
+ if (selection.value.some((v) => isFrame(v)) || props.location?.startsWith("bottom")) {
7288
+ return 32;
7289
+ }
7290
+ return 8;
7291
+ });
7089
7292
  function updateLocation() {
7090
7293
  overlay.value?.updateLocation();
7091
7294
  }
7092
- watch(() => getAabbInDrawboard(selection.value), updateLocation, {
7093
- deep: true
7094
- });
7295
+ watch(selectionAabbInDrawboard, updateLocation, { deep: true });
7095
7296
  __expose({
7096
7297
  updateLocation
7097
7298
  });
7098
7299
  return (_ctx, _cache) => {
7099
- return openBlock(), createBlock(_sfc_main$y, {
7300
+ return openBlock(), createBlock(_sfc_main$A, {
7100
7301
  ref: "overlayTpl",
7302
+ style: normalizeStyle(style.value),
7101
7303
  class: "mce-floatbar",
7102
7304
  location: props.location,
7103
7305
  middlewares: props.middlewares,
7104
- offset: unref(selection)[0] && unref(isFrame)(unref(selection)[0]) ? 32 : 8,
7306
+ offset: offset2.value,
7105
7307
  target: props.target,
7106
7308
  attach: false,
7107
7309
  "model-value": true
@@ -7110,1608 +7312,1838 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
7110
7312
  unref(selection).length > 0 ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
7111
7313
  ]),
7112
7314
  _: 3
7113
- }, 8, ["location", "middlewares", "offset", "target"]);
7315
+ }, 8, ["style", "location", "middlewares", "offset", "target"]);
7114
7316
  };
7115
7317
  }
7116
7318
  });
7117
- const _sfc_main$t = /* @__PURE__ */ defineComponent({
7118
- __name: "Frame",
7319
+ const _hoisted_1$j = { class: "mce-transformable__svg" };
7320
+ const _hoisted_2$8 = ["rx", "ry"];
7321
+ const _hoisted_3$6 = ["x", "y", "width", "height", "aria-label"];
7322
+ const _hoisted_4$3 = ["cx", "cy", "r", "aria-label"];
7323
+ const _hoisted_5$2 = { "pointer-events": "all" };
7324
+ const _hoisted_6$2 = ["x", "y", "width", "height", "aria-label", "cursor", "onPointerdown"];
7325
+ const _hoisted_7$2 = {
7326
+ "pointer-events": "all",
7327
+ class: "mce-transformable__svg-slot"
7328
+ };
7329
+ const _hoisted_8$1 = {
7330
+ key: 0,
7331
+ class: "mce-transformable__tip"
7332
+ };
7333
+ const _sfc_main$v = /* @__PURE__ */ defineComponent({
7334
+ __name: "Transformable",
7119
7335
  props: {
7120
- "modelValue": { required: true },
7121
- "modelModifiers": {}
7122
- },
7123
- emits: ["update:modelValue"],
7124
- setup(__props) {
7125
- const frame = useModel(__props, "modelValue");
7126
- const input = useTemplateRef("inputTpl");
7127
- const {
7128
- getObbInDrawboard,
7129
- hoverElement,
7130
- selection,
7131
- state,
7132
- config,
7133
- exec
7134
- } = useEditor();
7135
- const editing = ref(false);
7136
- async function onDblclick() {
7137
- editing.value = true;
7138
- await nextTick();
7139
- if (input.value) {
7140
- input.value.focus();
7141
- input.value.select();
7142
- }
7143
- }
7144
- async function onPointerdown(ev) {
7145
- if (!editing.value) {
7146
- selection.value = [frame.value];
7147
- await nextTick();
7148
- exec("startTransform", ev);
7149
- }
7150
- }
7151
- return (_ctx, _cache) => {
7152
- return withDirectives((openBlock(), createElementBlock("div", {
7153
- style: normalizeStyle(unref(boundingBoxToStyle)(unref(getObbInDrawboard)(frame.value))),
7154
- class: normalizeClass(["mce-frame", [
7155
- unref(config).frameOutline && "mce-frame--outline"
7156
- ]])
7157
- }, [
7158
- withDirectives(createElementVNode("div", {
7159
- class: "mce-frame__name",
7160
- onDblclick,
7161
- onPointerdown,
7162
- onPointerenter: _cache[2] || (_cache[2] = ($event) => !unref(state) && (hoverElement.value = frame.value)),
7163
- onPointerleave: _cache[3] || (_cache[3] = ($event) => !unref(state) && (hoverElement.value = void 0))
7164
- }, [
7165
- createElementVNode("div", null, toDisplayString(frame.value.name), 1),
7166
- withDirectives(createElementVNode("input", {
7167
- ref: "inputTpl",
7168
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => frame.value.name = $event),
7169
- onBlur: _cache[1] || (_cache[1] = ($event) => editing.value = false)
7170
- }, null, 544), [
7171
- [vShow, editing.value],
7172
- [vModelText, frame.value.name]
7173
- ])
7174
- ], 544), [
7175
- [vShow, unref(config).viewMode === "edgeless"]
7176
- ])
7177
- ], 6)), [
7178
- [vShow, frame.value.visible]
7179
- ]);
7180
- };
7181
- }
7182
- });
7183
- const _sfc_main$s = /* @__PURE__ */ defineComponent({
7184
- __name: "Frames",
7185
- setup(__props) {
7186
- const {
7187
- frames
7188
- } = useEditor();
7189
- return (_ctx, _cache) => {
7190
- return openBlock(true), createElementBlock(Fragment, null, renderList(unref(frames), (frame, key) => {
7191
- return openBlock(), createBlock(_sfc_main$t, {
7192
- key,
7193
- "model-value": frame
7194
- }, null, 8, ["model-value"]);
7195
- }), 128);
7196
- };
7197
- }
7198
- });
7199
- const _sfc_main$r = /* @__PURE__ */ defineComponent({
7200
- __name: "GoBackSelectedArea",
7201
- setup(__props) {
7202
- const {
7203
- selectionAabb,
7204
- drawboardAabb,
7205
- aabbToDrawboardAabb,
7206
- t,
7207
- exec
7208
- } = useEditor();
7209
- const isActive = computed(() => {
7210
- return selectionAabb.value.width && selectionAabb.value.height && !isOverlappingAabb(
7211
- drawboardAabb.value,
7212
- aabbToDrawboardAabb(selectionAabb.value)
7213
- );
7214
- });
7215
- return (_ctx, _cache) => {
7216
- return isActive.value ? (openBlock(), createElementBlock("div", {
7217
- key: 0,
7218
- class: "mce-back-selected-aera",
7219
- onClick: _cache[0] || (_cache[0] = withModifiers(($event) => unref(exec)("scrollToSelection", { behavior: "smooth" }), ["prevent"]))
7220
- }, [
7221
- createVNode(_sfc_main$z, { icon: "$gps" }),
7222
- createElementVNode("span", null, toDisplayString(unref(t)("goBackSelectedArea")), 1)
7223
- ])) : createCommentVNode("", true);
7224
- };
7225
- }
7226
- });
7227
- const _hoisted_1$h = ["data-name"];
7228
- const _sfc_main$q = /* @__PURE__ */ defineComponent({
7229
- __name: "Hover",
7230
- setup(__props) {
7231
- const {
7232
- selection,
7233
- hoverElement,
7234
- getObbInDrawboard
7235
- } = useEditor();
7236
- const hoverElementObb = computed(() => getObbInDrawboard(hoverElement.value));
7237
- return (_ctx, _cache) => {
7238
- return unref(hoverElement) && !unref(hoverElement).equal(unref(selection)[0]) ? (openBlock(), createElementBlock("div", {
7239
- key: 0,
7240
- class: "mce-hover",
7241
- "data-name": unref(hoverElement).name,
7242
- style: normalizeStyle({
7243
- borderColor: "currentcolor",
7244
- ...unref(boundingBoxToStyle)(hoverElementObb.value)
7245
- })
7246
- }, null, 12, _hoisted_1$h)) : createCommentVNode("", true);
7247
- };
7248
- }
7249
- });
7250
- const _hoisted_1$g = { class: "mce-btn" };
7251
- const _sfc_main$p = /* @__PURE__ */ defineComponent({
7252
- __name: "Btn",
7253
- setup(__props) {
7254
- return (_ctx, _cache) => {
7255
- return openBlock(), createElementBlock("div", _hoisted_1$g, [
7256
- renderSlot(_ctx.$slots, "default")
7257
- ]);
7258
- };
7259
- }
7260
- });
7261
- const _hoisted_1$f = { class: "mce-layer__name" };
7262
- const _hoisted_2$8 = { class: "mce-layer__action" };
7263
- const _sfc_main$o = /* @__PURE__ */ defineComponent({
7264
- ...{
7265
- name: "MceLayer",
7266
- inheritAttrs: false
7336
+ tag: { default: "div" },
7337
+ modelValue: {},
7338
+ movable: { type: Boolean, default: true },
7339
+ rotatable: { type: Boolean, default: true },
7340
+ resizable: { type: Boolean, default: true },
7341
+ adjustableBorderRadius: { type: Boolean, default: false },
7342
+ threshold: { default: 0 },
7343
+ resizeStrategy: {},
7344
+ handleStrategy: {},
7345
+ handleShape: { default: "rect" },
7346
+ hideUi: { type: Boolean },
7347
+ handles: { default: () => [
7348
+ "move",
7349
+ // resize
7350
+ "resize-left",
7351
+ "resize-top",
7352
+ "resize-right",
7353
+ "resize-bottom",
7354
+ "resize-top-left",
7355
+ "resize-top-right",
7356
+ "resize-bottom-right",
7357
+ "resize-bottom-left",
7358
+ // border-radius
7359
+ "border-radius-top-left",
7360
+ "border-radius-top-right",
7361
+ "border-radius-bottom-left",
7362
+ "border-radius-bottom-right",
7363
+ // rotate
7364
+ "rotate-top-left",
7365
+ "rotate-top-right",
7366
+ "rotate-bottom-left",
7367
+ "rotate-bottom-right"
7368
+ ] },
7369
+ initialSize: { type: Boolean },
7370
+ borderStyle: {},
7371
+ tipFormat: {}
7267
7372
  },
7268
- __name: "Layer",
7269
- props: /* @__PURE__ */ mergeModels({
7270
- root: Boolean,
7271
- node: {
7272
- type: Object,
7273
- required: true
7274
- },
7275
- active: Boolean,
7276
- indent: {
7277
- type: Number,
7278
- default: 0
7279
- }
7280
- }, {
7281
- "opened": { default: false },
7282
- "openedModifiers": {}
7283
- }),
7284
- emits: ["update:opened"],
7285
- setup(__props) {
7373
+ emits: ["update:modelValue", "start", "move", "end"],
7374
+ setup(__props, { expose: __expose, emit: __emit }) {
7286
7375
  const props = __props;
7287
- const {
7288
- isElement,
7289
- isFrame,
7290
- isVisible,
7291
- setVisible,
7292
- isLock,
7293
- setLock,
7294
- selection,
7295
- nodes,
7296
- nodeIndexMap,
7297
- zoomTo,
7298
- hoverElement,
7299
- exec
7300
- } = useEditor();
7301
- const opened = useModel(__props, "opened");
7302
- const dom = ref();
7303
- const {
7304
- selecting,
7305
- sortedSelection
7306
- } = useLayerItem({
7307
- id: props.node.id,
7308
- opened,
7309
- node: computed(() => props.node),
7310
- dom: computed(() => dom.value)
7376
+ const emit = __emit;
7377
+ const cursors = {
7378
+ "rotate-top-left": (angle) => createCursor("rotate", 360 + angle),
7379
+ "rotate-top-right": (angle) => createCursor("rotate", 90 + angle),
7380
+ "rotate-bottom-left": (angle) => createCursor("rotate", 270 + angle),
7381
+ "rotate-bottom-right": (angle) => createCursor("rotate", 180 + angle),
7382
+ "resize-left": (angle) => createCursor("resizeXy", 180 + angle),
7383
+ "resize-top": (angle) => createCursor("resizeXy", 90 + angle),
7384
+ "resize-right": (angle) => createCursor("resizeXy", 180 + angle),
7385
+ "resize-bottom": (angle) => createCursor("resizeXy", 90 + angle),
7386
+ "resize-top-left": (angle) => createCursor("resizeBevel", 90 + angle),
7387
+ "resize-top-right": (angle) => createCursor("resizeBevel", 180 + angle),
7388
+ "resize-bottom-right": (angle) => createCursor("resizeBevel", 90 + angle),
7389
+ "resize-bottom-left": (angle) => createCursor("resizeBevel", 180 + angle)
7390
+ };
7391
+ const modelValue = useModel(props, "modelValue");
7392
+ const model = computed({
7393
+ get: () => {
7394
+ let { left = 0, top = 0, width = 0, height = 0, rotate = 0, borderRadius = 0 } = modelValue.value ?? {};
7395
+ if (Number.isNaN(Number(width)))
7396
+ width = 0;
7397
+ if (Number.isNaN(Number(height)))
7398
+ height = 0;
7399
+ return { left, top, width, height, rotate, borderRadius };
7400
+ },
7401
+ set: (val) => modelValue.value = val
7311
7402
  });
7312
- const isFrist = computed(() => sortedSelection.value[0]?.equal(props.node));
7313
- const isLast = computed(() => {
7314
- const last = sortedSelection.value[sortedSelection.value.length - 1];
7315
- if (last) {
7316
- if (last.equal(props.node)) {
7317
- if (!opened.value || !props.node?.children.length)
7318
- return true;
7319
- } else if (last.equal(props.node?.parent)) ;
7403
+ const transforming = ref(false);
7404
+ const activeHandle = ref();
7405
+ const computedHandles = computed(() => {
7406
+ const size = 8;
7407
+ const { width = 0, height = 0, borderRadius } = model.value;
7408
+ const center = { x: width / 2, y: height / 2 };
7409
+ const shape = props.handleShape;
7410
+ const lines = [
7411
+ { type: "top", points: [[0, 0], [1, 0]] },
7412
+ { type: "right", points: [[1, 0], [1, 1]] },
7413
+ { type: "bottom", points: [[0, 1], [1, 1]] },
7414
+ { type: "left", points: [[0, 0], [0, 1]] }
7415
+ ];
7416
+ const points = [
7417
+ { type: "top", point: [0.5, 0] },
7418
+ { type: "right", point: [1, 0.5] },
7419
+ { type: "bottom", point: [0.5, 1] },
7420
+ { type: "left", point: [0, 0.5] },
7421
+ { type: "top-left", point: [0, 0] },
7422
+ { type: "top-right", point: [1, 0] },
7423
+ { type: "bottom-left", point: [0, 1] },
7424
+ { type: "bottom-right", point: [1, 1] }
7425
+ ];
7426
+ const lineHandles = lines.map((item) => {
7427
+ const [p1, p2] = item.points;
7428
+ const minX = Math.min(p1[0], p2[0]) * width;
7429
+ const maxX = Math.max(p1[0], p2[0]) * width;
7430
+ const minY = Math.min(p1[1], p2[1]) * height;
7431
+ const maxY = Math.max(p1[1], p2[1]) * height;
7432
+ return {
7433
+ type: item.type,
7434
+ x: minX - size / 2,
7435
+ y: minY - size / 2,
7436
+ width: maxX - minX + size,
7437
+ height: maxY - minY + size
7438
+ };
7439
+ });
7440
+ const pointHandles = points.map((item) => {
7441
+ return {
7442
+ type: item.type,
7443
+ shape,
7444
+ x: item.point[0] * width - size / 2,
7445
+ y: item.point[1] * height - size / 2,
7446
+ width: size,
7447
+ height: size
7448
+ };
7449
+ });
7450
+ const diagonalPointHandles = pointHandles.filter((item) => item.type.split("-").length === 2);
7451
+ const rotateHandles = diagonalPointHandles.map((item) => {
7452
+ const sign = {
7453
+ x: center.x - item.x > 0 ? 1 : -1,
7454
+ y: center.y - item.y > 0 ? 1 : -1
7455
+ };
7456
+ return {
7457
+ ...item,
7458
+ shape: void 0,
7459
+ type: `rotate-${item.type}`,
7460
+ x: item.x - sign.x * size,
7461
+ y: item.y - sign.y * size
7462
+ };
7463
+ });
7464
+ const minSize = Math.min(width, height);
7465
+ const borderRadiusHandles = props.adjustableBorderRadius ? diagonalPointHandles.map((item) => {
7466
+ const sign = {
7467
+ x: center.x - item.x > 0 ? 1 : -1,
7468
+ y: center.y - item.y > 0 ? 1 : -1
7469
+ };
7470
+ const offset2 = minSize * 0.1;
7471
+ const ws = (borderRadius + offset2) / (width / 2 + offset2);
7472
+ const hs = (borderRadius + offset2) / (height / 2 + offset2);
7473
+ return {
7474
+ ...item,
7475
+ shape: "circle",
7476
+ type: `border-radius-${item.type}`,
7477
+ x: item.x + sign.x * width / 2 * ws,
7478
+ y: item.y + sign.y * height / 2 * hs
7479
+ };
7480
+ }) : [];
7481
+ let handles;
7482
+ if (props.handleStrategy === "point") {
7483
+ handles = [
7484
+ // move
7485
+ ...lineHandles.map((item) => ({ ...item, type: "move" })),
7486
+ // resize
7487
+ ...pointHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
7488
+ // border-radius
7489
+ ...borderRadiusHandles,
7490
+ // rotate
7491
+ ...rotateHandles
7492
+ ];
7493
+ } else {
7494
+ handles = [
7495
+ // resize
7496
+ ...lineHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
7497
+ ...diagonalPointHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
7498
+ // border-radius
7499
+ ...borderRadiusHandles,
7500
+ // rotate
7501
+ ...rotateHandles
7502
+ ];
7320
7503
  }
7321
- return false;
7504
+ return handles.filter((handle) => {
7505
+ if (props.handles.includes(handle.type)) {
7506
+ return !(!props.resizable && handle.type.startsWith("resize") || !props.rotatable && handle.type.startsWith("rotate") || !props.movable && handle.type === "move");
7507
+ }
7508
+ return false;
7509
+ }).map((anchor) => {
7510
+ anchor.width = Math.max(anchor.width, 0);
7511
+ anchor.height = Math.max(anchor.height, 0);
7512
+ return anchor;
7513
+ });
7322
7514
  });
7323
- const isActive = computed(() => selection.value.some((v) => v.equal(props.node)));
7324
- const inputDom = ref();
7325
- const isHoverElement = computed(() => props.node?.equal(hoverElement.value));
7326
- const hovering = ref(false);
7327
- const editing = ref(false);
7328
- const editValue = ref();
7329
- const thumbnailIcon = computed(() => {
7330
- const node = props.node;
7331
- if (isFrame(node)) {
7332
- return "$frame";
7333
- } else if (node.children.length) {
7334
- return "$group";
7335
- } else if (isElement(node)) {
7336
- if (node.foreground.isValid() && node.foreground.image) {
7337
- return "$image";
7515
+ const handlesRef = ref();
7516
+ const sizeStyle = computed(() => {
7517
+ const { width = 0, height = 0 } = model.value;
7518
+ return {
7519
+ width: props.initialSize && !width ? void 0 : `${width}px`,
7520
+ height: props.initialSize && !height ? void 0 : `${height}px`
7521
+ };
7522
+ });
7523
+ const style = computed(() => {
7524
+ const { left = 0, top = 0, rotate = 0 } = model.value;
7525
+ const radian = rotate * Math.PI / 180;
7526
+ const cos = Math.cos(radian);
7527
+ const sin = Math.sin(radian);
7528
+ return {
7529
+ ...sizeStyle.value,
7530
+ transform: `matrix(${cos}, ${sin}, ${-sin}, ${cos}, ${left}, ${top})`
7531
+ };
7532
+ });
7533
+ const tip = computed(() => props.tipFormat?.("size"));
7534
+ function start(event, index) {
7535
+ if (event && event.button !== void 0 && event.button !== 0) {
7536
+ return false;
7537
+ }
7538
+ event?.preventDefault();
7539
+ event?.stopPropagation();
7540
+ const { left, top, width, height, rotate, borderRadius } = model.value;
7541
+ let aspectRatio = 0;
7542
+ if (width && height) {
7543
+ aspectRatio = width / height;
7544
+ }
7545
+ const handle = index === void 0 ? { type: "move", x: 0, y: 0, width: 0, height: 0 } : computedHandles.value[index];
7546
+ activeHandle.value = handle.type;
7547
+ const isMove = handle.type === "move";
7548
+ const isRotate = handle.type.startsWith("rotate");
7549
+ const isBorderRadius = handle.type.startsWith("border-radius");
7550
+ const isHorizontal = handle.type === "resize-left" || handle.type === "resize-right";
7551
+ const isHorizontalVertical = handle.type.split("-").length === 2;
7552
+ const centerPoint = {
7553
+ x: left + width / 2,
7554
+ y: top + height / 2
7555
+ };
7556
+ const startPoint = {
7557
+ x: left,
7558
+ y: top
7559
+ };
7560
+ if (!isMove) {
7561
+ startPoint.x += handle.x + handle.width / 2;
7562
+ startPoint.y += handle.y + handle.height / 2;
7563
+ }
7564
+ const sign = {
7565
+ x: startPoint.x - centerPoint.x > 0 ? 1 : -1,
7566
+ y: startPoint.y - centerPoint.y > 0 ? 1 : -1
7567
+ };
7568
+ const rotatedStartPoint = rotatePoint(startPoint, centerPoint, rotate);
7569
+ const rotatedSymmetricPoint = {
7570
+ x: centerPoint.x * 2 - rotatedStartPoint.x,
7571
+ y: centerPoint.y * 2 - rotatedStartPoint.y
7572
+ };
7573
+ const startAngle = Math.atan2(
7574
+ rotatedStartPoint.y - centerPoint.y,
7575
+ rotatedStartPoint.x - centerPoint.x
7576
+ ) / (Math.PI / 180);
7577
+ let startClientPoint = event ? { x: event.clientX, y: event.clientY } : void 0;
7578
+ function startTransform() {
7579
+ transforming.value = true;
7580
+ emit("start", model.value);
7581
+ }
7582
+ if (!props.threshold && !transforming.value) {
7583
+ startTransform();
7584
+ }
7585
+ function onMove(event2) {
7586
+ const updated = {};
7587
+ if (!startClientPoint) {
7588
+ startClientPoint = { x: event2.clientX, y: event2.clientY };
7338
7589
  }
7339
- if (node.text.isValid()) {
7340
- return "$text";
7590
+ const rotatedOffset = {
7591
+ x: event2.clientX - startClientPoint.x,
7592
+ y: event2.clientY - startClientPoint.y
7593
+ };
7594
+ if (!transforming.value) {
7595
+ if (Math.abs(rotatedOffset.x) < props.threshold && Math.abs(rotatedOffset.y) < props.threshold) {
7596
+ return;
7597
+ }
7598
+ startTransform();
7341
7599
  }
7342
- }
7343
- return "$shape";
7344
- });
7345
- function onMousedown() {
7346
- }
7347
- function onClickExpand() {
7348
- opened.value = !opened.value;
7349
- }
7350
- function onClickContent(e) {
7351
- selecting.value = true;
7352
- if (isElement(props.node)) {
7353
- if (e.shiftKey) {
7354
- const _nodes = [
7355
- ...selection.value.filter((v) => !v.equal(props.node)),
7356
- props.node
7357
- ];
7358
- let min;
7359
- let max;
7360
- _nodes.forEach((el) => {
7361
- const index = nodeIndexMap.get(el.id);
7362
- if (index !== void 0) {
7363
- min = min === void 0 ? index : Math.min(min, index);
7364
- max = max === void 0 ? index : Math.max(max, index);
7365
- }
7366
- });
7367
- if (min !== void 0 && max !== void 0) {
7368
- let _selection = nodes.value.slice(min, max + 1);
7369
- const result = new Set(_selection.map((node) => node.id));
7370
- const parents = /* @__PURE__ */ new Set();
7371
- _selection.forEach((node) => node.parent && parents.add(node.parent));
7372
- parents.forEach((parent) => {
7373
- if (parent.children.every((ch) => result.has(ch.id))) {
7374
- const ids = new Set(parent.children.map((ch) => ch.id));
7375
- _selection = [
7376
- ..._selection.filter((v) => !ids.has(v.id)),
7377
- parent
7378
- ];
7379
- }
7380
- });
7381
- selection.value = _selection;
7600
+ const rotatedCurrentPoint = {
7601
+ x: rotatedStartPoint.x + rotatedOffset.x,
7602
+ y: rotatedStartPoint.y + rotatedOffset.y
7603
+ };
7604
+ if (isMove) {
7605
+ if (props.movable) {
7606
+ updated.left = startPoint.x + rotatedOffset.x;
7607
+ updated.top = startPoint.y + rotatedOffset.y;
7382
7608
  }
7383
- } else if (e.ctrlKey || e.metaKey) {
7384
- const filtered = selection.value.filter((v) => !v.equal(props.node));
7385
- if (filtered.length !== selection.value.length) {
7386
- selection.value = filtered;
7609
+ } else if (isRotate) {
7610
+ if (props.rotatable) {
7611
+ const endAngle = Math.atan2(
7612
+ rotatedCurrentPoint.y - centerPoint.y,
7613
+ rotatedCurrentPoint.x - centerPoint.x
7614
+ ) / (Math.PI / 180);
7615
+ updated.rotate = (rotate + endAngle - startAngle + 360) % 360;
7616
+ }
7617
+ } else if (isBorderRadius) {
7618
+ const offset2 = rotatePoint(rotatedOffset, { x: 0, y: 0 }, -rotate);
7619
+ const dx = -sign.x * offset2.x;
7620
+ const dy = -sign.y * offset2.y;
7621
+ const _offset = Math.abs(dx) < Math.abs(dy) ? dy : dx;
7622
+ updated.borderRadius = borderRadius + _offset;
7623
+ } else if (isHorizontalVertical) {
7624
+ const currentPoint = rotatePoint(rotatedCurrentPoint, centerPoint, -rotate);
7625
+ const newCurrentPoint = isHorizontal ? { x: currentPoint.x, y: startPoint.y } : { x: startPoint.x, y: currentPoint.y };
7626
+ const newRotatedCurrentPoint = rotatePoint(newCurrentPoint, centerPoint, rotate);
7627
+ const distance = Math.abs(getDistance(newRotatedCurrentPoint, rotatedSymmetricPoint));
7628
+ if (isHorizontal) {
7629
+ updated.width = distance;
7630
+ if (props.resizeStrategy === "lockAspectRatio" && aspectRatio) {
7631
+ updated.height = distance / aspectRatio;
7632
+ } else {
7633
+ updated.height = height;
7634
+ }
7387
7635
  } else {
7388
- selection.value = [...filtered, props.node];
7636
+ updated.height = distance;
7637
+ if (props.resizeStrategy === "lockAspectRatio" && aspectRatio) {
7638
+ updated.width = distance * aspectRatio;
7639
+ } else {
7640
+ updated.width = width;
7641
+ }
7389
7642
  }
7643
+ const newCenterPoint = getMidpoint(newRotatedCurrentPoint, rotatedSymmetricPoint);
7644
+ updated.left = newCenterPoint.x - updated.width / 2;
7645
+ updated.top = newCenterPoint.y - updated.height / 2;
7390
7646
  } else {
7391
- selection.value = [props.node];
7647
+ let newRotatedCurrentPoint;
7648
+ if ((props.resizeStrategy === "lockAspectRatio" || props.resizeStrategy === "lockAspectRatioDiagonal") && aspectRatio) {
7649
+ const offset2 = rotatePoint(rotatedOffset, { x: 0, y: 0 }, -rotate);
7650
+ const dx = sign.x * offset2.x;
7651
+ const dy = sign.y * offset2.y * aspectRatio;
7652
+ const _offset = Math.abs(dx) < Math.abs(dy) ? dx : dy;
7653
+ newRotatedCurrentPoint = rotatePoint(
7654
+ {
7655
+ x: startPoint.x + sign.x * _offset,
7656
+ y: startPoint.y + sign.y * _offset / aspectRatio
7657
+ },
7658
+ centerPoint,
7659
+ rotate
7660
+ );
7661
+ } else {
7662
+ newRotatedCurrentPoint = rotatedCurrentPoint;
7663
+ }
7664
+ const newCenterPoint = getMidpoint(newRotatedCurrentPoint, rotatedSymmetricPoint);
7665
+ const points = [
7666
+ rotatePoint(newRotatedCurrentPoint, newCenterPoint, -rotate),
7667
+ rotatePoint(rotatedSymmetricPoint, newCenterPoint, -rotate)
7668
+ ];
7669
+ const [minX, maxX] = points[0].x > points[1].x ? [points[1].x, points[0].x] : [points[0].x, points[1].x];
7670
+ const [minY, maxY] = points[0].y > points[1].y ? [points[1].y, points[0].y] : [points[0].y, points[1].y];
7671
+ updated.width = maxX - minX;
7672
+ updated.height = maxY - minY;
7673
+ updated.left = minX;
7674
+ updated.top = minY;
7675
+ }
7676
+ if ("width" in updated && updated.width <= 0 || "height" in updated && updated.height <= 0) {
7677
+ return;
7678
+ }
7679
+ if (updated.borderRadius ?? borderRadius) {
7680
+ updated.borderRadius = Math.min(
7681
+ Math.max(0, updated.borderRadius ?? borderRadius),
7682
+ Math.min((updated.width ?? width) / 2, (updated.height ?? height) / 2)
7683
+ );
7392
7684
  }
7685
+ const oldValue = { ...model.value };
7686
+ const newValue = { ...model.value, ...updated };
7687
+ model.value = newValue;
7688
+ emit("move", newValue, oldValue);
7393
7689
  }
7394
- nextTick().then(() => {
7395
- selecting.value = false;
7396
- });
7397
- }
7398
- function onDblclickThumbnail(e) {
7399
- e.stopPropagation();
7400
- if (isElement(props.node)) {
7401
- zoomTo("selection", {
7402
- behavior: "smooth"
7403
- });
7690
+ function onEnd() {
7691
+ window.removeEventListener("pointermove", onMove);
7692
+ window.removeEventListener("pointerup", onEnd, true);
7693
+ transforming.value = false;
7694
+ activeHandle.value = void 0;
7695
+ emit("end", model.value);
7404
7696
  }
7697
+ window.addEventListener("pointermove", onMove);
7698
+ window.addEventListener("pointerup", onEnd, true);
7699
+ return true;
7405
7700
  }
7406
- function onDblclickContent() {
7407
- editing.value = true;
7408
- editValue.value = props.node.name;
7409
- nextTick().then(() => {
7410
- inputDom.value?.focus();
7411
- });
7701
+ const cursorMap = {
7702
+ rotate: '<path d="M22.4789 9.45728L25.9935 12.9942L22.4789 16.5283V14.1032C18.126 14.1502 14.6071 17.6737 14.5675 22.0283H17.05L13.513 25.543L9.97889 22.0283H12.5674C12.6071 16.5691 17.0214 12.1503 22.4789 12.1031L22.4789 9.45728Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M21.4789 7.03223L27.4035 12.9945L21.4789 18.9521V15.1868C18.4798 15.6549 16.1113 18.0273 15.649 21.0284H19.475L13.5128 26.953L7.55519 21.0284H11.6189C12.1243 15.8155 16.2679 11.6677 21.4789 11.1559L21.4789 7.03223ZM22.4789 12.1031C17.0214 12.1503 12.6071 16.5691 12.5674 22.0284H9.97889L13.513 25.543L17.05 22.0284H14.5675C14.5705 21.6896 14.5947 21.3558 14.6386 21.0284C15.1157 17.4741 17.9266 14.6592 21.4789 14.1761C21.8063 14.1316 22.1401 14.1069 22.4789 14.1032V16.5284L25.9935 12.9942L22.4789 9.45729L22.4789 12.1031Z" fill="white"/>',
7703
+ resizeXy: '<path d="m9 17.9907v.005l5.997 5.996.001-3.999h1.999 2.02v4l5.98-6.001-5.98-5.999.001 4.019-2.021.002h-2l.001-4.022zm1.411.003 3.587-3.588-.001 2.587h3.5 2.521v-2.585l3.565 3.586-3.564 3.585-.001-2.585h-2.521l-3.499-.001-.001 2.586z" fill="white"/><path d="m17.4971 18.9932h2.521v2.586l3.565-3.586-3.565-3.585v2.605h-2.521-3.5v-2.607l-3.586 3.587 3.586 3.586v-2.587z" fill="black"/>',
7704
+ resizeBevel: '<path d="m19.7432 17.0869-4.072 4.068 2.829 2.828-8.473-.013-.013-8.47 2.841 2.842 4.075-4.068 1.414-1.415-2.844-2.842h8.486v8.484l-2.83-2.827z" fill="white"/><path d="m18.6826 16.7334-4.427 4.424 1.828 1.828-5.056-.016-.014-5.054 1.842 1.841 4.428-4.422 2.474-2.475-1.844-1.843h5.073v5.071l-1.83-1.828z" fill="black"/>'
7705
+ };
7706
+ function createCursor(type, angle) {
7707
+ const path = cursorMap[type];
7708
+ return `<svg height="32" width="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><defs><filter id="shadow" color-interpolation-filters="sRGB"><feDropShadow dx="1" dy="1" stdDeviation="1.2" flood-opacity=".5"/></filter></defs><g fill="none" transform="rotate(${angle} 16 16)" filter="url(%23shadow)">${path}</g></svg>`.replace(/"/g, "'");
7412
7709
  }
7413
- function onMouseenter() {
7414
- if (isElement(props.node)) {
7415
- hoverElement.value = props.node;
7416
- hovering.value = true;
7710
+ function getCursor(type) {
7711
+ if (type === "move") {
7712
+ return "move";
7713
+ }
7714
+ const create = cursors[type];
7715
+ if (!create) {
7716
+ return void 0;
7417
7717
  }
7718
+ return `url("data:image/svg+xml,${create(model.value.rotate ?? 0)}") 16 16, pointer`;
7418
7719
  }
7419
- function onMouseleave() {
7420
- hoverElement.value = void 0;
7421
- hovering.value = false;
7720
+ function rotatePoint(point, origin, angle) {
7721
+ const radian = angle * Math.PI / 180;
7722
+ const cos = Math.cos(radian);
7723
+ const sin = Math.sin(radian);
7724
+ return {
7725
+ x: (point.x - origin.x) * cos - (point.y - origin.y) * sin + origin.x,
7726
+ y: (point.x - origin.x) * sin + (point.y - origin.y) * cos + origin.y
7727
+ };
7422
7728
  }
7423
- function onContextmenu(e) {
7424
- if (isElement(props.node)) {
7425
- if (!selection.value.some((v) => v.equal(props.node))) {
7426
- selection.value = [props.node];
7729
+ function getMidpoint(point1, point2) {
7730
+ return {
7731
+ x: (point2.x + point1.x) / 2,
7732
+ y: (point2.y + point1.y) / 2
7733
+ };
7734
+ }
7735
+ function getDistance(point1, point2) {
7736
+ const dx = point2.x - point1.x;
7737
+ const dy = point2.y - point1.y;
7738
+ return (dx + dy >= 0 ? 1 : -1) * Math.sqrt(dx * dx + dy * dy);
7739
+ }
7740
+ onMounted(async () => {
7741
+ const vm = getCurrentInstance();
7742
+ const root = vm?.proxy?.$el;
7743
+ if (root && props.initialSize) {
7744
+ await nextTick();
7745
+ let width;
7746
+ let height;
7747
+ const style2 = getComputedStyle(root);
7748
+ if (style2.width.endsWith("px") && style2.height.endsWith("px")) {
7749
+ width = Number(style2.width.replace("px", ""));
7750
+ height = Number(style2.height.replace("px", ""));
7751
+ } else {
7752
+ ({ width, height } = root.getBoundingClientRect());
7753
+ }
7754
+ if (width && height) {
7755
+ model.value = { ...model.value, width, height };
7756
+ } else if ("ResizeObserver" in globalThis) {
7757
+ const observer = new ResizeObserver(([entry]) => {
7758
+ if (entry.contentRect.width && entry.contentRect.height) {
7759
+ model.value = {
7760
+ ...model.value,
7761
+ width: entry.contentRect.width,
7762
+ height: entry.contentRect.height
7763
+ };
7764
+ observer.unobserve(root);
7765
+ }
7766
+ });
7767
+ observer.observe(root);
7427
7768
  }
7428
- exec("openContextMenu", e);
7429
7769
  }
7430
- }
7431
- function onInputBlur() {
7432
- console.log("onInputBlur");
7433
- editing.value = false;
7434
- if (editValue.value) {
7435
- props.node.name = editValue.value;
7436
- editValue.value = void 0;
7770
+ });
7771
+ __expose({
7772
+ start,
7773
+ activeHandle,
7774
+ transforming
7775
+ });
7776
+ function Diagonal() {
7777
+ const handle = activeHandle.value;
7778
+ if (!handle || !handle.startsWith("resize")) {
7779
+ return void 0;
7780
+ }
7781
+ switch (props.resizeStrategy) {
7782
+ case "lockAspectRatio":
7783
+ break;
7784
+ case "lockAspectRatioDiagonal":
7785
+ if (handle.split("-").length === 2) {
7786
+ return void 0;
7787
+ }
7788
+ break;
7789
+ default:
7790
+ return void 0;
7791
+ }
7792
+ if (handle === "resize-top" || handle === "resize-right" || handle === "resize-top-right" || handle === "resize-bottom-left") {
7793
+ return h("line", {
7794
+ class: "mce-transformable__diagonal",
7795
+ x1: "100%",
7796
+ y1: "0",
7797
+ x2: "0",
7798
+ y2: "100%"
7799
+ });
7800
+ } else if (handle === "resize-left" || handle === "resize-bottom" || handle === "resize-top-left" || handle === "resize-bottom-right") {
7801
+ return h("line", {
7802
+ class: "mce-transformable__diagonal",
7803
+ x1: "0",
7804
+ y1: "0",
7805
+ x2: "100%",
7806
+ y2: "100%"
7807
+ });
7437
7808
  }
7809
+ return void 0;
7438
7810
  }
7439
7811
  return (_ctx, _cache) => {
7440
- const _component_MceLayer = resolveComponent("MceLayer");
7441
- return openBlock(), createElementBlock(Fragment, null, [
7442
- createElementVNode("div", {
7443
- ref_key: "dom",
7444
- ref: dom,
7445
- class: normalizeClass(["mce-layer", [
7446
- props.root && "mce-layer--root",
7447
- (__props.active || isActive.value) && "mce-layer--active",
7448
- isFrist.value && "mce-layer--first",
7449
- isLast.value && "mce-layer--last",
7450
- opened.value && "mce-layer--open",
7451
- isHoverElement.value && "mce-layer--hover"
7452
- ]]),
7453
- style: normalizeStyle({
7454
- "--indent-padding": `${props.indent * 16}px`
7812
+ return openBlock(), createBlock(resolveDynamicComponent(__props.tag), {
7813
+ class: normalizeClass(["mce-transformable", [
7814
+ transforming.value && "mce-transformable--transforming",
7815
+ props.hideUi && "mce-transformable--hide-ui",
7816
+ __props.resizeStrategy && `mce-transformable--${__props.resizeStrategy}`,
7817
+ activeHandle.value && `mce-transformable--${activeHandle.value}`,
7818
+ activeHandle.value === "move" && "mce-transformable--moving",
7819
+ activeHandle.value?.startsWith("resize") && "mce-transformable--resizing",
7820
+ activeHandle.value?.startsWith("rotate") && "mce-transformable--rotateing",
7821
+ props.borderStyle && `mce-transformable--${props.borderStyle}`
7822
+ ]]),
7823
+ style: normalizeStyle(style.value)
7824
+ }, {
7825
+ default: withCtx(() => [
7826
+ renderSlot(_ctx.$slots, "default", {
7827
+ value: unref(modelValue),
7828
+ props: {
7829
+ onPointerdown: start
7830
+ },
7831
+ start
7455
7832
  }),
7456
- onMousedown,
7457
- onMouseenter,
7458
- onMouseleave,
7459
- onContextmenu
7460
- }, [
7461
- createElementVNode("div", {
7462
- class: "mce-layer__expand",
7463
- onClick: onClickExpand
7464
- }, [
7465
- props.node.children.length ? (openBlock(), createBlock(_sfc_main$z, {
7466
- key: 0,
7467
- icon: "$arrowRight"
7468
- })) : createCommentVNode("", true)
7469
- ]),
7470
- createElementVNode("div", {
7471
- class: "mce-layer__content",
7472
- onClick: onClickContent,
7473
- onDblclick: onDblclickContent
7474
- }, [
7475
- createElementVNode("div", {
7476
- class: "mce-layer__thumbnail",
7477
- onDblclick: onDblclickThumbnail
7478
- }, [
7479
- createVNode(_sfc_main$z, { icon: thumbnailIcon.value }, null, 8, ["icon"])
7480
- ], 32),
7481
- createElementVNode("div", _hoisted_1$f, [
7482
- withDirectives(createElementVNode("input", {
7483
- ref_key: "inputDom",
7484
- ref: inputDom,
7485
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => editValue.value = $event),
7486
- type: "text",
7487
- class: "mce-layer__input",
7488
- autofocus: "",
7489
- onBlur: onInputBlur
7490
- }, null, 544), [
7491
- [vShow, editing.value],
7492
- [vModelText, editValue.value]
7493
- ]),
7494
- createElementVNode("div", {
7495
- style: normalizeStyle({ visibility: editing.value ? "hidden" : void 0 })
7496
- }, toDisplayString(editValue.value || props.node.name || props.node.id), 5)
7833
+ (openBlock(), createElementBlock("svg", _hoisted_1$j, [
7834
+ _cache[0] || (_cache[0] = createElementVNode("rect", {
7835
+ width: "100%",
7836
+ height: "100%",
7837
+ fill: "none",
7838
+ class: "mce-transformable__rect"
7839
+ }, null, -1)),
7840
+ createElementVNode("rect", {
7841
+ class: "mce-transformable__rect",
7842
+ width: "100%",
7843
+ height: "100%",
7844
+ fill: "none",
7845
+ rx: model.value.borderRadius,
7846
+ ry: model.value.borderRadius
7847
+ }, null, 8, _hoisted_2$8),
7848
+ createVNode(Diagonal),
7849
+ createElementVNode("g", null, [
7850
+ (openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value, (handle, index) => {
7851
+ return openBlock(), createElementBlock(Fragment, { key: index }, [
7852
+ handle.shape ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
7853
+ handle.shape === "rect" ? (openBlock(), createElementBlock("rect", {
7854
+ key: 0,
7855
+ x: handle.x,
7856
+ y: handle.y,
7857
+ width: handle.width,
7858
+ height: handle.height,
7859
+ "aria-label": handle.type,
7860
+ class: "mce-transformable__handle"
7861
+ }, null, 8, _hoisted_3$6)) : (openBlock(), createElementBlock("circle", {
7862
+ key: 1,
7863
+ cx: handle.x + handle.width / 2,
7864
+ cy: handle.y + handle.width / 2,
7865
+ r: handle.width / 2,
7866
+ "aria-label": handle.type,
7867
+ class: "mce-transformable__handle"
7868
+ }, null, 8, _hoisted_4$3))
7869
+ ], 64)) : createCommentVNode("", true)
7870
+ ], 64);
7871
+ }), 128))
7872
+ ]),
7873
+ createElementVNode("g", _hoisted_5$2, [
7874
+ (openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value, (handle, index) => {
7875
+ return openBlock(), createElementBlock("rect", {
7876
+ key: index,
7877
+ ref_for: true,
7878
+ ref_key: "handlesRef",
7879
+ ref: handlesRef,
7880
+ x: handle.x,
7881
+ y: handle.y,
7882
+ width: handle.width,
7883
+ height: handle.height,
7884
+ "aria-label": handle.type,
7885
+ class: "mce-transformable__handle-rect",
7886
+ cursor: transforming.value ? "auto" : getCursor(handle.type),
7887
+ onPointerdown: (event) => start(event, index)
7888
+ }, null, 40, _hoisted_6$2);
7889
+ }), 128))
7497
7890
  ]),
7498
- createElementVNode("div", _hoisted_2$8, [
7499
- props.root ? (openBlock(), createElementBlock("div", {
7500
- key: 0,
7501
- class: normalizeClass(["mce-btn", {
7502
- "mce-btn--hide": !hovering.value && !unref(isLock)(props.node)
7503
- }]),
7504
- onClick: _cache[1] || (_cache[1] = ($event) => unref(setLock)(props.node, !unref(isLock)(props.node)))
7505
- }, [
7506
- createVNode(_sfc_main$z, {
7507
- icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
7508
- }, null, 8, ["icon"])
7509
- ], 2)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
7510
- createVNode(_sfc_main$p, {
7511
- class: normalizeClass({
7512
- "mce-btn--hide": !hovering.value && !unref(isLock)(props.node)
7513
- }),
7514
- onClick: _cache[2] || (_cache[2] = withModifiers(($event) => unref(setLock)(props.node, !unref(isLock)(props.node)), ["prevent", "stop"]))
7515
- }, {
7516
- default: withCtx(() => [
7517
- createVNode(_sfc_main$z, {
7518
- icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
7519
- }, null, 8, ["icon"])
7520
- ]),
7521
- _: 1
7522
- }, 8, ["class"]),
7523
- createVNode(_sfc_main$p, {
7524
- class: normalizeClass({
7525
- "mce-btn--hide": !hovering.value && unref(isVisible)(props.node)
7526
- }),
7527
- onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(setVisible)(props.node, !unref(isVisible)(props.node)), ["prevent", "stop"]))
7528
- }, {
7529
- default: withCtx(() => [
7530
- createVNode(_sfc_main$z, {
7531
- icon: unref(isVisible)(props.node) ? "$visible" : "$unvisible"
7532
- }, null, 8, ["icon"])
7533
- ]),
7534
- _: 1
7535
- }, 8, ["class"])
7536
- ], 64))
7891
+ createElementVNode("g", _hoisted_7$2, [
7892
+ renderSlot(_ctx.$slots, "svg", { box: model.value })
7537
7893
  ])
7538
- ], 32)
7539
- ], 38),
7540
- opened.value ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.node.children, (child, key) => {
7541
- return openBlock(), createBlock(_component_MceLayer, {
7542
- key,
7543
- node: child,
7544
- indent: __props.root ? props.indent : props.indent + 1,
7545
- active: __props.active || isActive.value
7546
- }, null, 8, ["node", "indent", "active"]);
7547
- }), 128)) : createCommentVNode("", true)
7548
- ], 64);
7894
+ ])),
7895
+ tip.value ? (openBlock(), createElementBlock("div", _hoisted_8$1, toDisplayString(tip.value), 1)) : createCommentVNode("", true)
7896
+ ]),
7897
+ _: 3
7898
+ }, 8, ["class", "style"]);
7549
7899
  };
7550
7900
  }
7551
7901
  });
7552
- const _hoisted_1$e = { class: "mce-layers" };
7553
- const _hoisted_2$7 = { class: "mce-layers__wrapper" };
7554
- const _sfc_main$n = /* @__PURE__ */ defineComponent({
7555
- __name: "Layers",
7902
+ const _hoisted_1$i = { class: "mce-cropper" };
7903
+ const _sfc_main$u = /* @__PURE__ */ defineComponent({
7904
+ __name: "Cropper",
7905
+ props: /* @__PURE__ */ mergeModels({
7906
+ image: {},
7907
+ minScale: { default: 0.1 },
7908
+ maxScale: { default: 3 }
7909
+ }, {
7910
+ "modelValue": { default: () => ({}) },
7911
+ "modelModifiers": {},
7912
+ "style": { default: () => ({}) },
7913
+ "styleModifiers": {}
7914
+ }),
7915
+ emits: /* @__PURE__ */ mergeModels(["start", "end", "update:transform"], ["update:modelValue", "update:style"]),
7916
+ setup(__props, { emit: __emit }) {
7917
+ const props = __props;
7918
+ const emit = __emit;
7919
+ const cropRect = useModel(__props, "modelValue");
7920
+ const styleModel = useModel(__props, "style");
7921
+ const rootBox = ref({ width: 0, height: 0 });
7922
+ const { state: imageRef } = useImage(
7923
+ computed(() => ({
7924
+ src: props.image
7925
+ }))
7926
+ );
7927
+ const backup = cloneDeep(cropRect.value);
7928
+ const canvasRef = useTemplateRef("canvasRef");
7929
+ const computedCropRect = computed({
7930
+ get: () => {
7931
+ const { left = 0, top = 0, right = 0, bottom = 0 } = cropRect.value;
7932
+ return { left, top, right, bottom };
7933
+ },
7934
+ set: (val) => cropRect.value = val
7935
+ });
7936
+ const inverseMat = computed(() => {
7937
+ const { left, top, right, bottom } = computedCropRect.value;
7938
+ const sx = 1 / (1 - left - right);
7939
+ const sy = 1 / (1 - top - bottom);
7940
+ const tx = -left;
7941
+ const ty = -top;
7942
+ return { sx, sy, tx, ty };
7943
+ });
7944
+ const sourceTransform = computed({
7945
+ get: () => {
7946
+ const { sx, sy, tx, ty } = inverseMat.value;
7947
+ const { scaleX = 1, scaleY = 1 } = styleModel.value;
7948
+ const { width, height } = rootBox.value;
7949
+ return {
7950
+ width: sx * width,
7951
+ height: sy * height,
7952
+ left: tx * scaleX * (sx * width),
7953
+ top: ty * scaleY * (sy * height)
7954
+ };
7955
+ },
7956
+ set: (newValue) => {
7957
+ const { width, height } = rootBox.value;
7958
+ const { scaleX = 1, scaleY = 1 } = styleModel.value;
7959
+ const transform = {
7960
+ sx: newValue.width / width,
7961
+ sy: newValue.height / height,
7962
+ tx: newValue.left / newValue.width / scaleX,
7963
+ ty: newValue.top / newValue.height / scaleY
7964
+ };
7965
+ const left = -transform.tx;
7966
+ const top = -transform.ty;
7967
+ const w = 1 - 1 / transform.sx;
7968
+ const h2 = 1 - 1 / transform.sy;
7969
+ const right = w - left;
7970
+ const bottom = h2 - top;
7971
+ computedCropRect.value = { left, top, right, bottom };
7972
+ }
7973
+ });
7974
+ const scale = computed({
7975
+ get: () => inverseMat.value.sx,
7976
+ set: (value) => {
7977
+ const transform = inverseMat.value;
7978
+ const rate = transform.sx / value;
7979
+ const left = -transform.tx;
7980
+ const top = -transform.ty;
7981
+ const w = 1 - 1 / value;
7982
+ const h2 = 1 - 1 / transform.sy * rate;
7983
+ const right = w - left;
7984
+ const bottom = h2 - top;
7985
+ computedCropRect.value = { left, top, right, bottom };
7986
+ }
7987
+ });
7988
+ onBeforeMount(() => emit("start"));
7989
+ onBeforeUnmount(() => emit("end"));
7990
+ const sourceStyle = computed(() => {
7991
+ const { sx, sy, tx, ty } = inverseMat.value;
7992
+ const { scaleX = 1, scaleY = 1 } = styleModel.value;
7993
+ return {
7994
+ transform: [
7995
+ `scale(${sx}, ${sy})`,
7996
+ `translate(${tx * scaleX * 100}%, ${ty * scaleY * 100}%)`
7997
+ ].join(" ")
7998
+ };
7999
+ });
8000
+ watch([canvasRef, imageRef], render2);
8001
+ watch(computedCropRect, render2, { deep: true });
8002
+ watch([() => styleModel.value.scaleX, () => styleModel.value.scaleY], render2);
8003
+ function render2() {
8004
+ const ctx = canvasRef.value?.getContext("2d");
8005
+ if (!ctx || !imageRef.value)
8006
+ return;
8007
+ const { scaleX = 1, scaleY = 1 } = styleModel.value;
8008
+ const { naturalWidth, naturalHeight } = imageRef.value;
8009
+ ctx.canvas.width = naturalWidth;
8010
+ ctx.canvas.height = naturalHeight;
8011
+ ctx.clearRect(0, 0, naturalWidth, naturalHeight);
8012
+ ctx.globalAlpha = 0.4;
8013
+ ctx.scale(scaleX, scaleY);
8014
+ ctx.drawImage(imageRef.value, 0, 0, naturalWidth, naturalHeight);
8015
+ }
8016
+ function ok() {
8017
+ emit("end");
8018
+ }
8019
+ function cancel() {
8020
+ cropRect.value = backup;
8021
+ ok();
8022
+ }
8023
+ function onResizeObserver(entries) {
8024
+ const { width, height } = entries[0].contentRect;
8025
+ rootBox.value = { width, height };
8026
+ }
8027
+ function applySourceTransformToStyle() {
8028
+ const { left = 0, top = 0, width = 0, height = 0 } = styleModel.value;
8029
+ const { sx, sy, tx, ty } = inverseMat.value;
8030
+ cropRect.value = {};
8031
+ styleModel.value = {
8032
+ ...styleModel.value,
8033
+ width: sx * width,
8034
+ height: sy * height,
8035
+ left: left + tx * (sx * width),
8036
+ top: top + ty * (sy * height)
8037
+ };
8038
+ ok();
8039
+ }
8040
+ return (_ctx, _cache) => {
8041
+ return withDirectives((openBlock(), createElementBlock("div", _hoisted_1$i, [
8042
+ createElementVNode("div", {
8043
+ class: "mce-cropper__source",
8044
+ style: normalizeStyle(sourceStyle.value)
8045
+ }, [
8046
+ createElementVNode("canvas", {
8047
+ ref_key: "canvasRef",
8048
+ ref: canvasRef
8049
+ }, null, 512)
8050
+ ], 4),
8051
+ createVNode(_sfc_main$v, {
8052
+ modelValue: sourceTransform.value,
8053
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => sourceTransform.value = $event),
8054
+ class: "mce-cropper__transformable",
8055
+ rotatable: false
8056
+ }, {
8057
+ default: withCtx(({ props: slotProps }) => [
8058
+ createElementVNode("div", mergeProps({ class: "mce-cropper__transformable_rect" }, slotProps), null, 16)
8059
+ ]),
8060
+ _: 1
8061
+ }, 8, ["modelValue"]),
8062
+ renderSlot(_ctx.$slots, "default", {
8063
+ scale: scale.value,
8064
+ ok,
8065
+ cancel,
8066
+ applySourceTransformToStyle
8067
+ })
8068
+ ])), [
8069
+ [unref(vResizeObserver), onResizeObserver]
8070
+ ]);
8071
+ };
8072
+ }
8073
+ });
8074
+ const _sfc_main$t = /* @__PURE__ */ defineComponent({
8075
+ __name: "ForegroundCropper",
7556
8076
  setup(__props) {
7557
8077
  const {
7558
- root,
7559
- selection,
7560
8078
  state,
7561
- nodeIndexMap
8079
+ setState,
8080
+ elementSelection
7562
8081
  } = useEditor();
7563
- const sortedSelection = computed(() => {
7564
- return selection.value.map((node) => {
7565
- return {
7566
- node,
7567
- index: nodeIndexMap.get(node.id) ?? 0
7568
- };
7569
- }).sort((a, b) => a.index - b.index).map((v) => v.node);
7570
- });
8082
+ const element = computed(() => elementSelection.value[0]);
8083
+ return (_ctx, _cache) => {
8084
+ return unref(state) === "cropping" && element.value?.foreground.isValid() ? (openBlock(), createBlock(_sfc_main$u, {
8085
+ key: 0,
8086
+ modelValue: element.value.foreground.cropRect,
8087
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => element.value.foreground.cropRect = $event),
8088
+ style: normalizeStyle(element.value.style.toJSON()),
8089
+ image: element.value.foreground.image,
8090
+ class: "pointer-events-auto",
8091
+ "onUpdate:style": _cache[1] || (_cache[1] = (val) => element.value.style.setProperties(val)),
8092
+ onEnd: _cache[2] || (_cache[2] = () => unref(setState)(void 0))
8093
+ }, null, 8, ["modelValue", "style", "image"])) : createCommentVNode("", true);
8094
+ };
8095
+ }
8096
+ });
8097
+ const _sfc_main$s = /* @__PURE__ */ defineComponent({
8098
+ __name: "Frame",
8099
+ props: {
8100
+ "modelValue": { required: true },
8101
+ "modelModifiers": {}
8102
+ },
8103
+ emits: ["update:modelValue"],
8104
+ setup(__props) {
8105
+ const frame = useModel(__props, "modelValue");
8106
+ const input = useTemplateRef("inputTpl");
7571
8107
  const {
7572
- selecting,
7573
- openedItems,
7574
- domItems
7575
- } = createLayer({
7576
- sortedSelection
7577
- });
7578
- watch(selection, (selection2) => {
7579
- if (state.value === "selecting" || selecting.value) {
7580
- return;
8108
+ getObb,
8109
+ hoverElement,
8110
+ selection,
8111
+ state,
8112
+ config,
8113
+ exec
8114
+ } = useEditor();
8115
+ const editing = ref(false);
8116
+ async function onDblclick() {
8117
+ editing.value = true;
8118
+ await nextTick();
8119
+ if (input.value) {
8120
+ input.value.focus();
8121
+ input.value.select();
7581
8122
  }
7582
- let last;
7583
- selection2.forEach((node) => {
7584
- node.findAncestor((ancestor) => {
7585
- const opened = openedItems.get(ancestor.id);
7586
- if (opened) {
7587
- opened.value = true;
7588
- }
7589
- return false;
7590
- });
7591
- last = node;
7592
- });
7593
- if (last) {
7594
- nextTick().then(() => {
7595
- domItems.get(last.id)?.value?.scrollIntoView({
7596
- block: "center"
7597
- });
7598
- });
8123
+ }
8124
+ async function onPointerdown(ev) {
8125
+ if (!editing.value) {
8126
+ selection.value = [frame.value];
8127
+ await nextTick();
8128
+ exec("startTransform", ev);
7599
8129
  }
7600
- });
8130
+ }
7601
8131
  return (_ctx, _cache) => {
7602
- return openBlock(), createElementBlock("div", _hoisted_1$e, [
7603
- createElementVNode("div", _hoisted_2$7, [
7604
- createVNode(_sfc_main$o, {
7605
- root: true,
7606
- node: unref(root),
7607
- opened: true
7608
- }, null, 8, ["node"])
8132
+ return withDirectives((openBlock(), createElementBlock("div", {
8133
+ style: normalizeStyle(unref(boundingBoxToStyle)(unref(getObb)(frame.value, "drawboard"))),
8134
+ class: normalizeClass(["mce-frame", [
8135
+ unref(config).frameOutline && "mce-frame--outline",
8136
+ unref(hoverElement)?.equal(frame.value) && "mce-frame--hover",
8137
+ unref(selection).some((v) => v.equal(frame.value)) && "mce-frame--selected"
8138
+ ]])
8139
+ }, [
8140
+ withDirectives(createElementVNode("div", {
8141
+ class: "mce-frame__name",
8142
+ onDblclick,
8143
+ onPointerdown,
8144
+ onPointerenter: _cache[2] || (_cache[2] = ($event) => !unref(state) && (hoverElement.value = frame.value)),
8145
+ onPointerleave: _cache[3] || (_cache[3] = ($event) => !unref(state) && (hoverElement.value = void 0))
8146
+ }, [
8147
+ createElementVNode("div", null, toDisplayString(frame.value.name), 1),
8148
+ withDirectives(createElementVNode("input", {
8149
+ ref: "inputTpl",
8150
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => frame.value.name = $event),
8151
+ onBlur: _cache[1] || (_cache[1] = ($event) => editing.value = false)
8152
+ }, null, 544), [
8153
+ [vShow, editing.value],
8154
+ [vModelText, frame.value.name]
8155
+ ])
8156
+ ], 544), [
8157
+ [vShow, unref(config).viewMode === "edgeless"]
7609
8158
  ])
8159
+ ], 6)), [
8160
+ [vShow, frame.value.visible]
7610
8161
  ]);
7611
8162
  };
7612
8163
  }
7613
8164
  });
7614
- const _sfc_main$m = /* @__PURE__ */ defineComponent({
7615
- __name: "Tooltip",
7616
- props: /* @__PURE__ */ mergeModels({
7617
- ...makeMceOverlayProps({
7618
- location: "right",
7619
- offset: 8
7620
- })
7621
- }, {
7622
- "modelValue": { type: Boolean },
7623
- "modelModifiers": {}
7624
- }),
7625
- emits: ["update:modelValue"],
7626
- setup(__props, { expose: __expose }) {
7627
- const props = __props;
7628
- const isActive = useModel(__props, "modelValue");
7629
- const overlay = useTemplateRef("overlayTpl");
7630
- function updateLocation() {
7631
- overlay.value?.updateLocation();
7632
- }
7633
- __expose({
7634
- updateLocation
7635
- });
8165
+ const _sfc_main$r = /* @__PURE__ */ defineComponent({
8166
+ __name: "Frames",
8167
+ setup(__props) {
8168
+ const {
8169
+ frames
8170
+ } = useEditor();
8171
+ return (_ctx, _cache) => {
8172
+ return openBlock(true), createElementBlock(Fragment, null, renderList(unref(frames), (frame, key) => {
8173
+ return openBlock(), createBlock(_sfc_main$s, {
8174
+ key,
8175
+ "model-value": frame
8176
+ }, null, 8, ["model-value"]);
8177
+ }), 128);
8178
+ };
8179
+ }
8180
+ });
8181
+ const _sfc_main$q = /* @__PURE__ */ defineComponent({
8182
+ __name: "GoBackSelectedArea",
8183
+ setup(__props) {
8184
+ const {
8185
+ selectionAabb,
8186
+ drawboardAabb,
8187
+ aabbToDrawboardAabb,
8188
+ t,
8189
+ exec
8190
+ } = useEditor();
8191
+ const isActive = computed(() => {
8192
+ return selectionAabb.value.width && selectionAabb.value.height && !isOverlappingAabb(
8193
+ drawboardAabb.value,
8194
+ aabbToDrawboardAabb(selectionAabb.value)
8195
+ );
8196
+ });
8197
+ return (_ctx, _cache) => {
8198
+ return isActive.value ? (openBlock(), createElementBlock("div", {
8199
+ key: 0,
8200
+ class: "mce-back-selected-aera",
8201
+ onClick: _cache[0] || (_cache[0] = withModifiers(($event) => unref(exec)("scrollToSelection", { behavior: "smooth" }), ["prevent"]))
8202
+ }, [
8203
+ createVNode(_sfc_main$B, { icon: "$gps" }),
8204
+ createElementVNode("span", null, toDisplayString(unref(t)("goBackSelectedArea")), 1)
8205
+ ])) : createCommentVNode("", true);
8206
+ };
8207
+ }
8208
+ });
8209
+ const _hoisted_1$h = ["data-name"];
8210
+ const _sfc_main$p = /* @__PURE__ */ defineComponent({
8211
+ __name: "Hover",
8212
+ setup(__props) {
8213
+ const {
8214
+ selection,
8215
+ hoverElement,
8216
+ getObb,
8217
+ camera
8218
+ } = useEditor();
8219
+ const hoverElementObb = computed(() => getObb(hoverElement.value, "drawboard"));
8220
+ return (_ctx, _cache) => {
8221
+ return unref(hoverElement) && !unref(hoverElement).equal(unref(selection)[0]) ? (openBlock(), createElementBlock("div", {
8222
+ key: 0,
8223
+ class: "mce-hover",
8224
+ "data-name": unref(hoverElement).name,
8225
+ style: normalizeStyle({
8226
+ borderColor: "currentcolor",
8227
+ borderRadius: `${(unref(hoverElement).style.borderRadius ?? 0) * unref(camera).zoom.x}px`,
8228
+ ...unref(boundingBoxToStyle)(hoverElementObb.value)
8229
+ })
8230
+ }, null, 12, _hoisted_1$h)) : createCommentVNode("", true);
8231
+ };
8232
+ }
8233
+ });
8234
+ const _hoisted_1$g = { class: "mce-btn" };
8235
+ const _sfc_main$o = /* @__PURE__ */ defineComponent({
8236
+ __name: "Btn",
8237
+ setup(__props) {
7636
8238
  return (_ctx, _cache) => {
7637
- return openBlock(), createBlock(_sfc_main$y, {
7638
- ref: "overlayTpl",
7639
- modelValue: isActive.value,
7640
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isActive.value = $event),
7641
- class: "mce-tooltip",
7642
- location: props.location,
7643
- offset: props.offset,
7644
- target: props.target,
7645
- attach: props.attach
7646
- }, createSlots({
7647
- default: withCtx(() => [
7648
- isActive.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
7649
- ]),
7650
- _: 2
7651
- }, [
7652
- _ctx.$slots.activator ? {
7653
- name: "activator",
7654
- fn: withCtx((activatorProps) => [
7655
- renderSlot(_ctx.$slots, "activator", normalizeProps(guardReactiveProps(activatorProps)))
7656
- ]),
7657
- key: "0"
7658
- } : void 0
7659
- ]), 1032, ["modelValue", "location", "offset", "target", "attach"]);
8239
+ return openBlock(), createElementBlock("div", _hoisted_1$g, [
8240
+ renderSlot(_ctx.$slots, "default")
8241
+ ]);
7660
8242
  };
7661
8243
  }
7662
8244
  });
7663
- const _hoisted_1$d = ["width", "height"];
7664
- const _hoisted_2$6 = ["onDblclick", "onMousedown", "onMousemove"];
7665
- const _hoisted_3$6 = { style: { "font-size": "12px", "text-wrap": "nowrap" } };
7666
- const _sfc_main$l = /* @__PURE__ */ defineComponent({
8245
+ const _hoisted_1$f = { class: "mce-layer__name" };
8246
+ const _hoisted_2$7 = { class: "mce-layer__action" };
8247
+ const _sfc_main$n = /* @__PURE__ */ defineComponent({
7667
8248
  ...{
8249
+ name: "MceLayer",
7668
8250
  inheritAttrs: false
7669
8251
  },
7670
- __name: "Ruler",
7671
- props: {
7672
- size: { default: 16 },
7673
- vertical: { type: Boolean },
7674
- zoom: { default: 1 },
7675
- position: { default: 0 },
7676
- unit: { default: 50 },
7677
- unitFractions: { default: () => [1, 2, 5, 10] },
7678
- selected: {},
7679
- pixelRatio: { default: window.devicePixelRatio || 1 },
7680
- refline: { type: Boolean },
7681
- axis: { type: Boolean },
7682
- labelFormat: { type: Function, default: (tick) => String(tick) }
7683
- },
7684
- setup(__props, { expose: __expose }) {
8252
+ __name: "Layer",
8253
+ props: /* @__PURE__ */ mergeModels({
8254
+ root: Boolean,
8255
+ node: {
8256
+ type: Object,
8257
+ required: true
8258
+ },
8259
+ active: Boolean,
8260
+ indent: {
8261
+ type: Number,
8262
+ default: 0
8263
+ }
8264
+ }, {
8265
+ "opened": { default: false },
8266
+ "openedModifiers": {}
8267
+ }),
8268
+ emits: ["update:opened"],
8269
+ setup(__props) {
7685
8270
  const props = __props;
7686
- const attrs = useAttrs();
7687
- const pixelRatio = computed(() => props.pixelRatio);
7688
- const tipText = ref();
7689
- const tipPos = ref({ x: 0, y: 0 });
7690
- const canvas = useTemplateRef("canvasTpl");
7691
- const offscreenCanvas = "OffscreenCanvas" in window ? new OffscreenCanvas(props.size, props.size) : document.createElement("canvas");
7692
- const ctx = offscreenCanvas.getContext("2d");
7693
- const box = ref();
7694
- const colors = reactive({
7695
- text: "#000",
7696
- border: "#000"
8271
+ const {
8272
+ isElement,
8273
+ isFrame,
8274
+ isVisible,
8275
+ setVisible,
8276
+ isLock,
8277
+ setLock,
8278
+ selection,
8279
+ nodes,
8280
+ nodeIndexMap,
8281
+ zoomTo,
8282
+ hoverElement,
8283
+ exec
8284
+ } = useEditor();
8285
+ const opened = useModel(__props, "opened");
8286
+ const dom = ref();
8287
+ const {
8288
+ selecting,
8289
+ sortedSelection
8290
+ } = useLayerItem({
8291
+ id: props.node.id,
8292
+ opened,
8293
+ node: computed(() => props.node),
8294
+ dom: computed(() => dom.value)
7697
8295
  });
7698
- function drawSelected() {
7699
- if (!props.selected?.width || !props.selected?.height)
7700
- return;
7701
- ctx.fillStyle = "#6165FD20";
7702
- const offset2 = props.vertical ? props.selected.top : props.selected.left;
7703
- const length = props.vertical ? props.selected.height : props.selected.width;
7704
- ctx.fillRect(offset2, 0, length, props.size);
7705
- }
7706
- function drawAxis(start2, end2, size, color) {
7707
- ctx.lineWidth = size;
7708
- ctx.strokeStyle = color;
7709
- ctx.beginPath();
7710
- ctx.moveTo(start2[0], start2[1]);
7711
- ctx.lineTo(end2[0], end2[1]);
7712
- ctx.stroke();
7713
- }
7714
- function drawTick(tick, len, direction = 1) {
7715
- const x1 = tick;
7716
- const y1 = props.size;
7717
- const x2 = tick;
7718
- const y2 = props.size - len * direction;
7719
- ctx.moveTo(x1, y1);
7720
- ctx.lineTo(x2, y2);
7721
- }
7722
- function drawText(content, tick, top, size) {
7723
- ctx.font = `${size}px sans-serif`;
7724
- ctx.textAlign = "left";
7725
- ctx.textBaseline = "bottom";
7726
- const x2 = tick;
7727
- const y2 = props.size - top;
7728
- ctx.save();
7729
- if (props.vertical) {
7730
- ctx.translate(0, props.size);
7731
- ctx.scale(1, -1);
7732
- }
7733
- ctx.fillText(content, x2, y2);
7734
- ctx.restore();
7735
- }
7736
- const unit = computed(() => {
7737
- const idealUnit = Math.max(props.unit / props.zoom, 1);
7738
- const unitFractions = props.unitFractions;
7739
- const exponent = Math.floor(Math.log10(idealUnit));
7740
- const fraction = idealUnit / 10 ** exponent;
7741
- let niceFraction = unitFractions[unitFractions.length - 1];
7742
- for (const cur of unitFractions) {
7743
- if (fraction <= cur) {
7744
- niceFraction = cur;
7745
- break;
7746
- }
8296
+ const isFrist = computed(() => sortedSelection.value[0]?.equal(props.node));
8297
+ const isLast = computed(() => {
8298
+ const last = sortedSelection.value[sortedSelection.value.length - 1];
8299
+ if (last) {
8300
+ if (last.equal(props.node)) {
8301
+ if (!opened.value || !props.node?.children.length)
8302
+ return true;
8303
+ } else if (last.equal(props.node?.parent)) ;
7747
8304
  }
7748
- return niceFraction * 10 ** exponent;
7749
- });
7750
- const start = computed(() => {
7751
- const value = props.position / props.zoom;
7752
- return Math.floor(value / unit.value) * unit.value;
7753
- });
7754
- const end = computed(() => {
7755
- const len = (props.vertical ? box.value?.height : box.value?.width) ?? 0;
7756
- const value = len / props.zoom;
7757
- return start.value + Math.ceil(value / unit.value) * unit.value;
8305
+ return false;
7758
8306
  });
7759
- function numToPx(num) {
7760
- return Math.round(num * props.zoom - props.position);
7761
- }
7762
- function pxToNum(px) {
7763
- return Math.round((px + props.position) / props.zoom);
7764
- }
7765
- function render2() {
7766
- const cvs = canvas.value;
7767
- if (!cvs || !offscreenCanvas.width || !offscreenCanvas.height)
7768
- return;
7769
- ctx.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
7770
- ctx.save();
7771
- ctx.scale(pixelRatio.value, pixelRatio.value);
7772
- if (props.vertical) {
7773
- ctx.scale(1, -1);
7774
- ctx.translate(0, 0);
7775
- ctx.rotate(-Math.PI / 2);
7776
- }
7777
- drawSelected();
7778
- if (props.axis) {
7779
- drawAxis(
7780
- [0, props.size],
7781
- [props.vertical ? cvs.height : cvs.width, props.size],
7782
- 2,
7783
- colors.border
7784
- );
7785
- }
7786
- const drawPrimary = (tick, label) => {
7787
- drawTick(tick, 10);
7788
- drawText(label, tick + 2, 4, 8);
7789
- };
7790
- const drawSecondary = (tick) => drawTick(tick, 4);
7791
- let inc = unit.value / 10;
7792
- inc = (inc > 0 ? 1 : -1) * Math.max(1, Math.abs(inc));
7793
- ctx.beginPath();
7794
- ctx.lineWidth = 1;
7795
- ctx.strokeStyle = colors.text;
7796
- ctx.fillStyle = colors.text;
7797
- for (let tick = start.value; tick <= end.value; tick += inc) {
7798
- if (tick % unit.value === 0) {
7799
- drawPrimary(numToPx(tick), props.labelFormat(tick));
7800
- }
7801
- }
7802
- ctx.stroke();
7803
- ctx.beginPath();
7804
- ctx.lineWidth = 1;
7805
- ctx.strokeStyle = colors.border;
7806
- for (let tick = start.value; tick <= end.value; tick += inc) {
7807
- if (tick % unit.value === 0) ;
7808
- else if (tick % inc === 0) {
7809
- drawSecondary(numToPx(tick));
8307
+ const isActive = computed(() => selection.value.some((v) => v.equal(props.node)));
8308
+ const inputDom = ref();
8309
+ const isHoverElement = computed(() => props.node?.equal(hoverElement.value));
8310
+ const hovering = ref(false);
8311
+ const editing = ref(false);
8312
+ const editValue = ref();
8313
+ const thumbnailIcon = computed(() => {
8314
+ const node = props.node;
8315
+ if (isFrame(node)) {
8316
+ return "$frame";
8317
+ } else if (node.children.length) {
8318
+ return "$group";
8319
+ } else if (isElement(node)) {
8320
+ if (node.foreground.isValid() && node.foreground.image) {
8321
+ return "$image";
7810
8322
  }
7811
- }
7812
- ctx.stroke();
7813
- ctx.restore();
7814
- if ("transferToImageBitmap" in offscreenCanvas) {
7815
- cvs.getContext("bitmaprenderer").transferFromImageBitmap(offscreenCanvas.transferToImageBitmap());
7816
- } else {
7817
- const mainCtx = cvs.getContext("2d");
7818
- if (mainCtx) {
7819
- mainCtx.clearRect(0, 0, cvs.width, cvs.height);
7820
- mainCtx.drawImage(offscreenCanvas, 0, 0);
8323
+ if (node.text.isValid()) {
8324
+ return "$text";
7821
8325
  }
7822
8326
  }
8327
+ return "$shape";
8328
+ });
8329
+ function onMousedown() {
7823
8330
  }
7824
- watch(
7825
- [canvas, () => props.zoom, () => props.position, () => props.selected],
7826
- () => {
7827
- render2();
7828
- },
7829
- { immediate: true, deep: true }
7830
- );
7831
- const resize = useDebounceFn(() => {
7832
- if (!canvas.value)
7833
- return;
7834
- const _box = canvas.value.parentElement.getBoundingClientRect();
7835
- offscreenCanvas.width = canvas.value.width = _box.width * pixelRatio.value;
7836
- offscreenCanvas.height = canvas.value.height = _box.height * pixelRatio.value;
7837
- canvas.value.style.width = `${_box.width}px`;
7838
- canvas.value.style.height = `${_box.height}px`;
7839
- box.value = _box;
7840
- render2();
7841
- }, 50);
7842
- onMounted(() => {
7843
- resize();
7844
- const dom = canvas.value;
7845
- if (dom) {
7846
- const style = window.getComputedStyle(dom);
7847
- colors.text = style.getPropertyValue("--text-color").trim();
7848
- colors.border = style.getPropertyValue("--border-color").trim();
8331
+ function onClickExpand() {
8332
+ opened.value = !opened.value;
8333
+ }
8334
+ function onClickContent(e) {
8335
+ selecting.value = true;
8336
+ if (isElement(props.node)) {
8337
+ if (e.shiftKey) {
8338
+ const _nodes = [
8339
+ ...selection.value.filter((v) => !v.equal(props.node)),
8340
+ props.node
8341
+ ];
8342
+ let min;
8343
+ let max;
8344
+ _nodes.forEach((el) => {
8345
+ const index = nodeIndexMap.get(el.id);
8346
+ if (index !== void 0) {
8347
+ min = min === void 0 ? index : Math.min(min, index);
8348
+ max = max === void 0 ? index : Math.max(max, index);
8349
+ }
8350
+ });
8351
+ if (min !== void 0 && max !== void 0) {
8352
+ let _selection = nodes.value.slice(min, max + 1);
8353
+ const result = new Set(_selection.map((node) => node.id));
8354
+ const parents = /* @__PURE__ */ new Set();
8355
+ _selection.forEach((node) => node.parent && parents.add(node.parent));
8356
+ parents.forEach((parent) => {
8357
+ if (parent.children.every((ch) => result.has(ch.id))) {
8358
+ const ids = new Set(parent.children.map((ch) => ch.id));
8359
+ _selection = [
8360
+ ..._selection.filter((v) => !ids.has(v.id)),
8361
+ parent
8362
+ ];
8363
+ }
8364
+ });
8365
+ selection.value = _selection;
8366
+ }
8367
+ } else if (e.ctrlKey || e.metaKey) {
8368
+ const filtered = selection.value.filter((v) => !v.equal(props.node));
8369
+ if (filtered.length !== selection.value.length) {
8370
+ selection.value = filtered;
8371
+ } else {
8372
+ selection.value = [...filtered, props.node];
8373
+ }
8374
+ } else {
8375
+ selection.value = [props.node];
8376
+ }
7849
8377
  }
7850
- });
7851
- onBeforeUnmount(() => {
7852
- offscreenCanvas.width = 0;
7853
- offscreenCanvas.height = 0;
7854
- });
7855
- const savedLines = ref([]);
7856
- const tempLine = ref();
7857
- const lines = computed(() => {
7858
- const res = [...savedLines.value];
7859
- if (typeof tempLine.value === "number")
7860
- res.unshift(tempLine.value);
7861
- return res;
7862
- });
7863
- function getTick(e) {
7864
- return pxToNum(
7865
- props.vertical ? e.clientY - box.value.top : e.clientX - box.value.left
7866
- );
8378
+ nextTick().then(() => {
8379
+ selecting.value = false;
8380
+ });
7867
8381
  }
7868
- function onMousedown(e) {
7869
- const tick = getTick(e);
7870
- if (props.refline) {
7871
- savedLines.value.push(tick);
8382
+ function onDblclickThumbnail(e) {
8383
+ e.stopPropagation();
8384
+ if (isElement(props.node)) {
8385
+ zoomTo("selection", {
8386
+ behavior: "smooth"
8387
+ });
7872
8388
  }
7873
8389
  }
7874
- function onMousemove(e, temp = false) {
7875
- const tick = getTick(e);
7876
- if (props.refline && temp) {
7877
- tempLine.value = tick;
8390
+ function onDblclickContent() {
8391
+ editing.value = true;
8392
+ editValue.value = props.node.name;
8393
+ nextTick().then(() => {
8394
+ const dom2 = inputDom.value;
8395
+ if (dom2) {
8396
+ dom2.focus();
8397
+ dom2.select();
8398
+ }
8399
+ });
8400
+ }
8401
+ function onMouseenter() {
8402
+ if (isElement(props.node)) {
8403
+ hoverElement.value = props.node;
8404
+ hovering.value = true;
7878
8405
  }
7879
- tipText.value = props.labelFormat(tick);
7880
- tipPos.value = { x: e.clientX, y: e.clientY };
7881
8406
  }
7882
- function onLeave() {
7883
- tempLine.value = void 0;
7884
- tipText.value = void 0;
8407
+ function onMouseleave() {
8408
+ hoverElement.value = void 0;
8409
+ hovering.value = false;
7885
8410
  }
7886
- function onReflineDblclick(index) {
7887
- savedLines.value.splice(index, 1);
8411
+ function onContextmenu(e) {
8412
+ if (isElement(props.node)) {
8413
+ if (!selection.value.some((v) => v.equal(props.node))) {
8414
+ selection.value = [props.node];
8415
+ }
8416
+ exec("openContextMenu", e);
8417
+ }
7888
8418
  }
7889
- function onReflineMousedown(e, index) {
7890
- e.stopPropagation();
7891
- e.preventDefault();
7892
- const move = (e2) => {
7893
- savedLines.value[index] = getTick(e2);
7894
- };
7895
- const up = () => {
7896
- window.removeEventListener("mousemove", move);
7897
- window.removeEventListener("mouseup", up);
7898
- };
7899
- window.addEventListener("mousemove", move);
7900
- window.addEventListener("mouseup", up);
8419
+ function onInputBlur() {
8420
+ editing.value = false;
8421
+ if (editValue.value) {
8422
+ props.node.name = editValue.value;
8423
+ editValue.value = void 0;
8424
+ }
7901
8425
  }
7902
- __expose({
7903
- box
7904
- });
7905
8426
  return (_ctx, _cache) => {
8427
+ const _component_MceLayer = resolveComponent("MceLayer");
7906
8428
  return openBlock(), createElementBlock(Fragment, null, [
7907
- withDirectives((openBlock(), createElementBlock("div", mergeProps({
7908
- class: ["mce-ruler", [
7909
- `mce-ruler--${props.vertical ? "vertical" : "horizontal"}`
7910
- ]],
7911
- style: { "--size": `${props.size}px` }
7912
- }, unref(attrs), {
8429
+ createElementVNode("div", {
8430
+ ref_key: "dom",
8431
+ ref: dom,
8432
+ class: normalizeClass(["mce-layer", [
8433
+ props.root && "mce-layer--root",
8434
+ (__props.active || isActive.value) && "mce-layer--active",
8435
+ isFrist.value && "mce-layer--first",
8436
+ isLast.value && "mce-layer--last",
8437
+ opened.value && "mce-layer--open",
8438
+ isHoverElement.value && "mce-layer--hover"
8439
+ ]]),
8440
+ style: normalizeStyle({
8441
+ "--indent-padding": `${props.indent * 16}px`
8442
+ }),
7913
8443
  onMousedown,
7914
- onMousemove: _cache[0] || (_cache[0] = ($event) => onMousemove($event, true)),
7915
- onMouseleave: onLeave
7916
- }), [
7917
- createElementVNode("canvas", {
7918
- ref: "canvasTpl",
7919
- class: "mce-ruler__canvas",
7920
- width: props.size,
7921
- height: props.size
7922
- }, null, 8, _hoisted_1$d)
7923
- ], 16)), [
7924
- [unref(vResizeObserver), unref(resize)]
7925
- ]),
7926
- (openBlock(true), createElementBlock(Fragment, null, renderList(lines.value, (item, index) => {
7927
- return openBlock(), createElementBlock("div", {
7928
- key: index,
7929
- class: normalizeClass(["mce-ruler-refline", {
7930
- "mce-ruler-refline--vertical": props.vertical,
7931
- "mce-ruler-refline--horizontal": !props.vertical,
7932
- "mce-ruler-refline--temp": item === tempLine.value
7933
- }]),
7934
- style: normalizeStyle({
7935
- [props.vertical ? "height" : "width"]: "0",
7936
- [props.vertical ? "width" : "height"]: "100%",
7937
- [props.vertical ? "top" : "left"]: `${numToPx(item)}px`,
7938
- [props.vertical ? "left" : "top"]: 0
7939
- }),
7940
- onDblclick: ($event) => onReflineDblclick(index),
7941
- onMousedown: ($event) => onReflineMousedown($event, index),
7942
- onMousemove: () => tipText.value = `${item}`,
7943
- onMouseleave: onLeave
7944
- }, null, 46, _hoisted_2$6);
7945
- }), 128)),
7946
- createVNode(_sfc_main$m, {
7947
- "model-value": !!tipText.value,
7948
- target: tipPos.value,
7949
- offset: 24
7950
- }, {
7951
- default: withCtx(() => [
7952
- createElementVNode("div", _hoisted_3$6, toDisplayString(tipText.value), 1)
8444
+ onMouseenter,
8445
+ onMouseleave,
8446
+ onContextmenu
8447
+ }, [
8448
+ createElementVNode("div", {
8449
+ class: "mce-layer__expand",
8450
+ onClick: onClickExpand
8451
+ }, [
8452
+ props.node.children.length ? (openBlock(), createBlock(_sfc_main$B, {
8453
+ key: 0,
8454
+ icon: "$arrowRight"
8455
+ })) : createCommentVNode("", true)
7953
8456
  ]),
7954
- _: 1
7955
- }, 8, ["model-value", "target"])
8457
+ createElementVNode("div", {
8458
+ class: "mce-layer__content",
8459
+ onClick: onClickContent,
8460
+ onDblclick: onDblclickContent
8461
+ }, [
8462
+ createElementVNode("div", {
8463
+ class: "mce-layer__thumbnail",
8464
+ onDblclick: onDblclickThumbnail
8465
+ }, [
8466
+ createVNode(_sfc_main$B, { icon: thumbnailIcon.value }, null, 8, ["icon"])
8467
+ ], 32),
8468
+ createElementVNode("div", _hoisted_1$f, [
8469
+ withDirectives(createElementVNode("input", {
8470
+ ref_key: "inputDom",
8471
+ ref: inputDom,
8472
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => editValue.value = $event),
8473
+ type: "text",
8474
+ class: "mce-layer__input",
8475
+ autofocus: "",
8476
+ onBlur: onInputBlur
8477
+ }, null, 544), [
8478
+ [vShow, editing.value],
8479
+ [vModelText, editValue.value]
8480
+ ]),
8481
+ createElementVNode("div", {
8482
+ style: normalizeStyle({ visibility: editing.value ? "hidden" : void 0 })
8483
+ }, toDisplayString(editValue.value || props.node.name || props.node.id), 5)
8484
+ ]),
8485
+ createElementVNode("div", _hoisted_2$7, [
8486
+ props.root ? (openBlock(), createElementBlock("div", {
8487
+ key: 0,
8488
+ class: normalizeClass(["mce-btn", {
8489
+ "mce-btn--hide": !hovering.value && !unref(isLock)(props.node)
8490
+ }]),
8491
+ onClick: _cache[1] || (_cache[1] = ($event) => unref(setLock)(props.node, !unref(isLock)(props.node)))
8492
+ }, [
8493
+ createVNode(_sfc_main$B, {
8494
+ icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
8495
+ }, null, 8, ["icon"])
8496
+ ], 2)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
8497
+ createVNode(_sfc_main$o, {
8498
+ class: normalizeClass({
8499
+ "mce-btn--hide": !hovering.value && !unref(isLock)(props.node)
8500
+ }),
8501
+ onClick: _cache[2] || (_cache[2] = withModifiers(($event) => unref(setLock)(props.node, !unref(isLock)(props.node)), ["prevent", "stop"]))
8502
+ }, {
8503
+ default: withCtx(() => [
8504
+ createVNode(_sfc_main$B, {
8505
+ icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
8506
+ }, null, 8, ["icon"])
8507
+ ]),
8508
+ _: 1
8509
+ }, 8, ["class"]),
8510
+ createVNode(_sfc_main$o, {
8511
+ class: normalizeClass({
8512
+ "mce-btn--hide": !hovering.value && unref(isVisible)(props.node)
8513
+ }),
8514
+ onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(setVisible)(props.node, !unref(isVisible)(props.node)), ["prevent", "stop"]))
8515
+ }, {
8516
+ default: withCtx(() => [
8517
+ createVNode(_sfc_main$B, {
8518
+ icon: unref(isVisible)(props.node) ? "$visible" : "$unvisible"
8519
+ }, null, 8, ["icon"])
8520
+ ]),
8521
+ _: 1
8522
+ }, 8, ["class"])
8523
+ ], 64))
8524
+ ])
8525
+ ], 32)
8526
+ ], 38),
8527
+ opened.value ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.node.children, (child, key) => {
8528
+ return openBlock(), createBlock(_component_MceLayer, {
8529
+ key,
8530
+ node: child,
8531
+ indent: __props.root ? props.indent : props.indent + 1,
8532
+ active: __props.active || isActive.value
8533
+ }, null, 8, ["node", "indent", "active"]);
8534
+ }), 128)) : createCommentVNode("", true)
7956
8535
  ], 64);
7957
8536
  };
7958
8537
  }
7959
8538
  });
7960
- const _hoisted_1$c = { class: "mce-rulers" };
7961
- const _sfc_main$k = /* @__PURE__ */ defineComponent({
7962
- ...{
7963
- inheritAttrs: false
7964
- },
7965
- __name: "Rulers",
8539
+ const _hoisted_1$e = { class: "mce-layers" };
8540
+ const _hoisted_2$6 = { class: "mce-layers__wrapper" };
8541
+ const _sfc_main$m = /* @__PURE__ */ defineComponent({
8542
+ __name: "Layers",
7966
8543
  setup(__props) {
7967
8544
  const {
7968
- camera,
7969
- getAabbInDrawboard,
7970
- selection
8545
+ root,
8546
+ selection,
8547
+ state,
8548
+ nodeIndexMap
7971
8549
  } = useEditor();
7972
- const activeAabb = computed(() => getAabbInDrawboard(selection.value));
8550
+ const sortedSelection = computed(() => {
8551
+ return selection.value.map((node) => {
8552
+ return {
8553
+ node,
8554
+ index: nodeIndexMap.get(node.id) ?? 0
8555
+ };
8556
+ }).sort((a, b) => a.index - b.index).map((v) => v.node);
8557
+ });
8558
+ const {
8559
+ selecting,
8560
+ openedItems,
8561
+ domItems
8562
+ } = createLayer({
8563
+ sortedSelection
8564
+ });
8565
+ watch(selection, (selection2) => {
8566
+ if (state.value === "selecting" || selecting.value) {
8567
+ return;
8568
+ }
8569
+ let last;
8570
+ selection2.forEach((node) => {
8571
+ node.findAncestor((ancestor) => {
8572
+ const opened = openedItems.get(ancestor.id);
8573
+ if (opened) {
8574
+ opened.value = true;
8575
+ }
8576
+ return false;
8577
+ });
8578
+ last = node;
8579
+ });
8580
+ if (last) {
8581
+ nextTick().then(() => {
8582
+ domItems.get(last.id)?.value?.scrollIntoView({
8583
+ block: "center"
8584
+ });
8585
+ });
8586
+ }
8587
+ });
7973
8588
  return (_ctx, _cache) => {
7974
- return openBlock(), createElementBlock("div", _hoisted_1$c, [
7975
- createVNode(_sfc_main$l, {
7976
- refline: "",
7977
- zoom: unref(camera).zoom.x,
7978
- position: unref(camera).position.x,
7979
- selected: activeAabb.value,
7980
- axis: "",
7981
- size: 16
7982
- }, null, 8, ["zoom", "position", "selected"]),
7983
- createVNode(_sfc_main$l, {
7984
- refline: "",
7985
- zoom: unref(camera).zoom.y,
7986
- position: unref(camera).position.y,
7987
- selected: activeAabb.value,
7988
- axis: "",
7989
- vertical: "",
7990
- size: 16
7991
- }, null, 8, ["zoom", "position", "selected"]),
7992
- _cache[0] || (_cache[0] = createElementVNode("div", { class: "mce-rulers__left-top" }, null, -1))
8589
+ return openBlock(), createElementBlock("div", _hoisted_1$e, [
8590
+ createElementVNode("div", _hoisted_2$6, [
8591
+ createVNode(_sfc_main$n, {
8592
+ root: true,
8593
+ node: unref(root),
8594
+ opened: true
8595
+ }, null, 8, ["node"])
8596
+ ])
7993
8597
  ]);
7994
8598
  };
7995
8599
  }
7996
8600
  });
7997
- const _hoisted_1$b = {
7998
- ref: "trackTplRef",
7999
- class: "mce-scrollbar__track"
8601
+ const _export_sfc = (sfc, props) => {
8602
+ const target = sfc.__vccOpts || sfc;
8603
+ for (const [key, val] of props) {
8604
+ target[key] = val;
8605
+ }
8606
+ return target;
8000
8607
  };
8001
- const _sfc_main$j = /* @__PURE__ */ defineComponent({
8002
- __name: "Scrollbar",
8608
+ const _sfc_main$l = {};
8609
+ const _hoisted_1$d = {
8610
+ class: "mce-made-with",
8611
+ href: "https://github.com/qq15725/mce",
8612
+ target: "_blank"
8613
+ };
8614
+ function _sfc_render$1(_ctx, _cache) {
8615
+ return openBlock(), createElementBlock("a", _hoisted_1$d, [..._cache[0] || (_cache[0] = [
8616
+ createElementVNode("div", null, "MADE WITH", -1),
8617
+ createElementVNode("div", null, "MCE", -1)
8618
+ ])]);
8619
+ }
8620
+ const MadeWith = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$1]]);
8621
+ const _sfc_main$k = /* @__PURE__ */ defineComponent({
8622
+ __name: "Tooltip",
8003
8623
  props: /* @__PURE__ */ mergeModels({
8004
- length: {},
8005
- vertical: { type: Boolean },
8006
- size: {},
8007
- offset: {}
8624
+ ...makeMceOverlayProps({
8625
+ location: "right",
8626
+ offset: 8
8627
+ })
8008
8628
  }, {
8009
- "modelValue": { required: true },
8629
+ "modelValue": { type: Boolean },
8010
8630
  "modelModifiers": {}
8011
8631
  }),
8012
- emits: /* @__PURE__ */ mergeModels(["scroll"], ["update:modelValue"]),
8013
- setup(__props, { emit: __emit }) {
8632
+ emits: ["update:modelValue"],
8633
+ setup(__props, { expose: __expose }) {
8014
8634
  const props = __props;
8015
- const emit = __emit;
8016
- const position = useModel(__props, "modelValue");
8017
- const track = useTemplateRef("trackTplRef");
8018
- const thumb = useTemplateRef("thumbTplRef");
8019
- const trackLength = ref(0);
8020
- const contentLength = computed(() => {
8021
- return props.length + trackLength.value + Math.abs(position.value) * 2;
8022
- });
8023
- const thumbLength = computed(() => {
8024
- return Math.max(0.05, Math.min(1, trackLength.value / contentLength.value));
8025
- });
8026
- const thumbPosition = computed(() => {
8027
- return (Math.abs(position.value) + position.value) / (contentLength.value - trackLength.value) * (1 - thumbLength.value);
8028
- });
8029
- const resize = useDebounceFn(() => {
8030
- const box = track.value?.getBoundingClientRect() ?? { width: 0, height: 0 };
8031
- trackLength.value = props.vertical ? box.height : box.width;
8032
- }, 50);
8033
- const lerp = (a, b, t) => a * (1 - t) + b * t;
8034
- const thumbToTrack = (thumbLength2, thumbPosition2) => lerp(thumbLength2 / 2, 1 - thumbLength2 / 2, thumbPosition2);
8035
- const start = computed(() => thumbToTrack(thumbLength.value, thumbPosition.value));
8036
- const end = computed(() => 1 - start.value - thumbLength.value);
8037
- const thumbTop = computed(() => props.vertical ? `${start.value * 100}%` : "0%");
8038
- const thumbBottom = computed(() => props.vertical ? `${end.value * 100}%` : "50%");
8039
- const thumbLeft = computed(() => props.vertical ? "0%" : `${start.value * 100}%`);
8040
- const thumbRight = computed(() => props.vertical ? "50%" : `${end.value * 100}%`);
8041
- function update(val) {
8042
- emit("scroll", val - position.value);
8043
- position.value = val;
8044
- }
8045
- function amount(val) {
8046
- update(position.value + val);
8635
+ const isActive = useModel(__props, "modelValue");
8636
+ const overlay = useTemplateRef("overlayTpl");
8637
+ function updateLocation() {
8638
+ overlay.value?.updateLocation();
8047
8639
  }
8048
- const isActive = ref(false);
8049
- watch(track, (track2, oldTrack) => {
8050
- function onMousedown(event) {
8051
- if (!thumb.value?.contains(event.target)) {
8052
- return;
8053
- }
8054
- isActive.value = true;
8055
- let last = event;
8056
- event.stopPropagation();
8057
- function onMousemove(event2) {
8058
- const offset2 = {
8059
- x: last.clientX - event2.clientX,
8060
- y: last.clientY - event2.clientY
8061
- };
8062
- last = event2;
8063
- amount((props.vertical ? offset2.y : offset2.x) / (trackLength.value * (1 - thumbLength.value)) * contentLength.value * -1);
8064
- }
8065
- function onMouseup() {
8066
- isActive.value = false;
8067
- window.removeEventListener("mousemove", onMousemove);
8068
- window.removeEventListener("mouseup", onMouseup);
8069
- }
8070
- window.addEventListener("mousemove", onMousemove);
8071
- window.addEventListener("mouseup", onMouseup);
8072
- }
8073
- oldTrack?.removeEventListener("mousedown", onMousedown);
8074
- track2?.addEventListener("mousedown", onMousedown);
8640
+ __expose({
8641
+ updateLocation
8075
8642
  });
8076
8643
  return (_ctx, _cache) => {
8077
- return withDirectives((openBlock(), createElementBlock("div", {
8078
- class: normalizeClass(["mce-scrollbar", {
8079
- "mce-scrollbar--vertical": props.vertical,
8080
- "mce-scrollbar--horizontal": !props.vertical
8081
- }]),
8082
- style: normalizeStyle({
8083
- [props.vertical ? "height" : "width"]: `calc(100% - ${props.size + props.offset}px)`,
8084
- [props.vertical ? "width" : "height"]: `${props.size}px`,
8085
- [props.vertical ? "top" : "left"]: `${props.offset}px`
8086
- })
8087
- }, [
8088
- createElementVNode("div", _hoisted_1$b, [
8089
- createElementVNode("div", {
8090
- ref: "thumbTplRef",
8091
- class: normalizeClass(["mce-scrollbar__thumb", {
8092
- "mce-scrollbar__thumb--active": isActive.value
8093
- }]),
8094
- style: normalizeStyle({
8095
- top: thumbTop.value,
8096
- bottom: thumbBottom.value,
8097
- left: thumbLeft.value,
8098
- right: thumbRight.value
8099
- })
8100
- }, null, 6)
8101
- ], 512)
8102
- ], 6)), [
8103
- [unref(vResizeObserver), unref(resize)]
8104
- ]);
8644
+ return openBlock(), createBlock(_sfc_main$A, {
8645
+ ref: "overlayTpl",
8646
+ modelValue: isActive.value,
8647
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isActive.value = $event),
8648
+ class: "mce-tooltip",
8649
+ location: props.location,
8650
+ offset: props.offset,
8651
+ target: props.target,
8652
+ attach: props.attach
8653
+ }, createSlots({
8654
+ default: withCtx(() => [
8655
+ isActive.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
8656
+ ]),
8657
+ _: 2
8658
+ }, [
8659
+ _ctx.$slots.activator ? {
8660
+ name: "activator",
8661
+ fn: withCtx((activatorProps) => [
8662
+ renderSlot(_ctx.$slots, "activator", normalizeProps(guardReactiveProps(activatorProps)))
8663
+ ]),
8664
+ key: "0"
8665
+ } : void 0
8666
+ ]), 1032, ["modelValue", "location", "offset", "target", "attach"]);
8105
8667
  };
8106
8668
  }
8107
8669
  });
8108
- const _sfc_main$i = /* @__PURE__ */ defineComponent({
8670
+ const _hoisted_1$c = ["width", "height"];
8671
+ const _hoisted_2$5 = ["onDblclick", "onMousedown", "onMousemove"];
8672
+ const _hoisted_3$5 = { style: { "font-size": "12px", "text-wrap": "nowrap" } };
8673
+ const _sfc_main$j = /* @__PURE__ */ defineComponent({
8109
8674
  ...{
8110
8675
  inheritAttrs: false
8111
8676
  },
8112
- __name: "Scrollbars",
8113
- props: {
8114
- infinite: { type: Boolean, default: true },
8115
- offset: { default: 0 },
8116
- size: { default: 8 }
8117
- },
8118
- setup(__props) {
8119
- const props = __props;
8120
- const {
8121
- camera,
8122
- viewAabb
8123
- } = useEditor();
8124
- return (_ctx, _cache) => {
8125
- return openBlock(), createElementBlock(Fragment, null, [
8126
- createVNode(_sfc_main$j, mergeProps(props, {
8127
- modelValue: unref(camera).position.y,
8128
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(camera).position.y = $event),
8129
- vertical: "",
8130
- length: unref(viewAabb).height * unref(camera).zoom.y
8131
- }), null, 16, ["modelValue", "length"]),
8132
- createVNode(_sfc_main$j, mergeProps(props, {
8133
- modelValue: unref(camera).position.x,
8134
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => unref(camera).position.x = $event),
8135
- length: unref(viewAabb).width * unref(camera).zoom.x
8136
- }), null, 16, ["modelValue", "length"])
8137
- ], 64);
8138
- };
8139
- }
8140
- });
8141
- const _hoisted_1$a = { class: "mce-transformable__svg" };
8142
- const _hoisted_2$5 = ["rx", "ry"];
8143
- const _hoisted_3$5 = ["x", "y", "width", "height", "aria-label"];
8144
- const _hoisted_4$3 = ["cx", "cy", "r", "aria-label"];
8145
- const _hoisted_5$2 = { "pointer-events": "all" };
8146
- const _hoisted_6$2 = ["x", "y", "width", "height", "aria-label", "cursor", "onPointerdown"];
8147
- const _hoisted_7$2 = {
8148
- "pointer-events": "all",
8149
- class: "mce-transformable__svg-slot"
8150
- };
8151
- const _hoisted_8$1 = {
8152
- key: 0,
8153
- class: "mce-transformable__tip"
8154
- };
8155
- const _sfc_main$h = /* @__PURE__ */ defineComponent({
8156
- __name: "Transformable",
8677
+ __name: "Ruler",
8157
8678
  props: {
8158
- tag: { default: "div" },
8159
- modelValue: {},
8160
- movable: { type: Boolean, default: true },
8161
- rotatable: { type: Boolean, default: true },
8162
- resizable: { type: Boolean, default: true },
8163
- adjustableBorderRadius: { type: Boolean, default: false },
8164
- threshold: { default: 0 },
8165
- resizeStrategy: {},
8166
- handleStrategy: {},
8167
- handleShape: { default: "rect" },
8168
- hideUi: { type: Boolean },
8169
- handles: { default: () => [
8170
- "move",
8171
- // resize
8172
- "resize-left",
8173
- "resize-top",
8174
- "resize-right",
8175
- "resize-bottom",
8176
- "resize-top-left",
8177
- "resize-top-right",
8178
- "resize-bottom-right",
8179
- "resize-bottom-left",
8180
- // border-radius
8181
- "border-radius-top-left",
8182
- "border-radius-top-right",
8183
- "border-radius-bottom-left",
8184
- "border-radius-bottom-right",
8185
- // rotate
8186
- "rotate-top-left",
8187
- "rotate-top-right",
8188
- "rotate-bottom-left",
8189
- "rotate-bottom-right"
8190
- ] },
8191
- initialSize: { type: Boolean },
8192
- borderStyle: {},
8193
- tipFormat: {}
8679
+ size: { default: 16 },
8680
+ vertical: { type: Boolean },
8681
+ zoom: { default: 1 },
8682
+ position: { default: 0 },
8683
+ unit: { default: 50 },
8684
+ unitFractions: { default: () => [1, 2, 5, 10] },
8685
+ selected: {},
8686
+ pixelRatio: { default: window.devicePixelRatio || 1 },
8687
+ refline: { type: Boolean },
8688
+ axis: { type: Boolean },
8689
+ labelFormat: { type: Function, default: (tick) => String(tick) }
8194
8690
  },
8195
- emits: ["update:modelValue", "start", "move", "end"],
8196
- setup(__props, { expose: __expose, emit: __emit }) {
8691
+ setup(__props, { expose: __expose }) {
8197
8692
  const props = __props;
8198
- const emit = __emit;
8199
- const cursors = {
8200
- "rotate-top-left": (angle) => createCursor("rotate", 360 + angle),
8201
- "rotate-top-right": (angle) => createCursor("rotate", 90 + angle),
8202
- "rotate-bottom-left": (angle) => createCursor("rotate", 270 + angle),
8203
- "rotate-bottom-right": (angle) => createCursor("rotate", 180 + angle),
8204
- "resize-left": (angle) => createCursor("resizeXy", 180 + angle),
8205
- "resize-top": (angle) => createCursor("resizeXy", 90 + angle),
8206
- "resize-right": (angle) => createCursor("resizeXy", 180 + angle),
8207
- "resize-bottom": (angle) => createCursor("resizeXy", 90 + angle),
8208
- "resize-top-left": (angle) => createCursor("resizeBevel", 90 + angle),
8209
- "resize-top-right": (angle) => createCursor("resizeBevel", 180 + angle),
8210
- "resize-bottom-right": (angle) => createCursor("resizeBevel", 90 + angle),
8211
- "resize-bottom-left": (angle) => createCursor("resizeBevel", 180 + angle)
8212
- };
8213
- const modelValue = useModel(props, "modelValue");
8214
- const model = computed({
8215
- get: () => {
8216
- let { left = 0, top = 0, width = 0, height = 0, rotate = 0, borderRadius = 0 } = modelValue.value ?? {};
8217
- if (Number.isNaN(Number(width)))
8218
- width = 0;
8219
- if (Number.isNaN(Number(height)))
8220
- height = 0;
8221
- return { left, top, width, height, rotate, borderRadius };
8222
- },
8223
- set: (val) => modelValue.value = val
8693
+ const attrs = useAttrs();
8694
+ const pixelRatio = computed(() => props.pixelRatio);
8695
+ const tipText = ref();
8696
+ const tipPos = ref({ x: 0, y: 0 });
8697
+ const canvas = useTemplateRef("canvasTpl");
8698
+ const offscreenCanvas = "OffscreenCanvas" in window ? new OffscreenCanvas(props.size, props.size) : document.createElement("canvas");
8699
+ const ctx = offscreenCanvas.getContext("2d");
8700
+ const box = ref();
8701
+ const colors = reactive({
8702
+ text: "#000",
8703
+ border: "#000"
8224
8704
  });
8225
- const transforming = ref(false);
8226
- const activeHandle = ref();
8227
- const computedHandles = computed(() => {
8228
- const size = 8;
8229
- const { width = 0, height = 0, borderRadius } = model.value;
8230
- const center = { x: width / 2, y: height / 2 };
8231
- const shape = props.handleShape;
8232
- const lines = [
8233
- { type: "top", points: [[0, 0], [1, 0]] },
8234
- { type: "right", points: [[1, 0], [1, 1]] },
8235
- { type: "bottom", points: [[0, 1], [1, 1]] },
8236
- { type: "left", points: [[0, 0], [0, 1]] }
8237
- ];
8238
- const points = [
8239
- { type: "top", point: [0.5, 0] },
8240
- { type: "right", point: [1, 0.5] },
8241
- { type: "bottom", point: [0.5, 1] },
8242
- { type: "left", point: [0, 0.5] },
8243
- { type: "top-left", point: [0, 0] },
8244
- { type: "top-right", point: [1, 0] },
8245
- { type: "bottom-left", point: [0, 1] },
8246
- { type: "bottom-right", point: [1, 1] }
8247
- ];
8248
- const lineHandles = lines.map((item) => {
8249
- const [p1, p2] = item.points;
8250
- const minX = Math.min(p1[0], p2[0]) * width;
8251
- const maxX = Math.max(p1[0], p2[0]) * width;
8252
- const minY = Math.min(p1[1], p2[1]) * height;
8253
- const maxY = Math.max(p1[1], p2[1]) * height;
8254
- return {
8255
- type: item.type,
8256
- x: minX - size / 2,
8257
- y: minY - size / 2,
8258
- width: maxX - minX + size,
8259
- height: maxY - minY + size
8260
- };
8261
- });
8262
- const pointHandles = points.map((item) => {
8263
- return {
8264
- type: item.type,
8265
- shape,
8266
- x: item.point[0] * width - size / 2,
8267
- y: item.point[1] * height - size / 2,
8268
- width: size,
8269
- height: size
8270
- };
8271
- });
8272
- const diagonalPointHandles = pointHandles.filter((item) => item.type.split("-").length === 2);
8273
- const rotateHandles = diagonalPointHandles.map((item) => {
8274
- const sign = {
8275
- x: center.x - item.x > 0 ? 1 : -1,
8276
- y: center.y - item.y > 0 ? 1 : -1
8277
- };
8278
- return {
8279
- ...item,
8280
- shape: void 0,
8281
- type: `rotate-${item.type}`,
8282
- x: item.x - sign.x * size,
8283
- y: item.y - sign.y * size
8284
- };
8285
- });
8286
- const minSize = Math.min(width, height);
8287
- const borderRadiusHandles = props.adjustableBorderRadius ? diagonalPointHandles.map((item) => {
8288
- const sign = {
8289
- x: center.x - item.x > 0 ? 1 : -1,
8290
- y: center.y - item.y > 0 ? 1 : -1
8291
- };
8292
- const offset2 = minSize * 0.1;
8293
- return {
8294
- ...item,
8295
- shape: "circle",
8296
- type: `border-radius-${item.type}`,
8297
- x: item.x + sign.x * Math.min(width / 2, offset2 + borderRadius),
8298
- y: item.y + sign.y * Math.min(height / 2, offset2 + borderRadius)
8299
- };
8300
- }) : [];
8301
- let handles;
8302
- if (props.handleStrategy === "point") {
8303
- handles = [
8304
- // move
8305
- ...lineHandles.map((item) => ({ ...item, type: "move" })),
8306
- // resize
8307
- ...pointHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
8308
- // border-radius
8309
- ...borderRadiusHandles,
8310
- // rotate
8311
- ...rotateHandles
8312
- ];
8313
- } else {
8314
- handles = [
8315
- // resize
8316
- ...lineHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
8317
- ...diagonalPointHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
8318
- // border-radius
8319
- ...borderRadiusHandles,
8320
- // rotate
8321
- ...rotateHandles
8322
- ];
8705
+ function drawSelected() {
8706
+ if (!props.selected?.width || !props.selected?.height)
8707
+ return;
8708
+ ctx.fillStyle = "#6165FD20";
8709
+ const offset2 = props.vertical ? props.selected.top : props.selected.left;
8710
+ const length = props.vertical ? props.selected.height : props.selected.width;
8711
+ ctx.fillRect(offset2, 0, length, props.size);
8712
+ }
8713
+ function drawAxis(start2, end2, size, color) {
8714
+ ctx.lineWidth = size;
8715
+ ctx.strokeStyle = color;
8716
+ ctx.beginPath();
8717
+ ctx.moveTo(start2[0], start2[1]);
8718
+ ctx.lineTo(end2[0], end2[1]);
8719
+ ctx.stroke();
8720
+ }
8721
+ function drawTick(tick, len, direction = 1) {
8722
+ const x1 = tick;
8723
+ const y1 = props.size;
8724
+ const x2 = tick;
8725
+ const y2 = props.size - len * direction;
8726
+ ctx.moveTo(x1, y1);
8727
+ ctx.lineTo(x2, y2);
8728
+ }
8729
+ function drawText(content, tick, top, size) {
8730
+ ctx.font = `${size}px sans-serif`;
8731
+ ctx.textAlign = "left";
8732
+ ctx.textBaseline = "bottom";
8733
+ const x2 = tick;
8734
+ const y2 = props.size - top;
8735
+ ctx.save();
8736
+ if (props.vertical) {
8737
+ ctx.translate(0, props.size);
8738
+ ctx.scale(1, -1);
8323
8739
  }
8324
- return handles.filter((handle) => {
8325
- if (props.handles.includes(handle.type)) {
8326
- return !(!props.resizable && handle.type.startsWith("resize") || !props.rotatable && handle.type.startsWith("rotate") || !props.movable && handle.type === "move");
8740
+ ctx.fillText(content, x2, y2);
8741
+ ctx.restore();
8742
+ }
8743
+ const unit = computed(() => {
8744
+ const idealUnit = Math.max(props.unit / props.zoom, 1);
8745
+ const unitFractions = props.unitFractions;
8746
+ const exponent = Math.floor(Math.log10(idealUnit));
8747
+ const fraction = idealUnit / 10 ** exponent;
8748
+ let niceFraction = unitFractions[unitFractions.length - 1];
8749
+ for (const cur of unitFractions) {
8750
+ if (fraction <= cur) {
8751
+ niceFraction = cur;
8752
+ break;
8327
8753
  }
8328
- return false;
8329
- }).map((anchor) => {
8330
- anchor.width = Math.max(anchor.width, 0);
8331
- anchor.height = Math.max(anchor.height, 0);
8332
- return anchor;
8333
- });
8754
+ }
8755
+ return niceFraction * 10 ** exponent;
8334
8756
  });
8335
- const handlesRef = ref();
8336
- const sizeStyle = computed(() => {
8337
- const { width = 0, height = 0 } = model.value;
8338
- return {
8339
- width: props.initialSize && !width ? void 0 : `${width}px`,
8340
- height: props.initialSize && !height ? void 0 : `${height}px`
8341
- };
8757
+ const start = computed(() => {
8758
+ const value = props.position / props.zoom;
8759
+ return Math.floor(value / unit.value) * unit.value;
8342
8760
  });
8343
- const style = computed(() => {
8344
- const { left = 0, top = 0, rotate = 0 } = model.value;
8345
- const radian = rotate * Math.PI / 180;
8346
- const cos = Math.cos(radian);
8347
- const sin = Math.sin(radian);
8348
- return {
8349
- ...sizeStyle.value,
8350
- transform: `matrix(${cos}, ${sin}, ${-sin}, ${cos}, ${left}, ${top})`
8351
- };
8761
+ const end = computed(() => {
8762
+ const len = (props.vertical ? box.value?.height : box.value?.width) ?? 0;
8763
+ const value = len / props.zoom;
8764
+ return start.value + Math.ceil(value / unit.value) * unit.value;
8352
8765
  });
8353
- const tip = computed(() => props.tipFormat?.("size"));
8354
- function start(event, index) {
8355
- if (event && event.button !== void 0 && event.button !== 0) {
8356
- return false;
8357
- }
8358
- event?.preventDefault();
8359
- event?.stopPropagation();
8360
- const { left, top, width, height, rotate, borderRadius } = model.value;
8361
- let aspectRatio = 0;
8362
- if (width && height) {
8363
- aspectRatio = width / height;
8766
+ function numToPx(num) {
8767
+ return Math.round(num * props.zoom - props.position);
8768
+ }
8769
+ function pxToNum(px) {
8770
+ return Math.round((px + props.position) / props.zoom);
8771
+ }
8772
+ function render2() {
8773
+ const cvs = canvas.value;
8774
+ if (!cvs || !offscreenCanvas.width || !offscreenCanvas.height)
8775
+ return;
8776
+ ctx.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
8777
+ ctx.save();
8778
+ ctx.scale(pixelRatio.value, pixelRatio.value);
8779
+ if (props.vertical) {
8780
+ ctx.scale(1, -1);
8781
+ ctx.translate(0, 0);
8782
+ ctx.rotate(-Math.PI / 2);
8364
8783
  }
8365
- const handle = index === void 0 ? { type: "move", x: 0, y: 0, width: 0, height: 0 } : computedHandles.value[index];
8366
- activeHandle.value = handle.type;
8367
- const isMove = handle.type === "move";
8368
- const isRotate = handle.type.startsWith("rotate");
8369
- const isBorderRadius = handle.type.startsWith("border-radius");
8370
- const isHorizontal = handle.type === "resize-left" || handle.type === "resize-right";
8371
- const isHorizontalVertical = handle.type.split("-").length === 2;
8372
- const centerPoint = {
8373
- x: left + width / 2,
8374
- y: top + height / 2
8375
- };
8376
- const startPoint = {
8377
- x: left,
8378
- y: top
8379
- };
8380
- if (!isMove) {
8381
- startPoint.x += handle.x + handle.width / 2;
8382
- startPoint.y += handle.y + handle.height / 2;
8784
+ drawSelected();
8785
+ if (props.axis) {
8786
+ drawAxis(
8787
+ [0, props.size],
8788
+ [props.vertical ? cvs.height : cvs.width, props.size],
8789
+ 2,
8790
+ colors.border
8791
+ );
8383
8792
  }
8384
- const sign = {
8385
- x: startPoint.x - centerPoint.x > 0 ? 1 : -1,
8386
- y: startPoint.y - centerPoint.y > 0 ? 1 : -1
8387
- };
8388
- const rotatedStartPoint = rotatePoint(startPoint, centerPoint, rotate);
8389
- const rotatedSymmetricPoint = {
8390
- x: centerPoint.x * 2 - rotatedStartPoint.x,
8391
- y: centerPoint.y * 2 - rotatedStartPoint.y
8793
+ const drawPrimary = (tick, label) => {
8794
+ drawTick(tick, 10);
8795
+ drawText(label, tick + 2, 4, 8);
8392
8796
  };
8393
- const startAngle = Math.atan2(
8394
- rotatedStartPoint.y - centerPoint.y,
8395
- rotatedStartPoint.x - centerPoint.x
8396
- ) / (Math.PI / 180);
8397
- let startClientPoint = event ? { x: event.clientX, y: event.clientY } : void 0;
8398
- function startTransform() {
8399
- transforming.value = true;
8400
- emit("start", model.value);
8401
- }
8402
- if (!props.threshold && !transforming.value) {
8403
- startTransform();
8404
- }
8405
- function onMove(event2) {
8406
- const updated = {};
8407
- if (!startClientPoint) {
8408
- startClientPoint = { x: event2.clientX, y: event2.clientY };
8409
- }
8410
- const rotatedOffset = {
8411
- x: event2.clientX - startClientPoint.x,
8412
- y: event2.clientY - startClientPoint.y
8413
- };
8414
- if (!transforming.value) {
8415
- if (Math.abs(rotatedOffset.x) < props.threshold && Math.abs(rotatedOffset.y) < props.threshold) {
8416
- return;
8417
- }
8418
- startTransform();
8797
+ const drawSecondary = (tick) => drawTick(tick, 4);
8798
+ let inc = unit.value / 10;
8799
+ inc = (inc > 0 ? 1 : -1) * Math.max(1, Math.abs(inc));
8800
+ ctx.beginPath();
8801
+ ctx.lineWidth = 1;
8802
+ ctx.strokeStyle = colors.text;
8803
+ ctx.fillStyle = colors.text;
8804
+ for (let tick = start.value; tick <= end.value; tick += inc) {
8805
+ if (tick % unit.value === 0) {
8806
+ drawPrimary(numToPx(tick), props.labelFormat(tick));
8419
8807
  }
8420
- const rotatedCurrentPoint = {
8421
- x: rotatedStartPoint.x + rotatedOffset.x,
8422
- y: rotatedStartPoint.y + rotatedOffset.y
8423
- };
8424
- if (isMove) {
8425
- if (props.movable) {
8426
- updated.left = startPoint.x + rotatedOffset.x;
8427
- updated.top = startPoint.y + rotatedOffset.y;
8428
- }
8429
- } else if (isRotate) {
8430
- if (props.rotatable) {
8431
- const endAngle = Math.atan2(
8432
- rotatedCurrentPoint.y - centerPoint.y,
8433
- rotatedCurrentPoint.x - centerPoint.x
8434
- ) / (Math.PI / 180);
8435
- updated.rotate = (rotate + endAngle - startAngle + 360) % 360;
8436
- }
8437
- } else if (isBorderRadius) {
8438
- const offset2 = rotatePoint(rotatedOffset, { x: 0, y: 0 }, -rotate);
8439
- const _offset = Math.abs(offset2.x) < Math.abs(offset2.y) ? -sign.x * offset2.x : -sign.y * offset2.y * aspectRatio;
8440
- updated.borderRadius = Math.min(
8441
- Math.max(0, borderRadius + _offset),
8442
- Math.min(width / 2, height / 2)
8443
- );
8444
- } else if (isHorizontalVertical) {
8445
- const currentPoint = rotatePoint(rotatedCurrentPoint, centerPoint, -rotate);
8446
- const newCurrentPoint = isHorizontal ? { x: currentPoint.x, y: startPoint.y } : { x: startPoint.x, y: currentPoint.y };
8447
- const newRotatedCurrentPoint = rotatePoint(newCurrentPoint, centerPoint, rotate);
8448
- const distance = Math.abs(getDistance(newRotatedCurrentPoint, rotatedSymmetricPoint));
8449
- if (isHorizontal) {
8450
- updated.width = distance;
8451
- if (props.resizeStrategy === "lockAspectRatio" && aspectRatio) {
8452
- updated.height = distance / aspectRatio;
8453
- } else {
8454
- updated.height = height;
8455
- }
8456
- } else {
8457
- updated.height = distance;
8458
- if (props.resizeStrategy === "lockAspectRatio" && aspectRatio) {
8459
- updated.width = distance * aspectRatio;
8460
- } else {
8461
- updated.width = width;
8462
- }
8463
- }
8464
- const newCenterPoint = getMidpoint(newRotatedCurrentPoint, rotatedSymmetricPoint);
8465
- updated.left = newCenterPoint.x - updated.width / 2;
8466
- updated.top = newCenterPoint.y - updated.height / 2;
8467
- } else {
8468
- let newRotatedCurrentPoint;
8469
- if ((props.resizeStrategy === "lockAspectRatio" || props.resizeStrategy === "lockAspectRatioDiagonal") && aspectRatio) {
8470
- const offset2 = rotatePoint(rotatedOffset, { x: 0, y: 0 }, -rotate);
8471
- const _offset = Math.abs(offset2.x) < Math.abs(offset2.y) ? sign.x * offset2.x : sign.y * offset2.y * aspectRatio;
8472
- newRotatedCurrentPoint = rotatePoint(
8473
- {
8474
- x: startPoint.x + sign.x * _offset,
8475
- y: startPoint.y + sign.y * _offset / aspectRatio
8476
- },
8477
- centerPoint,
8478
- rotate
8479
- );
8480
- } else {
8481
- newRotatedCurrentPoint = rotatedCurrentPoint;
8482
- }
8483
- const newCenterPoint = getMidpoint(newRotatedCurrentPoint, rotatedSymmetricPoint);
8484
- const points = [
8485
- rotatePoint(newRotatedCurrentPoint, newCenterPoint, -rotate),
8486
- rotatePoint(rotatedSymmetricPoint, newCenterPoint, -rotate)
8487
- ];
8488
- const [minX, maxX] = points[0].x > points[1].x ? [points[1].x, points[0].x] : [points[0].x, points[1].x];
8489
- const [minY, maxY] = points[0].y > points[1].y ? [points[1].y, points[0].y] : [points[0].y, points[1].y];
8490
- updated.width = maxX - minX;
8491
- updated.height = maxY - minY;
8492
- updated.left = minX;
8493
- updated.top = minY;
8808
+ }
8809
+ ctx.stroke();
8810
+ ctx.beginPath();
8811
+ ctx.lineWidth = 1;
8812
+ ctx.strokeStyle = colors.border;
8813
+ for (let tick = start.value; tick <= end.value; tick += inc) {
8814
+ if (tick % unit.value === 0) ;
8815
+ else if (tick % inc === 0) {
8816
+ drawSecondary(numToPx(tick));
8494
8817
  }
8495
- if ("width" in updated && updated.width <= 0 || "height" in updated && updated.height <= 0) {
8496
- return;
8818
+ }
8819
+ ctx.stroke();
8820
+ ctx.restore();
8821
+ if ("transferToImageBitmap" in offscreenCanvas) {
8822
+ cvs.getContext("bitmaprenderer").transferFromImageBitmap(offscreenCanvas.transferToImageBitmap());
8823
+ } else {
8824
+ const mainCtx = cvs.getContext("2d");
8825
+ if (mainCtx) {
8826
+ mainCtx.clearRect(0, 0, cvs.width, cvs.height);
8827
+ mainCtx.drawImage(offscreenCanvas, 0, 0);
8497
8828
  }
8498
- const oldValue = { ...model.value };
8499
- const newValue = { ...model.value, ...updated };
8500
- model.value = newValue;
8501
- emit("move", newValue, oldValue);
8502
8829
  }
8503
- function onEnd() {
8504
- window.removeEventListener("pointermove", onMove);
8505
- window.removeEventListener("pointerup", onEnd, true);
8506
- transforming.value = false;
8507
- activeHandle.value = void 0;
8508
- emit("end", model.value);
8830
+ }
8831
+ watch(
8832
+ [canvas, () => props.zoom, () => props.position, () => props.selected],
8833
+ () => {
8834
+ render2();
8835
+ },
8836
+ { immediate: true, deep: true }
8837
+ );
8838
+ const resize = useDebounceFn(() => {
8839
+ if (!canvas.value)
8840
+ return;
8841
+ const _box = canvas.value.parentElement.getBoundingClientRect();
8842
+ offscreenCanvas.width = canvas.value.width = _box.width * pixelRatio.value;
8843
+ offscreenCanvas.height = canvas.value.height = _box.height * pixelRatio.value;
8844
+ canvas.value.style.width = `${_box.width}px`;
8845
+ canvas.value.style.height = `${_box.height}px`;
8846
+ box.value = _box;
8847
+ render2();
8848
+ }, 50);
8849
+ onMounted(() => {
8850
+ resize();
8851
+ const dom = canvas.value;
8852
+ if (dom) {
8853
+ const style = window.getComputedStyle(dom);
8854
+ colors.text = style.getPropertyValue("--text-color").trim();
8855
+ colors.border = style.getPropertyValue("--border-color").trim();
8509
8856
  }
8510
- window.addEventListener("pointermove", onMove);
8511
- window.addEventListener("pointerup", onEnd, true);
8512
- return true;
8857
+ });
8858
+ onBeforeUnmount(() => {
8859
+ offscreenCanvas.width = 0;
8860
+ offscreenCanvas.height = 0;
8861
+ });
8862
+ const savedLines = ref([]);
8863
+ const tempLine = ref();
8864
+ const lines = computed(() => {
8865
+ const res = [...savedLines.value];
8866
+ if (typeof tempLine.value === "number")
8867
+ res.unshift(tempLine.value);
8868
+ return res;
8869
+ });
8870
+ function getTick(e) {
8871
+ return pxToNum(
8872
+ props.vertical ? e.clientY - box.value.top : e.clientX - box.value.left
8873
+ );
8513
8874
  }
8514
- const cursorMap = {
8515
- rotate: '<path d="M22.4789 9.45728L25.9935 12.9942L22.4789 16.5283V14.1032C18.126 14.1502 14.6071 17.6737 14.5675 22.0283H17.05L13.513 25.543L9.97889 22.0283H12.5674C12.6071 16.5691 17.0214 12.1503 22.4789 12.1031L22.4789 9.45728Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M21.4789 7.03223L27.4035 12.9945L21.4789 18.9521V15.1868C18.4798 15.6549 16.1113 18.0273 15.649 21.0284H19.475L13.5128 26.953L7.55519 21.0284H11.6189C12.1243 15.8155 16.2679 11.6677 21.4789 11.1559L21.4789 7.03223ZM22.4789 12.1031C17.0214 12.1503 12.6071 16.5691 12.5674 22.0284H9.97889L13.513 25.543L17.05 22.0284H14.5675C14.5705 21.6896 14.5947 21.3558 14.6386 21.0284C15.1157 17.4741 17.9266 14.6592 21.4789 14.1761C21.8063 14.1316 22.1401 14.1069 22.4789 14.1032V16.5284L25.9935 12.9942L22.4789 9.45729L22.4789 12.1031Z" fill="white"/>',
8516
- resizeXy: '<path d="m9 17.9907v.005l5.997 5.996.001-3.999h1.999 2.02v4l5.98-6.001-5.98-5.999.001 4.019-2.021.002h-2l.001-4.022zm1.411.003 3.587-3.588-.001 2.587h3.5 2.521v-2.585l3.565 3.586-3.564 3.585-.001-2.585h-2.521l-3.499-.001-.001 2.586z" fill="white"/><path d="m17.4971 18.9932h2.521v2.586l3.565-3.586-3.565-3.585v2.605h-2.521-3.5v-2.607l-3.586 3.587 3.586 3.586v-2.587z" fill="black"/>',
8517
- resizeBevel: '<path d="m19.7432 17.0869-4.072 4.068 2.829 2.828-8.473-.013-.013-8.47 2.841 2.842 4.075-4.068 1.414-1.415-2.844-2.842h8.486v8.484l-2.83-2.827z" fill="white"/><path d="m18.6826 16.7334-4.427 4.424 1.828 1.828-5.056-.016-.014-5.054 1.842 1.841 4.428-4.422 2.474-2.475-1.844-1.843h5.073v5.071l-1.83-1.828z" fill="black"/>'
8518
- };
8519
- function createCursor(type, angle) {
8520
- const path = cursorMap[type];
8521
- return `<svg height="32" width="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><defs><filter id="shadow" color-interpolation-filters="sRGB"><feDropShadow dx="1" dy="1" stdDeviation="1.2" flood-opacity=".5"/></filter></defs><g fill="none" transform="rotate(${angle} 16 16)" filter="url(%23shadow)">${path}</g></svg>`.replace(/"/g, "'");
8875
+ function onMousedown(e) {
8876
+ const tick = getTick(e);
8877
+ if (props.refline) {
8878
+ savedLines.value.push(tick);
8879
+ }
8522
8880
  }
8523
- function getCursor(type) {
8524
- if (type === "move")
8525
- return "move";
8526
- const create = cursors[type];
8527
- if (!create) {
8528
- return "default";
8881
+ function onMousemove(e, temp = false) {
8882
+ const tick = getTick(e);
8883
+ if (props.refline && temp) {
8884
+ tempLine.value = tick;
8529
8885
  }
8530
- return `url("data:image/svg+xml,${create(model.value.rotate ?? 0)}") 16 16, pointer`;
8886
+ tipText.value = props.labelFormat(tick);
8887
+ tipPos.value = { x: e.clientX, y: e.clientY };
8531
8888
  }
8532
- function rotatePoint(point, origin, angle) {
8533
- const radian = angle * Math.PI / 180;
8534
- const cos = Math.cos(radian);
8535
- const sin = Math.sin(radian);
8536
- return {
8537
- x: (point.x - origin.x) * cos - (point.y - origin.y) * sin + origin.x,
8538
- y: (point.x - origin.x) * sin + (point.y - origin.y) * cos + origin.y
8539
- };
8889
+ function onLeave() {
8890
+ tempLine.value = void 0;
8891
+ tipText.value = void 0;
8540
8892
  }
8541
- function getMidpoint(point1, point2) {
8542
- return {
8543
- x: (point2.x + point1.x) / 2,
8544
- y: (point2.y + point1.y) / 2
8545
- };
8893
+ function onReflineDblclick(index) {
8894
+ savedLines.value.splice(index, 1);
8546
8895
  }
8547
- function getDistance(point1, point2) {
8548
- const dx = point2.x - point1.x;
8549
- const dy = point2.y - point1.y;
8550
- return (dx + dy >= 0 ? 1 : -1) * Math.sqrt(dx * dx + dy * dy);
8896
+ function onReflineMousedown(e, index) {
8897
+ e.stopPropagation();
8898
+ e.preventDefault();
8899
+ const move = (e2) => {
8900
+ savedLines.value[index] = getTick(e2);
8901
+ };
8902
+ const up = () => {
8903
+ window.removeEventListener("mousemove", move);
8904
+ window.removeEventListener("mouseup", up);
8905
+ };
8906
+ window.addEventListener("mousemove", move);
8907
+ window.addEventListener("mouseup", up);
8551
8908
  }
8552
- onMounted(async () => {
8553
- const vm = getCurrentInstance();
8554
- const root = vm?.proxy?.$el;
8555
- if (root && props.initialSize) {
8556
- await nextTick();
8557
- let width;
8558
- let height;
8559
- const style2 = getComputedStyle(root);
8560
- if (style2.width.endsWith("px") && style2.height.endsWith("px")) {
8561
- width = Number(style2.width.replace("px", ""));
8562
- height = Number(style2.height.replace("px", ""));
8563
- } else {
8564
- ({ width, height } = root.getBoundingClientRect());
8909
+ __expose({
8910
+ box
8911
+ });
8912
+ return (_ctx, _cache) => {
8913
+ return openBlock(), createElementBlock(Fragment, null, [
8914
+ withDirectives((openBlock(), createElementBlock("div", mergeProps({
8915
+ class: ["mce-ruler", [
8916
+ `mce-ruler--${props.vertical ? "vertical" : "horizontal"}`
8917
+ ]],
8918
+ style: { "--size": `${props.size}px` }
8919
+ }, unref(attrs), {
8920
+ onMousedown,
8921
+ onMousemove: _cache[0] || (_cache[0] = ($event) => onMousemove($event, true)),
8922
+ onMouseleave: onLeave
8923
+ }), [
8924
+ createElementVNode("canvas", {
8925
+ ref: "canvasTpl",
8926
+ class: "mce-ruler__canvas",
8927
+ width: props.size,
8928
+ height: props.size
8929
+ }, null, 8, _hoisted_1$c)
8930
+ ], 16)), [
8931
+ [unref(vResizeObserver), unref(resize)]
8932
+ ]),
8933
+ (openBlock(true), createElementBlock(Fragment, null, renderList(lines.value, (item, index) => {
8934
+ return openBlock(), createElementBlock("div", {
8935
+ key: index,
8936
+ class: normalizeClass(["mce-ruler-refline", {
8937
+ "mce-ruler-refline--vertical": props.vertical,
8938
+ "mce-ruler-refline--horizontal": !props.vertical,
8939
+ "mce-ruler-refline--temp": item === tempLine.value
8940
+ }]),
8941
+ style: normalizeStyle({
8942
+ [props.vertical ? "height" : "width"]: "0",
8943
+ [props.vertical ? "width" : "height"]: "100%",
8944
+ [props.vertical ? "top" : "left"]: `${numToPx(item)}px`,
8945
+ [props.vertical ? "left" : "top"]: 0
8946
+ }),
8947
+ onDblclick: ($event) => onReflineDblclick(index),
8948
+ onMousedown: ($event) => onReflineMousedown($event, index),
8949
+ onMousemove: () => tipText.value = `${item}`,
8950
+ onMouseleave: onLeave
8951
+ }, null, 46, _hoisted_2$5);
8952
+ }), 128)),
8953
+ createVNode(_sfc_main$k, {
8954
+ "model-value": !!tipText.value,
8955
+ target: tipPos.value,
8956
+ offset: 24
8957
+ }, {
8958
+ default: withCtx(() => [
8959
+ createElementVNode("div", _hoisted_3$5, toDisplayString(tipText.value), 1)
8960
+ ]),
8961
+ _: 1
8962
+ }, 8, ["model-value", "target"])
8963
+ ], 64);
8964
+ };
8965
+ }
8966
+ });
8967
+ const _hoisted_1$b = { class: "mce-rulers" };
8968
+ const _sfc_main$i = /* @__PURE__ */ defineComponent({
8969
+ ...{
8970
+ inheritAttrs: false
8971
+ },
8972
+ __name: "Rulers",
8973
+ setup(__props) {
8974
+ const {
8975
+ camera,
8976
+ selectionAabbInDrawboard
8977
+ } = useEditor();
8978
+ return (_ctx, _cache) => {
8979
+ return openBlock(), createElementBlock("div", _hoisted_1$b, [
8980
+ createVNode(_sfc_main$j, {
8981
+ refline: "",
8982
+ zoom: unref(camera).zoom.x,
8983
+ position: unref(camera).position.x,
8984
+ selected: unref(selectionAabbInDrawboard),
8985
+ axis: "",
8986
+ size: 16
8987
+ }, null, 8, ["zoom", "position", "selected"]),
8988
+ createVNode(_sfc_main$j, {
8989
+ refline: "",
8990
+ zoom: unref(camera).zoom.y,
8991
+ position: unref(camera).position.y,
8992
+ selected: unref(selectionAabbInDrawboard),
8993
+ axis: "",
8994
+ vertical: "",
8995
+ size: 16
8996
+ }, null, 8, ["zoom", "position", "selected"]),
8997
+ _cache[0] || (_cache[0] = createElementVNode("div", { class: "mce-rulers__left-top" }, null, -1))
8998
+ ]);
8999
+ };
9000
+ }
9001
+ });
9002
+ const _hoisted_1$a = {
9003
+ ref: "trackTplRef",
9004
+ class: "mce-scrollbar__track"
9005
+ };
9006
+ const _sfc_main$h = /* @__PURE__ */ defineComponent({
9007
+ __name: "Scrollbar",
9008
+ props: /* @__PURE__ */ mergeModels({
9009
+ length: {},
9010
+ vertical: { type: Boolean },
9011
+ size: {},
9012
+ offset: {}
9013
+ }, {
9014
+ "modelValue": { required: true },
9015
+ "modelModifiers": {}
9016
+ }),
9017
+ emits: /* @__PURE__ */ mergeModels(["scroll"], ["update:modelValue"]),
9018
+ setup(__props, { emit: __emit }) {
9019
+ const props = __props;
9020
+ const emit = __emit;
9021
+ const position = useModel(__props, "modelValue");
9022
+ const track = useTemplateRef("trackTplRef");
9023
+ const thumb = useTemplateRef("thumbTplRef");
9024
+ const trackLength = ref(0);
9025
+ const contentLength = computed(() => {
9026
+ return props.length + trackLength.value + Math.abs(position.value) * 2;
9027
+ });
9028
+ const thumbLength = computed(() => {
9029
+ return Math.max(0.05, Math.min(1, trackLength.value / contentLength.value));
9030
+ });
9031
+ const thumbPosition = computed(() => {
9032
+ return (Math.abs(position.value) + position.value) / (contentLength.value - trackLength.value) * (1 - thumbLength.value);
9033
+ });
9034
+ const resize = useDebounceFn(() => {
9035
+ const box = track.value?.getBoundingClientRect() ?? { width: 0, height: 0 };
9036
+ trackLength.value = props.vertical ? box.height : box.width;
9037
+ }, 50);
9038
+ const lerp = (a, b, t) => a * (1 - t) + b * t;
9039
+ const thumbToTrack = (thumbLength2, thumbPosition2) => lerp(thumbLength2 / 2, 1 - thumbLength2 / 2, thumbPosition2);
9040
+ const start = computed(() => thumbToTrack(thumbLength.value, thumbPosition.value));
9041
+ const end = computed(() => 1 - start.value - thumbLength.value);
9042
+ const thumbTop = computed(() => props.vertical ? `${start.value * 100}%` : "0%");
9043
+ const thumbBottom = computed(() => props.vertical ? `${end.value * 100}%` : "50%");
9044
+ const thumbLeft = computed(() => props.vertical ? "0%" : `${start.value * 100}%`);
9045
+ const thumbRight = computed(() => props.vertical ? "50%" : `${end.value * 100}%`);
9046
+ function update(val) {
9047
+ emit("scroll", val - position.value);
9048
+ position.value = val;
9049
+ }
9050
+ function amount(val) {
9051
+ update(position.value + val);
9052
+ }
9053
+ const isActive = ref(false);
9054
+ watch(track, (track2, oldTrack) => {
9055
+ function onMousedown(event) {
9056
+ if (!thumb.value?.contains(event.target)) {
9057
+ return;
8565
9058
  }
8566
- if (width && height) {
8567
- model.value = { ...model.value, width, height };
8568
- } else if ("ResizeObserver" in globalThis) {
8569
- const observer = new ResizeObserver(([entry]) => {
8570
- if (entry.contentRect.width && entry.contentRect.height) {
8571
- model.value = {
8572
- ...model.value,
8573
- width: entry.contentRect.width,
8574
- height: entry.contentRect.height
8575
- };
8576
- observer.unobserve(root);
8577
- }
8578
- });
8579
- observer.observe(root);
9059
+ isActive.value = true;
9060
+ let last = event;
9061
+ event.stopPropagation();
9062
+ function onMousemove(event2) {
9063
+ const offset2 = {
9064
+ x: last.clientX - event2.clientX,
9065
+ y: last.clientY - event2.clientY
9066
+ };
9067
+ last = event2;
9068
+ amount((props.vertical ? offset2.y : offset2.x) / (trackLength.value * (1 - thumbLength.value)) * contentLength.value * -1);
9069
+ }
9070
+ function onMouseup() {
9071
+ isActive.value = false;
9072
+ window.removeEventListener("mousemove", onMousemove);
9073
+ window.removeEventListener("mouseup", onMouseup);
8580
9074
  }
9075
+ window.addEventListener("mousemove", onMousemove);
9076
+ window.addEventListener("mouseup", onMouseup);
8581
9077
  }
9078
+ oldTrack?.removeEventListener("mousedown", onMousedown);
9079
+ track2?.addEventListener("mousedown", onMousedown);
8582
9080
  });
8583
- __expose({
8584
- start,
8585
- activeHandle,
8586
- transforming
8587
- });
8588
- function Diagonal() {
8589
- const handle = activeHandle.value;
8590
- if (!handle || !handle.startsWith("resize")) {
8591
- return void 0;
8592
- }
8593
- switch (props.resizeStrategy) {
8594
- case "lockAspectRatio":
8595
- break;
8596
- case "lockAspectRatioDiagonal":
8597
- if (handle.split("-").length === 2) {
8598
- return void 0;
8599
- }
8600
- break;
8601
- default:
8602
- return void 0;
8603
- }
8604
- if (handle === "resize-top" || handle === "resize-right" || handle === "resize-top-right" || handle === "resize-bottom-left") {
8605
- return h("line", {
8606
- class: "mce-transformable__diagonal",
8607
- x1: "100%",
8608
- y1: "0",
8609
- x2: "0",
8610
- y2: "100%"
8611
- });
8612
- } else if (handle === "resize-left" || handle === "resize-bottom" || handle === "resize-top-left" || handle === "resize-bottom-right") {
8613
- return h("line", {
8614
- class: "mce-transformable__diagonal",
8615
- x1: "0",
8616
- y1: "0",
8617
- x2: "100%",
8618
- y2: "100%"
8619
- });
8620
- }
8621
- return void 0;
8622
- }
8623
9081
  return (_ctx, _cache) => {
8624
- return openBlock(), createBlock(resolveDynamicComponent(__props.tag), {
8625
- class: normalizeClass(["mce-transformable", [
8626
- transforming.value && "mce-transformable--transforming",
8627
- props.hideUi && "mce-transformable--hide-ui",
8628
- __props.resizeStrategy && `mce-transformable--${__props.resizeStrategy}`,
8629
- activeHandle.value && `mce-transformable--${activeHandle.value}`,
8630
- activeHandle.value === "move" && "mce-transformable--moving",
8631
- activeHandle.value?.startsWith("resize") && "mce-transformable--resizing",
8632
- activeHandle.value?.startsWith("rotate") && "mce-transformable--rotateing",
8633
- props.borderStyle && `mce-transformable--${props.borderStyle}`
8634
- ]]),
8635
- style: normalizeStyle(style.value)
8636
- }, {
8637
- default: withCtx(() => [
8638
- renderSlot(_ctx.$slots, "default", {
8639
- value: unref(modelValue),
8640
- props: {
8641
- onPointerdown: start
8642
- },
8643
- start
8644
- }),
8645
- (openBlock(), createElementBlock("svg", _hoisted_1$a, [
8646
- _cache[0] || (_cache[0] = createElementVNode("rect", {
8647
- width: "100%",
8648
- height: "100%",
8649
- fill: "none",
8650
- class: "mce-transformable__rect"
8651
- }, null, -1)),
8652
- createElementVNode("rect", {
8653
- class: "mce-transformable__rect",
8654
- width: "100%",
8655
- height: "100%",
8656
- fill: "none",
8657
- rx: model.value.borderRadius,
8658
- ry: model.value.borderRadius
8659
- }, null, 8, _hoisted_2$5),
8660
- createVNode(Diagonal),
8661
- createElementVNode("g", null, [
8662
- (openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value, (handle, index) => {
8663
- return openBlock(), createElementBlock(Fragment, { key: index }, [
8664
- handle.shape ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
8665
- handle.shape === "rect" ? (openBlock(), createElementBlock("rect", {
8666
- key: 0,
8667
- x: handle.x,
8668
- y: handle.y,
8669
- width: handle.width,
8670
- height: handle.height,
8671
- "aria-label": handle.type,
8672
- class: "mce-transformable__handle"
8673
- }, null, 8, _hoisted_3$5)) : (openBlock(), createElementBlock("circle", {
8674
- key: 1,
8675
- cx: handle.x + handle.width / 2,
8676
- cy: handle.y + handle.width / 2,
8677
- r: handle.width / 2,
8678
- "aria-label": handle.type,
8679
- class: "mce-transformable__handle"
8680
- }, null, 8, _hoisted_4$3))
8681
- ], 64)) : createCommentVNode("", true)
8682
- ], 64);
8683
- }), 128))
8684
- ]),
8685
- createElementVNode("g", _hoisted_5$2, [
8686
- (openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value, (handle, index) => {
8687
- return openBlock(), createElementBlock("rect", {
8688
- key: index,
8689
- ref_for: true,
8690
- ref_key: "handlesRef",
8691
- ref: handlesRef,
8692
- x: handle.x,
8693
- y: handle.y,
8694
- width: handle.width,
8695
- height: handle.height,
8696
- "aria-label": handle.type,
8697
- class: "mce-transformable__handle-rect",
8698
- cursor: transforming.value ? "auto" : getCursor(handle.type),
8699
- onPointerdown: (event) => start(event, index)
8700
- }, null, 40, _hoisted_6$2);
8701
- }), 128))
8702
- ]),
8703
- createElementVNode("g", _hoisted_7$2, [
8704
- renderSlot(_ctx.$slots, "svg", { box: model.value })
8705
- ])
8706
- ])),
8707
- tip.value ? (openBlock(), createElementBlock("div", _hoisted_8$1, toDisplayString(tip.value), 1)) : createCommentVNode("", true)
8708
- ]),
8709
- _: 3
8710
- }, 8, ["class", "style"]);
9082
+ return withDirectives((openBlock(), createElementBlock("div", {
9083
+ class: normalizeClass(["mce-scrollbar", {
9084
+ "mce-scrollbar--vertical": props.vertical,
9085
+ "mce-scrollbar--horizontal": !props.vertical
9086
+ }]),
9087
+ style: normalizeStyle({
9088
+ [props.vertical ? "height" : "width"]: `calc(100% - ${props.size + props.offset}px)`,
9089
+ [props.vertical ? "width" : "height"]: `${props.size}px`,
9090
+ [props.vertical ? "top" : "left"]: `${props.offset}px`
9091
+ })
9092
+ }, [
9093
+ createElementVNode("div", _hoisted_1$a, [
9094
+ createElementVNode("div", {
9095
+ ref: "thumbTplRef",
9096
+ class: normalizeClass(["mce-scrollbar__thumb", {
9097
+ "mce-scrollbar__thumb--active": isActive.value
9098
+ }]),
9099
+ style: normalizeStyle({
9100
+ top: thumbTop.value,
9101
+ bottom: thumbBottom.value,
9102
+ left: thumbLeft.value,
9103
+ right: thumbRight.value
9104
+ })
9105
+ }, null, 6)
9106
+ ], 512)
9107
+ ], 6)), [
9108
+ [unref(vResizeObserver), unref(resize)]
9109
+ ]);
8711
9110
  };
8712
9111
  }
8713
9112
  });
8714
9113
  const _sfc_main$g = /* @__PURE__ */ defineComponent({
9114
+ ...{
9115
+ inheritAttrs: false
9116
+ },
9117
+ __name: "Scrollbars",
9118
+ props: {
9119
+ infinite: { type: Boolean, default: true },
9120
+ offset: { default: 0 },
9121
+ size: { default: 8 }
9122
+ },
9123
+ setup(__props) {
9124
+ const props = __props;
9125
+ const {
9126
+ camera,
9127
+ viewAabb
9128
+ } = useEditor();
9129
+ return (_ctx, _cache) => {
9130
+ return openBlock(), createElementBlock(Fragment, null, [
9131
+ createVNode(_sfc_main$h, mergeProps(props, {
9132
+ modelValue: unref(camera).position.y,
9133
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(camera).position.y = $event),
9134
+ vertical: "",
9135
+ length: unref(viewAabb).height * unref(camera).zoom.y
9136
+ }), null, 16, ["modelValue", "length"]),
9137
+ createVNode(_sfc_main$h, mergeProps(props, {
9138
+ modelValue: unref(camera).position.x,
9139
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => unref(camera).position.x = $event),
9140
+ length: unref(viewAabb).width * unref(camera).zoom.x
9141
+ }), null, 16, ["modelValue", "length"])
9142
+ ], 64);
9143
+ };
9144
+ }
9145
+ });
9146
+ const _sfc_main$f = /* @__PURE__ */ defineComponent({
8715
9147
  ...{
8716
9148
  inheritAttrs: false
8717
9149
  },
@@ -8723,12 +9155,14 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8723
9155
  setup(__props, { expose: __expose }) {
8724
9156
  const props = __props;
8725
9157
  const {
9158
+ isElement,
8726
9159
  state,
8727
9160
  resizeElement,
8728
9161
  elementSelection,
9162
+ selectionObb,
9163
+ selectionObbInDrawboard,
8729
9164
  camera,
8730
9165
  obbToFit,
8731
- getObbInDrawboard,
8732
9166
  getObb,
8733
9167
  registerCommand,
8734
9168
  unregisterCommand,
@@ -8749,8 +9183,8 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8749
9183
  }
8750
9184
  const obbs = [];
8751
9185
  elementSelection.value[0]?.findAncestor((ancestor) => {
8752
- if (ancestor instanceof Element2D) {
8753
- obbs.push(getObbInDrawboard(ancestor));
9186
+ if (isElement(ancestor)) {
9187
+ obbs.push(getObb(ancestor, "drawboard"));
8754
9188
  }
8755
9189
  return false;
8756
9190
  });
@@ -8762,15 +9196,15 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8762
9196
  }
8763
9197
  return elementSelection.value.map((el) => {
8764
9198
  return {
8765
- name: el.name,
8766
- box: getObbInDrawboard(el)
9199
+ element: el,
9200
+ box: getObb(el, "drawboard")
8767
9201
  };
8768
9202
  });
8769
9203
  });
8770
9204
  const _selectionTransform = computed(() => {
8771
9205
  const zoom = camera.value.zoom;
8772
9206
  return {
8773
- ...getObbInDrawboard(elementSelection.value),
9207
+ ...selectionObbInDrawboard.value,
8774
9208
  borderRadius: (elementSelection.value[0]?.style.borderRadius ?? 0) * zoom.x
8775
9209
  };
8776
9210
  });
@@ -8811,7 +9245,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8811
9245
  Object.assign(style, newStyle);
8812
9246
  element.updateGlobalTransform();
8813
9247
  element.findAncestor((ancestor) => {
8814
- if (ancestor instanceof Element2D && !isFrame(ancestor)) {
9248
+ if (isElement(ancestor) && !isFrame(ancestor)) {
8815
9249
  obbToFit(ancestor);
8816
9250
  }
8817
9251
  return false;
@@ -8839,7 +9273,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8839
9273
  return elementSelection.value.length === 1 && !isLock(element) && element.foreground.isValid();
8840
9274
  });
8841
9275
  function tipFormat() {
8842
- const obb = elementSelection.value.length === 1 ? elementSelection.value[0].style : getObb(elementSelection.value);
9276
+ const obb = elementSelection.value.length === 1 ? elementSelection.value[0].style : selectionObb.value;
8843
9277
  return `${Number(obb.width.toFixed(2))} × ${Number(obb.height.toFixed(2))}`;
8844
9278
  }
8845
9279
  __expose({
@@ -8850,7 +9284,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8850
9284
  (openBlock(true), createElementBlock(Fragment, null, renderList(parentObbs.value, (obb, index) => {
8851
9285
  return openBlock(), createElementBlock("div", {
8852
9286
  key: index,
8853
- class: "mce-parent-element-obb",
9287
+ class: "mce-selector__parent-element",
8854
9288
  style: normalizeStyle({
8855
9289
  borderColor: "currentColor",
8856
9290
  ...unref(boundingBoxToStyle)(obb)
@@ -8859,7 +9293,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8859
9293
  }), 128)),
8860
9294
  unref(state) === "selecting" ? (openBlock(), createElementBlock("div", {
8861
9295
  key: 0,
8862
- class: "mce-selected-area",
9296
+ class: "mce-selector__selected-area",
8863
9297
  style: normalizeStyle({
8864
9298
  borderColor: "currentcolor",
8865
9299
  ...unref(boundingBoxToStyle)(props.selectedArea)
@@ -8868,14 +9302,15 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8868
9302
  (openBlock(true), createElementBlock(Fragment, null, renderList(selectionObbs.value, (item, index) => {
8869
9303
  return openBlock(), createElementBlock("div", {
8870
9304
  key: index,
8871
- class: "mce-element-obb",
9305
+ class: "mce-selector__element",
8872
9306
  style: normalizeStyle({
8873
9307
  borderColor: "currentcolor",
9308
+ borderRadius: `${(item.element.style.borderRadius ?? 0) * unref(camera).zoom.x}px`,
8874
9309
  ...unref(boundingBoxToStyle)(item.box)
8875
9310
  })
8876
9311
  }, null, 4);
8877
9312
  }), 128)),
8878
- selectionTransform.value.width && selectionTransform.value.height ? (openBlock(), createBlock(_sfc_main$h, {
9313
+ selectionTransform.value.width && selectionTransform.value.height ? (openBlock(), createBlock(_sfc_main$v, {
8879
9314
  key: 1,
8880
9315
  ref: "transformableRef",
8881
9316
  modelValue: selectionTransform.value,
@@ -8886,7 +9321,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8886
9321
  "adjustable-border-radius": adjustableBorderRadius.value,
8887
9322
  "resize-strategy": props.resizeStrategy,
8888
9323
  "handle-shape": unref(config).handleShape,
8889
- class: "mce-selection-obb",
9324
+ class: "mce-selector__transform",
8890
9325
  "border-style": unref(elementSelection).length > 1 ? "dashed" : "solid",
8891
9326
  "tip-format": tipFormat,
8892
9327
  onMove: _cache[1] || (_cache[1] = () => !unref(state) && (state.value = "transforming")),
@@ -8902,7 +9337,8 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8902
9337
  ]), 1032, ["modelValue", "movable", "resizable", "rotatable", "adjustable-border-radius", "resize-strategy", "handle-shape", "border-style"])) : createCommentVNode("", true),
8903
9338
  selectionTransform.value.width && selectionTransform.value.height && _ctx.$slots.default ? (openBlock(), createElementBlock("div", {
8904
9339
  key: 2,
8905
- style: normalizeStyle([{ "position": "absolute" }, unref(boundingBoxToStyle)(selectionTransform.value)])
9340
+ class: "mce-selector__slot",
9341
+ style: normalizeStyle(unref(boundingBoxToStyle)(selectionTransform.value))
8906
9342
  }, [
8907
9343
  renderSlot(_ctx.$slots, "default", { box: selectionTransform.value })
8908
9344
  ], 4)) : createCommentVNode("", true)
@@ -8910,15 +9346,6 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8910
9346
  };
8911
9347
  }
8912
9348
  });
8913
- const _sfc_main$f = /* @__PURE__ */ defineComponent({
8914
- __name: "Setup",
8915
- setup(__props) {
8916
- useEditor().setup();
8917
- return (_ctx, _cache) => {
8918
- return null;
8919
- };
8920
- }
8921
- });
8922
9349
  const _hoisted_1$9 = {
8923
9350
  key: 0,
8924
9351
  class: "mce-float-panel__title"
@@ -8944,7 +9371,7 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
8944
9371
  ...props.defaultTransform
8945
9372
  });
8946
9373
  return (_ctx, _cache) => {
8947
- return openBlock(), createBlock(_sfc_main$h, {
9374
+ return openBlock(), createBlock(_sfc_main$v, {
8948
9375
  modelValue: transform.value,
8949
9376
  "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => transform.value = $event),
8950
9377
  class: "mce-float-panel",
@@ -8956,11 +9383,11 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
8956
9383
  createElementVNode("div", mergeProps({ class: "mce-float-panel__card" }, slotProps), [
8957
9384
  __props.title ? (openBlock(), createElementBlock("div", _hoisted_1$9, [
8958
9385
  createElementVNode("div", null, toDisplayString(__props.title), 1),
8959
- createVNode(_sfc_main$p, {
9386
+ createVNode(_sfc_main$o, {
8960
9387
  onClick: _cache[0] || (_cache[0] = ($event) => isActive.value = false)
8961
9388
  }, {
8962
9389
  default: withCtx(() => [
8963
- createVNode(_sfc_main$z, { icon: "$close" })
9390
+ createVNode(_sfc_main$B, { icon: "$close" })
8964
9391
  ]),
8965
9392
  _: 1
8966
9393
  })
@@ -9110,13 +9537,6 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
9110
9537
  };
9111
9538
  }
9112
9539
  });
9113
- const _export_sfc = (sfc, props) => {
9114
- const target = sfc.__vccOpts || sfc;
9115
- for (const [key, val] of props) {
9116
- target[key] = val;
9117
- }
9118
- return target;
9119
- };
9120
9540
  const ProgressIndicator = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-c4234331"]]);
9121
9541
  const _hoisted_1$6 = { class: "mce-statusbar" };
9122
9542
  const _hoisted_2$3 = { class: "mce-statusbar__main" };
@@ -9164,7 +9584,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
9164
9584
  ])
9165
9585
  ], 64)) : unref(state) === "transforming" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
9166
9586
  createElementVNode("div", _hoisted_8, [
9167
- createVNode(_sfc_main$z, { icon: "$mouseRightClick" })
9587
+ createVNode(_sfc_main$B, { icon: "$mouseRightClick" })
9168
9588
  ]),
9169
9589
  _cache[2] || (_cache[2] = createElementVNode("span", null, " / ", -1)),
9170
9590
  createElementVNode("div", _hoisted_9, [
@@ -9178,7 +9598,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
9178
9598
  ])
9179
9599
  ], 64)) : unref(state) ? (openBlock(), createElementBlock("span", _hoisted_13, toDisplayString(unref(t)(unref(state))), 1)) : (openBlock(), createElementBlock(Fragment, { key: 3 }, [
9180
9600
  createElementVNode("div", _hoisted_14, [
9181
- createVNode(_sfc_main$z, { icon: "$mouseLeftClick" }),
9601
+ createVNode(_sfc_main$B, { icon: "$mouseLeftClick" }),
9182
9602
  createElementVNode("span", null, toDisplayString(unref(t)("selectObject")), 1)
9183
9603
  ]),
9184
9604
  _cache[4] || (_cache[4] = createElementVNode("span", null, " + ", -1)),
@@ -9188,7 +9608,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
9188
9608
  ]),
9189
9609
  _cache[5] || (_cache[5] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
9190
9610
  createElementVNode("div", _hoisted_17, [
9191
- createVNode(_sfc_main$z, { icon: "$mouseLeftClick" }),
9611
+ createVNode(_sfc_main$B, { icon: "$mouseLeftClick" }),
9192
9612
  createElementVNode("span", null, toDisplayString(unref(t)("selectArea")), 1)
9193
9613
  ]),
9194
9614
  _cache[6] || (_cache[6] = createElementVNode("span", null, " + ", -1)),
@@ -9198,7 +9618,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
9198
9618
  ]),
9199
9619
  _cache[7] || (_cache[7] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
9200
9620
  createElementVNode("div", _hoisted_20, [
9201
- createVNode(_sfc_main$z, { icon: "$mouseLeftClick" }),
9621
+ createVNode(_sfc_main$B, { icon: "$mouseLeftClick" }),
9202
9622
  createElementVNode("span", null, toDisplayString(unref(t)("dragSelected")), 1)
9203
9623
  ])
9204
9624
  ], 64))
@@ -9275,6 +9695,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
9275
9695
  await nextTick();
9276
9696
  if (editor.pointerDown(e)) {
9277
9697
  editor.selectAll();
9698
+ editor._updateSelectionByDom();
9278
9699
  return true;
9279
9700
  }
9280
9701
  return false;
@@ -9521,7 +9942,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
9521
9942
  class: "mce-timeline__play",
9522
9943
  onClick: toggle
9523
9944
  }, [
9524
- createVNode(_sfc_main$z, {
9945
+ createVNode(_sfc_main$B, {
9525
9946
  icon: paused.value ? "$play" : "$pause"
9526
9947
  }, null, 8, ["icon"])
9527
9948
  ])
@@ -9550,7 +9971,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
9550
9971
  }, [
9551
9972
  createElementVNode("div", _hoisted_5, [
9552
9973
  createElementVNode("div", _hoisted_6, [
9553
- createVNode(_sfc_main$l, {
9974
+ createVNode(_sfc_main$j, {
9554
9975
  ref: "rulerTpl",
9555
9976
  zoom: 1 / unref(msPerPx) * fps.value,
9556
9977
  unit: 100,
@@ -9624,12 +10045,16 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9624
10045
  const props = __props;
9625
10046
  let editor;
9626
10047
  if (props.editor) {
9627
- editor = provideEditor(props.editor);
10048
+ editor = props.editor;
10049
+ provide(Editor.injectionKey, editor);
9628
10050
  } else {
9629
10051
  editor = useEditor();
9630
10052
  }
10053
+ editor.setup();
9631
10054
  provide(IconsSymbol, createIcons());
9632
10055
  const {
10056
+ isElement,
10057
+ showMadeWith,
9633
10058
  config,
9634
10059
  drawboardDom,
9635
10060
  renderEngine,
@@ -9638,12 +10063,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9638
10063
  hoverElement,
9639
10064
  state,
9640
10065
  setCursor,
9641
- isFrame,
9642
10066
  selectArea,
9643
10067
  exec,
9644
10068
  isLock,
10069
+ selectionAabbInDrawboard,
9645
10070
  elementSelection,
9646
- getAabbInDrawboard,
9647
10071
  drawboardAabb,
9648
10072
  drawboardPointer,
9649
10073
  screenCenterOffset,
@@ -9689,7 +10113,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9689
10113
  let hovered;
9690
10114
  if (elementSelection.value.length > 1 && isPointInsideAabb(
9691
10115
  { x: event.clientX, y: event.clientY },
9692
- getAabbInDrawboard(elementSelection.value)
10116
+ selectionAabbInDrawboard.value
9693
10117
  )) {
9694
10118
  cursor = "move";
9695
10119
  } else {
@@ -9699,7 +10123,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9699
10123
  event,
9700
10124
  editor
9701
10125
  });
9702
- if (result && !(result instanceof Element2D)) {
10126
+ if (result && !isElement(result)) {
9703
10127
  hovered = result.element;
9704
10128
  cursor = result.cursor;
9705
10129
  } else {
@@ -9724,7 +10148,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9724
10148
  const inSelection = isPointInsideAabb({
9725
10149
  x: start.x + -drawboardAabb.value.left,
9726
10150
  y: start.y + -drawboardAabb.value.top
9727
- }, getAabbInDrawboard(elementSelection.value));
10151
+ }, selectionAabbInDrawboard.value);
9728
10152
  if (downEvent.button === 2) {
9729
10153
  if (!inSelection) {
9730
10154
  const result = props.activeStrategy({
@@ -9732,7 +10156,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9732
10156
  event: downEvent,
9733
10157
  editor
9734
10158
  });
9735
- if (result && !(result instanceof Element2D)) {
10159
+ if (result && !isElement(result)) {
9736
10160
  selected = result.element ? [result.element] : [];
9737
10161
  } else {
9738
10162
  selected = result ? [result] : [];
@@ -9747,7 +10171,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9747
10171
  event,
9748
10172
  editor
9749
10173
  });
9750
- if (result && !(result instanceof Element2D)) {
10174
+ if (result && !isElement(result)) {
9751
10175
  selected = result.element ? [result.element] : [];
9752
10176
  } else {
9753
10177
  selected = result ? [result] : [];
@@ -9774,7 +10198,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9774
10198
  editor
9775
10199
  });
9776
10200
  let _element;
9777
- if (result && !(result instanceof Element2D)) {
10201
+ if (result && !isElement(result)) {
9778
10202
  _element = result.element;
9779
10203
  ctxState = result.state;
9780
10204
  } else {
@@ -9800,7 +10224,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9800
10224
  exec("startTransform", downEvent);
9801
10225
  }
9802
10226
  } else {
9803
- if (element && !isFrame(element)) {
10227
+ if (element) {
9804
10228
  if (canStartDrag()) {
9805
10229
  dragging = true;
9806
10230
  onDrag(moveEvent);
@@ -9816,7 +10240,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9816
10240
  function onMove(moveEvent) {
9817
10241
  current = { x: moveEvent.clientX, y: moveEvent.clientY };
9818
10242
  if (!inSelection) {
9819
- if (!element || isFrame(element)) {
10243
+ if (!element) {
9820
10244
  onSelectArea();
9821
10245
  }
9822
10246
  }
@@ -9888,10 +10312,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9888
10312
  }
9889
10313
  }
9890
10314
  }
10315
+ const slotProps = {
10316
+ editor
10317
+ };
9891
10318
  return (_ctx, _cache) => {
9892
10319
  return openBlock(), createBlock(_sfc_main$d, { class: "mce-editor" }, {
9893
10320
  default: withCtx(() => [
9894
- createVNode(_sfc_main$f),
9895
10321
  createVNode(_sfc_main$b, null, {
9896
10322
  default: withCtx(() => [
9897
10323
  createElementVNode("div", {
@@ -9906,38 +10332,52 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9906
10332
  }, [
9907
10333
  createElementVNode("canvas", _hoisted_2, null, 512),
9908
10334
  createVNode(_sfc_main$8, { ref: "textEditorTpl" }, null, 512),
9909
- createVNode(_sfc_main$A),
9910
- createVNode(_sfc_main$q),
9911
- createVNode(_sfc_main$s),
9912
- createVNode(_sfc_main$v),
9913
- createVNode(_sfc_main$g, {
10335
+ createVNode(_sfc_main$C),
10336
+ createVNode(_sfc_main$p),
10337
+ createVNode(_sfc_main$r),
10338
+ createVNode(_sfc_main$x),
10339
+ unref(config).ruler ? (openBlock(), createBlock(_sfc_main$i, { key: 0 })) : createCommentVNode("", true),
10340
+ unref(config).scrollbar ? (openBlock(), createBlock(_sfc_main$g, { key: 1 })) : createCommentVNode("", true),
10341
+ unref(showMadeWith) ? (openBlock(), createBlock(MadeWith, { key: 2 })) : createCommentVNode("", true),
10342
+ createVNode(_sfc_main$f, {
9914
10343
  ref: "selectorTpl",
9915
10344
  "selected-area": selectedArea.value,
9916
10345
  "resize-strategy": resizeStrategy.value
9917
10346
  }, {
9918
10347
  transformable: withCtx(({ box }) => [
9919
- renderSlot(_ctx.$slots, "transformer", { box })
10348
+ renderSlot(_ctx.$slots, "transformer", mergeProps({ box }, slotProps))
9920
10349
  ]),
9921
10350
  default: withCtx(({ box }) => [
9922
- renderSlot(_ctx.$slots, "selector", { box })
10351
+ createVNode(_sfc_main$t),
10352
+ renderSlot(_ctx.$slots, "selector", mergeProps({ box }, slotProps))
9923
10353
  ]),
9924
10354
  _: 3
9925
10355
  }, 8, ["selected-area", "resize-strategy"]),
9926
- unref(config).scrollbar ? (openBlock(), createBlock(_sfc_main$i, { key: 0 })) : createCommentVNode("", true),
9927
- _ctx.$slots.floatbar ? (openBlock(), createBlock(_sfc_main$u, {
9928
- key: 1,
10356
+ _ctx.$slots.floatbar || _ctx.$slots["floatbar-top"] ? (openBlock(), createBlock(_sfc_main$w, {
10357
+ key: 3,
10358
+ location: "top-start",
9929
10359
  target: unref(state) === "typing" ? textEditor.value?.textEditor : selector.value?.transformable?.$el
9930
10360
  }, {
9931
10361
  default: withCtx(() => [
9932
- renderSlot(_ctx.$slots, "floatbar")
10362
+ renderSlot(_ctx.$slots, "floatbar", normalizeProps(guardReactiveProps(slotProps))),
10363
+ renderSlot(_ctx.$slots, "floatbar-top", normalizeProps(guardReactiveProps(slotProps)))
9933
10364
  ]),
9934
10365
  _: 3
9935
10366
  }, 8, ["target"])) : createCommentVNode("", true),
9936
- createVNode(_sfc_main$w),
9937
- createVNode(_sfc_main$r),
9938
- unref(config).ruler ? (openBlock(), createBlock(_sfc_main$k, { key: 2 })) : createCommentVNode("", true),
10367
+ _ctx.$slots["floatbar-bottom"] ? (openBlock(), createBlock(_sfc_main$w, {
10368
+ key: 4,
10369
+ location: "bottom-start",
10370
+ target: selector.value?.transformable?.$el
10371
+ }, {
10372
+ default: withCtx(() => [
10373
+ renderSlot(_ctx.$slots, "floatbar-bottom", normalizeProps(guardReactiveProps(slotProps)))
10374
+ ]),
10375
+ _: 3
10376
+ }, 8, ["target"])) : createCommentVNode("", true),
10377
+ createVNode(_sfc_main$y),
10378
+ createVNode(_sfc_main$q),
9939
10379
  unref(config).layers ? (openBlock(), createBlock(_sfc_main$e, {
9940
- key: 3,
10380
+ key: 5,
9941
10381
  modelValue: unref(config).layers,
9942
10382
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(config).layers = $event),
9943
10383
  title: unref(t)("layers"),
@@ -9949,17 +10389,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9949
10389
  }
9950
10390
  }, {
9951
10391
  default: withCtx(() => [
9952
- createVNode(_sfc_main$n)
10392
+ createVNode(_sfc_main$m)
9953
10393
  ]),
9954
10394
  _: 1
9955
10395
  }, 8, ["modelValue", "title", "default-transform"])) : createCommentVNode("", true),
9956
10396
  createVNode(Toolbelt),
9957
- renderSlot(_ctx.$slots, "drawboard")
10397
+ renderSlot(_ctx.$slots, "drawboard", normalizeProps(guardReactiveProps(slotProps)))
9958
10398
  ], 40, _hoisted_1)
9959
10399
  ]),
9960
10400
  _: 3
9961
10401
  }),
9962
- renderSlot(_ctx.$slots, "default"),
10402
+ renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps))),
9963
10403
  createVNode(_sfc_main$c, {
9964
10404
  modelValue: unref(config).statusbar,
9965
10405
  "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => unref(config).statusbar = $event),
@@ -10016,7 +10456,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
10016
10456
  updateLocation
10017
10457
  });
10018
10458
  return (_ctx, _cache) => {
10019
- return openBlock(), createBlock(_sfc_main$y, {
10459
+ return openBlock(), createBlock(_sfc_main$A, {
10020
10460
  ref: "overlayTpl",
10021
10461
  modelValue: isActive.value,
10022
10462
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isActive.value = $event),
@@ -10040,10 +10480,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
10040
10480
  }
10041
10481
  });
10042
10482
  export {
10483
+ _sfc_main$u as Cropper,
10043
10484
  _sfc_main as Dialog,
10044
10485
  Doc,
10045
10486
  Editor,
10046
- _sfc_main$n as EditorLayers,
10487
+ _sfc_main$m as EditorLayers,
10047
10488
  _sfc_main$1 as EditorLayout,
10048
10489
  _sfc_main$c as EditorLayoutItem,
10049
10490
  Toolbelt as EditorToolbelt,
@@ -10056,12 +10497,12 @@ export {
10056
10497
  MceMenuSymbol,
10057
10498
  MceOverlaySymbol,
10058
10499
  MceSvgIcon,
10059
- _sfc_main$x as Menu,
10500
+ _sfc_main$z as Menu,
10060
10501
  Model,
10061
- _sfc_main$l as Ruler,
10502
+ _sfc_main$j as Ruler,
10062
10503
  SUPPORTS_CLIPBOARD,
10063
- _sfc_main$j as Scrollbar,
10064
- _sfc_main$h as Transformable,
10504
+ _sfc_main$h as Scrollbar,
10505
+ _sfc_main$v as Transformable,
10065
10506
  USER_AGENT,
10066
10507
  boundingBoxToStyle,
10067
10508
  consoleError,
@@ -10101,7 +10542,6 @@ export {
10101
10542
  mixins,
10102
10543
  plugins,
10103
10544
  propsFactory,
10104
- provideEditor,
10105
10545
  provideOverlay,
10106
10546
  refElement,
10107
10547
  templateRef,