mce 0.13.4 → 0.13.6

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, 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, 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, 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";
@@ -1054,8 +1054,8 @@ const _0_helper = defineMixin((editor) => {
1054
1054
  function isElement(value) {
1055
1055
  return value instanceof Element2D;
1056
1056
  }
1057
- function isFrame(node) {
1058
- return isElement(node) && node.meta.inEditorIs === "Frame";
1057
+ function isFrame(value) {
1058
+ return isElement(value) && value.meta.inEditorIs === "Frame";
1059
1059
  }
1060
1060
  function isVisible(node) {
1061
1061
  return isElement(node) && node.style.visibility === "visible";
@@ -1432,11 +1432,11 @@ function getImageSizeFromUrl(url, opts = {}) {
1432
1432
  if (timer)
1433
1433
  clearTimeout(timer);
1434
1434
  const w = this.naturalWidth;
1435
- const h = this.naturalHeight;
1436
- if (!w || !h) {
1435
+ const h2 = this.naturalHeight;
1436
+ if (!w || !h2) {
1437
1437
  reject(new Error("failed to read natural size"));
1438
1438
  } else {
1439
- resolve({ width: w, height: h });
1439
+ resolve({ width: w, height: h2 });
1440
1440
  }
1441
1441
  };
1442
1442
  img.onerror = function() {
@@ -2258,12 +2258,14 @@ const _3_view = defineMixin((editor) => {
2258
2258
  });
2259
2259
  const _4_0_text = defineMixin((editor) => {
2260
2260
  const {
2261
- config
2261
+ config,
2262
+ elementSelection,
2263
+ textSelection
2262
2264
  } = editor;
2263
- function textFontSizeToFit(element, scale) {
2264
- function _handle(element2) {
2265
+ function textFontSizeToFit(element2, scale) {
2266
+ function _handle(element3) {
2265
2267
  if (!scale) {
2266
- const chars = element2.text.base.characters;
2268
+ const chars = element3.text.base.characters;
2267
2269
  let pos = 0;
2268
2270
  let char;
2269
2271
  chars.forEach((_char) => {
@@ -2284,7 +2286,7 @@ const _4_0_text = defineMixin((editor) => {
2284
2286
  }).join("");
2285
2287
  const { boundingBox } = measureText({
2286
2288
  style: {
2287
- ...element2.style.toJSON(),
2289
+ ...element3.style.toJSON(),
2288
2290
  width: "auto"
2289
2291
  },
2290
2292
  content: [
@@ -2295,8 +2297,8 @@ const _4_0_text = defineMixin((editor) => {
2295
2297
  }
2296
2298
  ]
2297
2299
  });
2298
- const fontSize = (element2.style.fontSize || 12) / 2;
2299
- scale = (element2.style.width ?? 0) / (boundingBox.width + fontSize);
2300
+ const fontSize = (element3.style.fontSize || 12) / 2;
2301
+ scale = (element3.style.width ?? 0) / (boundingBox.width + fontSize);
2300
2302
  }
2301
2303
  function _scaleStyle(style) {
2302
2304
  if (style.fontSize)
@@ -2304,38 +2306,38 @@ const _4_0_text = defineMixin((editor) => {
2304
2306
  if (style.letterSpacing)
2305
2307
  style.letterSpacing = style.letterSpacing * scale;
2306
2308
  }
2307
- _scaleStyle(element2.style);
2308
- if (element2.text?.isValid?.() && Array.isArray(element2.text?.content)) {
2309
- element2.text.content.forEach((p) => {
2309
+ _scaleStyle(element3.style);
2310
+ if (element3.text?.isValid?.() && Array.isArray(element3.text?.content)) {
2311
+ element3.text.content.forEach((p) => {
2310
2312
  _scaleStyle(p);
2311
2313
  p.fragments.forEach((f) => {
2312
2314
  _scaleStyle(f);
2313
2315
  });
2314
2316
  });
2315
2317
  }
2316
- element2.requestRedraw();
2318
+ element3.requestRedraw();
2317
2319
  }
2318
- _handle(element);
2319
- element.findOne((descendant) => {
2320
+ _handle(element2);
2321
+ element2.findOne((descendant) => {
2320
2322
  if (descendant instanceof Element2D) {
2321
2323
  _handle(descendant);
2322
2324
  }
2323
2325
  return false;
2324
2326
  });
2325
2327
  }
2326
- function textToFit(element, typography) {
2328
+ function textToFit(element2, typography) {
2327
2329
  const strategy = typography ?? config.value.typographyStrategy;
2328
2330
  if (strategy === "fixedWidthHeight") {
2329
2331
  return;
2330
2332
  } else if (strategy === "autoFontSize") {
2331
- textFontSizeToFit(element);
2333
+ textFontSizeToFit(element2);
2332
2334
  return;
2333
2335
  }
2334
- function _handle(element2) {
2335
- if (!element2.text?.isValid?.() || typeof element2.text?.content !== "object") {
2336
+ function _handle(element3) {
2337
+ if (!element3.text?.isValid?.() || typeof element3.text?.content !== "object") {
2336
2338
  return;
2337
2339
  }
2338
- const style = element2.style.toJSON();
2340
+ const style = element3.style.toJSON();
2339
2341
  switch (strategy) {
2340
2342
  case "autoWidth":
2341
2343
  style.width = "auto";
@@ -2346,25 +2348,205 @@ const _4_0_text = defineMixin((editor) => {
2346
2348
  }
2347
2349
  const { boundingBox } = measureText({
2348
2350
  style,
2349
- content: element2.text.content
2351
+ content: element3.text.content
2350
2352
  });
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();
2353
+ if (element3.style.width !== boundingBox.width || element3.style.height !== boundingBox.height) {
2354
+ element3.style.width = boundingBox.width;
2355
+ element3.style.height = boundingBox.height;
2356
+ element3.requestRedraw();
2355
2357
  }
2356
2358
  }
2357
- _handle(element);
2358
- element.findOne((descendant) => {
2359
+ _handle(element2);
2360
+ element2.findOne((descendant) => {
2359
2361
  if (descendant instanceof Element2D) {
2360
2362
  _handle(descendant);
2361
2363
  }
2362
2364
  return false;
2363
2365
  });
2364
2366
  }
2367
+ const element = computed(() => elementSelection.value[0]);
2368
+ const hasSelectionRange = computed(() => {
2369
+ return (textSelection.value?.length ?? 0) > 1 && textSelection.value[0] !== textSelection.value[1];
2370
+ });
2371
+ function handleSelection([start, end], cb) {
2372
+ let flag = true;
2373
+ element.value?.text?.content.forEach((p, pIndex, pItems) => {
2374
+ if (!flag)
2375
+ return;
2376
+ p.fragments.forEach((f, fIndex, fItems) => {
2377
+ if (!flag)
2378
+ return;
2379
+ const { content, ...fStyle } = f;
2380
+ Array.from(normalizeCRLF(content)).forEach((c, cIndex, cItems) => {
2381
+ flag = cb({
2382
+ 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)),
2383
+ p,
2384
+ pIndex,
2385
+ pLength: pItems.length,
2386
+ f,
2387
+ fIndex,
2388
+ fStyle,
2389
+ fLength: fItems.length,
2390
+ c,
2391
+ cLength: cItems.length,
2392
+ cIndex
2393
+ });
2394
+ });
2395
+ });
2396
+ });
2397
+ }
2398
+ function getTextStyle(key) {
2399
+ if (!element.value) {
2400
+ return void 0;
2401
+ }
2402
+ let value = element.value.style[key];
2403
+ const content = element.value.text.content;
2404
+ if (hasSelectionRange.value) {
2405
+ const selection = textSelection.value;
2406
+ if (selection && selection[0] && selection[1]) {
2407
+ handleSelection(selection, ({ selected, fStyle }) => {
2408
+ if (selected && fStyle[key]) {
2409
+ value = fStyle[key];
2410
+ return false;
2411
+ }
2412
+ return true;
2413
+ });
2414
+ }
2415
+ } else {
2416
+ switch (key) {
2417
+ case "fontSize":
2418
+ return content?.reduce((prev, p) => {
2419
+ return p.fragments.reduce((prev2, f) => {
2420
+ return ~~Math.max(prev2, f[key] ?? 0);
2421
+ }, prev);
2422
+ }, value) ?? value;
2423
+ default:
2424
+ if (content.length === 1 && content[0].fragments.length === 1 && content[0].fragments[0][key]) {
2425
+ return content[0].fragments[0][key];
2426
+ }
2427
+ }
2428
+ }
2429
+ return value;
2430
+ }
2431
+ function setTextStyle(key, value) {
2432
+ if (!element.value) {
2433
+ return;
2434
+ }
2435
+ let isAllSelected = false;
2436
+ if (hasSelectionRange.value) {
2437
+ const selection = textSelection.value;
2438
+ if (selection && selection[0] && selection[1]) {
2439
+ if (selection[0].isFirst && selection[1].isLast && selection[1].isLastSelected) {
2440
+ isAllSelected = true;
2441
+ } else {
2442
+ const newContent = [];
2443
+ let newParagraph = { fragments: [] };
2444
+ let newFragment;
2445
+ handleSelection(selection, ({ selected, fIndex, fStyle, fLength, c, cIndex, cLength }) => {
2446
+ if (fIndex === 0 && cIndex === 0) {
2447
+ newParagraph = { fragments: [] };
2448
+ newFragment = void 0;
2449
+ }
2450
+ const style = { ...fStyle };
2451
+ if (selected) {
2452
+ style[key] = value;
2453
+ }
2454
+ if (newFragment) {
2455
+ const { content: _, ..._style } = newFragment;
2456
+ if (isEqualObject(style, _style)) {
2457
+ newFragment.content += c;
2458
+ } else {
2459
+ newParagraph.fragments.push(newFragment);
2460
+ newFragment = { ...style, content: c };
2461
+ }
2462
+ } else {
2463
+ newFragment = { ...style, content: c };
2464
+ }
2465
+ if (fIndex === fLength - 1 && cIndex === cLength - 1) {
2466
+ if (newFragment) {
2467
+ newParagraph.fragments.push(newFragment);
2468
+ }
2469
+ if (newParagraph.fragments.length) {
2470
+ newContent.push(newParagraph);
2471
+ newParagraph = { fragments: [] };
2472
+ }
2473
+ }
2474
+ return true;
2475
+ });
2476
+ if (newContent.length) {
2477
+ element.value.text.content = newContent;
2478
+ }
2479
+ }
2480
+ }
2481
+ } else {
2482
+ isAllSelected = true;
2483
+ }
2484
+ if (isAllSelected) {
2485
+ const el = element.value;
2486
+ switch (key) {
2487
+ case "fill":
2488
+ case "outline":
2489
+ el.text[key] = value;
2490
+ break;
2491
+ default:
2492
+ el.style[key] = value;
2493
+ break;
2494
+ }
2495
+ const content = element.value.text.content;
2496
+ content.forEach((p) => {
2497
+ delete p[key];
2498
+ p.fragments.forEach((f) => {
2499
+ delete f[key];
2500
+ });
2501
+ });
2502
+ el.text.content = content;
2503
+ }
2504
+ element.value.requestRedraw();
2505
+ textToFit(element.value);
2506
+ }
2507
+ function getTextFill() {
2508
+ if (!element.value) {
2509
+ return void 0;
2510
+ }
2511
+ let fill;
2512
+ if (hasSelectionRange.value) {
2513
+ fill = getTextStyle("fill");
2514
+ if (!fill) {
2515
+ const color = getTextStyle("color");
2516
+ fill = { color };
2517
+ }
2518
+ }
2519
+ fill = fill ?? element.value.text.fill ?? { color: element.value.style.color };
2520
+ return fill;
2521
+ }
2522
+ function setTextFill(value) {
2523
+ if (!element.value) {
2524
+ return;
2525
+ }
2526
+ if (hasSelectionRange.value && value?.color) {
2527
+ setTextStyle("fill", value);
2528
+ } else {
2529
+ element.value.text.fill = value;
2530
+ if (value?.color) {
2531
+ element.value.style.color = value.color;
2532
+ }
2533
+ element.value.text.content.forEach((p) => {
2534
+ delete p.fill;
2535
+ delete p.color;
2536
+ p.fragments.forEach((f) => {
2537
+ delete f.fill;
2538
+ delete f.color;
2539
+ });
2540
+ });
2541
+ }
2542
+ }
2365
2543
  Object.assign(editor, {
2366
2544
  textFontSizeToFit,
2367
- textToFit
2545
+ textToFit,
2546
+ setTextStyle,
2547
+ getTextStyle,
2548
+ getTextFill,
2549
+ setTextFill
2368
2550
  });
2369
2551
  return () => {
2370
2552
  TextEditor.register();
@@ -5896,6 +6078,7 @@ const plugins = [
5896
6078
  class Editor extends Observable {
5897
6079
  static injectionKey = Symbol.for("EditorKey");
5898
6080
  debug = ref(false);
6081
+ showMadeWith = ref(false);
5899
6082
  onEmit;
5900
6083
  plugins = /* @__PURE__ */ new Map();
5901
6084
  _setups = [];
@@ -5922,10 +6105,12 @@ class Editor extends Observable {
5922
6105
  _setupOptions(options) {
5923
6106
  const {
5924
6107
  debug = false,
6108
+ showMadeWith = false,
5925
6109
  plugins: plugins$1 = [],
5926
6110
  configCacheInLocal
5927
6111
  } = options;
5928
6112
  this.debug.value = debug;
6113
+ this.showMadeWith.value = showMadeWith;
5929
6114
  this.config = configCacheInLocal ? useLocalStorage("config", () => ({})) : ref({});
5930
6115
  this._setups = [];
5931
6116
  this._useMixins(
@@ -6214,6 +6399,7 @@ function useOverlay() {
6214
6399
  const makeMceStrategyProps = propsFactory({
6215
6400
  resizeStrategy: Function,
6216
6401
  activeStrategy: Function,
6402
+ doubleclickStrategy: Function,
6217
6403
  hoverStrategy: Function
6218
6404
  }, "makeMceStrategyProps");
6219
6405
  const defaultResizeStrategy = (element) => {
@@ -6223,40 +6409,57 @@ const defaultResizeStrategy = (element) => {
6223
6409
  return void 0;
6224
6410
  };
6225
6411
  const defaultActiveStrategy = (context) => {
6226
- const { element, oldElement, isExcluded } = context;
6227
- if (element && !isExcluded(element)) {
6228
- if (element.equal(oldElement)) {
6229
- if (element.text.isValid()) {
6230
- return {
6231
- element,
6232
- state: "typing"
6233
- };
6234
- }
6412
+ const { element, editor } = context;
6413
+ if (!element) {
6414
+ return void 0;
6415
+ }
6416
+ const { isRoot, isFrame, isElement, elementSelection } = editor;
6417
+ const activeElement = elementSelection.value[0];
6418
+ const cb = (node) => {
6419
+ 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))) {
6420
+ return true;
6235
6421
  }
6422
+ return false;
6423
+ };
6424
+ if (cb(element)) {
6236
6425
  return element;
6237
6426
  }
6427
+ return element.findAncestor(cb);
6428
+ };
6429
+ const defaultDoubleclickStrategy = (context) => {
6430
+ const { editor } = context;
6431
+ const { elementSelection } = editor;
6432
+ const element = elementSelection.value[0];
6433
+ if (element) {
6434
+ return element.foreground.isValid() ? void 0 : "typing";
6435
+ }
6238
6436
  return void 0;
6239
6437
  };
6240
6438
  const defaultHoverStrategy = (context) => {
6241
- const { element, isExcluded, oldElement } = context;
6242
- if (element && !isExcluded(element)) {
6243
- if (element.equal(oldElement)) {
6244
- return {
6245
- element,
6246
- cursor: "move"
6247
- };
6439
+ const { element, editor } = context;
6440
+ if (!element) {
6441
+ return void 0;
6442
+ }
6443
+ const { isRoot, isFrame, isElement, elementSelection } = editor;
6444
+ const activeElement = elementSelection.value[0];
6445
+ const cb = (node) => {
6446
+ 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))) {
6447
+ return true;
6248
6448
  }
6449
+ return false;
6450
+ };
6451
+ if (cb(element)) {
6249
6452
  return element;
6250
6453
  }
6251
- return void 0;
6454
+ return element.findAncestor(cb);
6252
6455
  };
6253
- const _hoisted_1$l = { class: "mce-auxiliary" };
6254
- const _sfc_main$A = /* @__PURE__ */ defineComponent({
6456
+ const _hoisted_1$n = { class: "mce-auxiliary" };
6457
+ const _sfc_main$D = /* @__PURE__ */ defineComponent({
6255
6458
  __name: "Auxiliary",
6256
6459
  setup(__props) {
6257
6460
  const { auxiliaryLines } = useEditor();
6258
6461
  return (_ctx, _cache) => {
6259
- return openBlock(), createElementBlock("div", _hoisted_1$l, [
6462
+ return openBlock(), createElementBlock("div", _hoisted_1$n, [
6260
6463
  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(auxiliaryLines), (item, key) => {
6261
6464
  return openBlock(), createElementBlock("div", {
6262
6465
  key,
@@ -6610,7 +6813,7 @@ function createLayout(props) {
6610
6813
  };
6611
6814
  }
6612
6815
  const MceMenuSymbol = Symbol.for("MceMenuSymbol");
6613
- const _sfc_main$z = /* @__PURE__ */ defineComponent({
6816
+ const _sfc_main$C = /* @__PURE__ */ defineComponent({
6614
6817
  __name: "Icon",
6615
6818
  props: {
6616
6819
  disabled: Boolean,
@@ -6635,7 +6838,7 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
6635
6838
  };
6636
6839
  }
6637
6840
  });
6638
- const _sfc_main$y = /* @__PURE__ */ defineComponent({
6841
+ const _sfc_main$B = /* @__PURE__ */ defineComponent({
6639
6842
  ...{
6640
6843
  inheritAttrs: false
6641
6844
  },
@@ -6748,7 +6951,7 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
6748
6951
  };
6749
6952
  }
6750
6953
  });
6751
- const _hoisted_1$k = ["onMouseenter"];
6954
+ const _hoisted_1$m = ["onMouseenter"];
6752
6955
  const _hoisted_2$a = ["onClick"];
6753
6956
  const _hoisted_3$7 = {
6754
6957
  key: 0,
@@ -6759,7 +6962,7 @@ const _hoisted_5$3 = {
6759
6962
  key: 1,
6760
6963
  class: "mce-list-item__append"
6761
6964
  };
6762
- const _sfc_main$x = /* @__PURE__ */ defineComponent({
6965
+ const _sfc_main$A = /* @__PURE__ */ defineComponent({
6763
6966
  ...{
6764
6967
  name: "MceMenu"
6765
6968
  },
@@ -6838,7 +7041,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6838
7041
  });
6839
7042
  return (_ctx, _cache) => {
6840
7043
  const _component_MceMenu = resolveComponent("MceMenu");
6841
- return openBlock(), createBlock(_sfc_main$y, {
7044
+ return openBlock(), createBlock(_sfc_main$B, {
6842
7045
  ref: "overlayTpl",
6843
7046
  modelValue: isActive.value,
6844
7047
  "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => isActive.value = $event),
@@ -6882,7 +7085,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6882
7085
  onClick: (e) => onClickItem(item, index, e)
6883
7086
  }, [
6884
7087
  hasPrepend.value ? (openBlock(), createElementBlock("div", _hoisted_3$7, [
6885
- item.checked ? (openBlock(), createBlock(_sfc_main$z, {
7088
+ item.checked ? (openBlock(), createBlock(_sfc_main$C, {
6886
7089
  key: 0,
6887
7090
  icon: "$check"
6888
7091
  })) : createCommentVNode("", true)
@@ -6893,10 +7096,10 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6893
7096
  ])
6894
7097
  ]),
6895
7098
  item.children?.length ? (openBlock(), createElementBlock("div", _hoisted_5$3, [
6896
- createVNode(_sfc_main$z, { icon: "$arrowRight" })
7099
+ createVNode(_sfc_main$C, { icon: "$arrowRight" })
6897
7100
  ])) : createCommentVNode("", true)
6898
7101
  ], 10, _hoisted_2$a)
6899
- ], 40, _hoisted_1$k))
7102
+ ], 40, _hoisted_1$m))
6900
7103
  ], 64);
6901
7104
  }), 128)),
6902
7105
  opened.value > -1 && __props.items?.[opened.value]?.children?.length ? (openBlock(), createBlock(_component_MceMenu, {
@@ -6926,12 +7129,12 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
6926
7129
  };
6927
7130
  }
6928
7131
  });
6929
- const _hoisted_1$j = { class: "mce-context-menu__title" };
7132
+ const _hoisted_1$l = { class: "mce-context-menu__title" };
6930
7133
  const _hoisted_2$9 = {
6931
7134
  key: 0,
6932
7135
  class: "mce-context-menu__kbd"
6933
7136
  };
6934
- const _sfc_main$w = /* @__PURE__ */ defineComponent({
7137
+ const _sfc_main$z = /* @__PURE__ */ defineComponent({
6935
7138
  __name: "ContextMenu",
6936
7139
  props: {
6937
7140
  "modelValue": { type: Boolean },
@@ -6989,7 +7192,7 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
6989
7192
  updateLocation
6990
7193
  });
6991
7194
  return (_ctx, _cache) => {
6992
- return openBlock(), createBlock(_sfc_main$x, {
7195
+ return openBlock(), createBlock(_sfc_main$A, {
6993
7196
  ref: "menuTplRef",
6994
7197
  modelValue: model.value,
6995
7198
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
@@ -7004,7 +7207,7 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
7004
7207
  "onClick:item": onClickItem
7005
7208
  }, {
7006
7209
  title: withCtx(({ item }) => [
7007
- createElementVNode("span", _hoisted_1$j, toDisplayString(unref(t)(item.key)), 1),
7210
+ createElementVNode("span", _hoisted_1$l, toDisplayString(unref(t)(item.key)), 1),
7008
7211
  unref(hotkeys).has(item.key) ? (openBlock(), createElementBlock("span", _hoisted_2$9, toDisplayString(unref(getKbd)(item.key)), 1)) : createCommentVNode("", true)
7009
7212
  ]),
7010
7213
  _: 1
@@ -7012,11 +7215,11 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
7012
7215
  };
7013
7216
  }
7014
7217
  });
7015
- const _hoisted_1$i = {
7218
+ const _hoisted_1$k = {
7016
7219
  key: 0,
7017
7220
  class: "mce-drawing__content"
7018
7221
  };
7019
- const _sfc_main$v = /* @__PURE__ */ defineComponent({
7222
+ const _sfc_main$y = /* @__PURE__ */ defineComponent({
7020
7223
  __name: "Drawing",
7021
7224
  setup(__props) {
7022
7225
  const {
@@ -7046,16 +7249,15 @@ const _sfc_main$v = /* @__PURE__ */ defineComponent({
7046
7249
  }),
7047
7250
  onMousedown
7048
7251
  }, [
7049
- unref(stateContext)?.content ? (openBlock(), createElementBlock("div", _hoisted_1$i, toDisplayString(unref(t)(unref(stateContext).content)), 1)) : createCommentVNode("", true)
7252
+ unref(stateContext)?.content ? (openBlock(), createElementBlock("div", _hoisted_1$k, toDisplayString(unref(t)(unref(stateContext).content)), 1)) : createCommentVNode("", true)
7050
7253
  ], 36)) : createCommentVNode("", true);
7051
7254
  };
7052
7255
  }
7053
7256
  });
7054
- const _sfc_main$u = /* @__PURE__ */ defineComponent({
7257
+ const _sfc_main$x = /* @__PURE__ */ defineComponent({
7055
7258
  __name: "Floatbar",
7056
7259
  props: {
7057
7260
  ...makeMceOverlayProps({
7058
- location: "top-start",
7059
7261
  middlewares: ["offset", "shift"],
7060
7262
  offset: 8
7061
7263
  })
@@ -7078,7 +7280,7 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
7078
7280
  updateLocation
7079
7281
  });
7080
7282
  return (_ctx, _cache) => {
7081
- return openBlock(), createBlock(_sfc_main$y, {
7283
+ return openBlock(), createBlock(_sfc_main$B, {
7082
7284
  ref: "overlayTpl",
7083
7285
  class: "mce-floatbar",
7084
7286
  location: props.location,
@@ -7096,1581 +7298,1815 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
7096
7298
  };
7097
7299
  }
7098
7300
  });
7099
- const _sfc_main$t = /* @__PURE__ */ defineComponent({
7100
- __name: "Frame",
7301
+ const _hoisted_1$j = { class: "mce-transformable__svg" };
7302
+ const _hoisted_2$8 = ["rx", "ry"];
7303
+ const _hoisted_3$6 = ["x", "y", "width", "height", "aria-label"];
7304
+ const _hoisted_4$3 = ["cx", "cy", "r", "aria-label"];
7305
+ const _hoisted_5$2 = { "pointer-events": "all" };
7306
+ const _hoisted_6$2 = ["x", "y", "width", "height", "aria-label", "cursor", "onPointerdown"];
7307
+ const _hoisted_7$2 = {
7308
+ "pointer-events": "all",
7309
+ class: "mce-transformable__svg-slot"
7310
+ };
7311
+ const _hoisted_8$1 = {
7312
+ key: 0,
7313
+ class: "mce-transformable__tip"
7314
+ };
7315
+ const _sfc_main$w = /* @__PURE__ */ defineComponent({
7316
+ __name: "Transformable",
7101
7317
  props: {
7102
- "modelValue": { required: true },
7103
- "modelModifiers": {}
7318
+ tag: { default: "div" },
7319
+ modelValue: {},
7320
+ movable: { type: Boolean, default: true },
7321
+ rotatable: { type: Boolean, default: true },
7322
+ resizable: { type: Boolean, default: true },
7323
+ adjustableBorderRadius: { type: Boolean, default: false },
7324
+ threshold: { default: 0 },
7325
+ resizeStrategy: {},
7326
+ handleStrategy: {},
7327
+ handleShape: { default: "rect" },
7328
+ hideUi: { type: Boolean },
7329
+ handles: { default: () => [
7330
+ "move",
7331
+ // resize
7332
+ "resize-left",
7333
+ "resize-top",
7334
+ "resize-right",
7335
+ "resize-bottom",
7336
+ "resize-top-left",
7337
+ "resize-top-right",
7338
+ "resize-bottom-right",
7339
+ "resize-bottom-left",
7340
+ // border-radius
7341
+ "border-radius-top-left",
7342
+ "border-radius-top-right",
7343
+ "border-radius-bottom-left",
7344
+ "border-radius-bottom-right",
7345
+ // rotate
7346
+ "rotate-top-left",
7347
+ "rotate-top-right",
7348
+ "rotate-bottom-left",
7349
+ "rotate-bottom-right"
7350
+ ] },
7351
+ initialSize: { type: Boolean },
7352
+ borderStyle: {},
7353
+ tipFormat: {}
7104
7354
  },
7105
- emits: ["update:modelValue"],
7106
- setup(__props) {
7107
- const frame = useModel(__props, "modelValue");
7108
- const input = useTemplateRef("inputTpl");
7109
- const {
7110
- getObbInDrawboard,
7111
- hoverElement,
7112
- selection,
7113
- state,
7114
- config,
7115
- exec
7116
- } = useEditor();
7117
- const editing = ref(false);
7118
- async function onDblclick() {
7119
- editing.value = true;
7120
- await nextTick();
7121
- if (input.value) {
7122
- input.value.focus();
7123
- input.value.select();
7124
- }
7125
- }
7126
- async function onPointerdown(ev) {
7127
- if (!editing.value) {
7128
- selection.value = [frame.value];
7129
- await nextTick();
7130
- exec("startTransform", ev);
7131
- }
7132
- }
7133
- return (_ctx, _cache) => {
7134
- return withDirectives((openBlock(), createElementBlock("div", {
7135
- style: normalizeStyle(unref(boundingBoxToStyle)(unref(getObbInDrawboard)(frame.value))),
7136
- class: normalizeClass(["mce-frame", [
7137
- unref(config).frameOutline && "mce-frame--outline"
7138
- ]])
7139
- }, [
7140
- withDirectives(createElementVNode("div", {
7141
- class: "mce-frame__name",
7142
- onDblclick,
7143
- onPointerdown,
7144
- onPointerenter: _cache[2] || (_cache[2] = ($event) => !unref(state) && (hoverElement.value = frame.value)),
7145
- onPointerleave: _cache[3] || (_cache[3] = ($event) => !unref(state) && (hoverElement.value = void 0))
7146
- }, [
7147
- createElementVNode("div", null, toDisplayString(frame.value.name), 1),
7148
- withDirectives(createElementVNode("input", {
7149
- ref: "inputTpl",
7150
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => frame.value.name = $event),
7151
- onBlur: _cache[1] || (_cache[1] = ($event) => editing.value = false)
7152
- }, null, 544), [
7153
- [vShow, editing.value],
7154
- [vModelText, frame.value.name]
7155
- ])
7156
- ], 544), [
7157
- [vShow, unref(config).viewMode === "edgeless"]
7158
- ])
7159
- ], 6)), [
7160
- [vShow, frame.value.visible]
7161
- ]);
7162
- };
7163
- }
7164
- });
7165
- const _sfc_main$s = /* @__PURE__ */ defineComponent({
7166
- __name: "Frames",
7167
- setup(__props) {
7168
- const {
7169
- frames
7170
- } = useEditor();
7171
- return (_ctx, _cache) => {
7172
- return openBlock(true), createElementBlock(Fragment, null, renderList(unref(frames), (frame, key) => {
7173
- return openBlock(), createBlock(_sfc_main$t, {
7174
- key,
7175
- "model-value": frame
7176
- }, null, 8, ["model-value"]);
7177
- }), 128);
7355
+ emits: ["update:modelValue", "start", "move", "end"],
7356
+ setup(__props, { expose: __expose, emit: __emit }) {
7357
+ const props = __props;
7358
+ const emit = __emit;
7359
+ const cursors = {
7360
+ "rotate-top-left": (angle) => createCursor("rotate", 360 + angle),
7361
+ "rotate-top-right": (angle) => createCursor("rotate", 90 + angle),
7362
+ "rotate-bottom-left": (angle) => createCursor("rotate", 270 + angle),
7363
+ "rotate-bottom-right": (angle) => createCursor("rotate", 180 + angle),
7364
+ "resize-left": (angle) => createCursor("resizeXy", 180 + angle),
7365
+ "resize-top": (angle) => createCursor("resizeXy", 90 + angle),
7366
+ "resize-right": (angle) => createCursor("resizeXy", 180 + angle),
7367
+ "resize-bottom": (angle) => createCursor("resizeXy", 90 + angle),
7368
+ "resize-top-left": (angle) => createCursor("resizeBevel", 90 + angle),
7369
+ "resize-top-right": (angle) => createCursor("resizeBevel", 180 + angle),
7370
+ "resize-bottom-right": (angle) => createCursor("resizeBevel", 90 + angle),
7371
+ "resize-bottom-left": (angle) => createCursor("resizeBevel", 180 + angle)
7178
7372
  };
7179
- }
7180
- });
7181
- const _sfc_main$r = /* @__PURE__ */ defineComponent({
7182
- __name: "GoBackSelectedArea",
7183
- setup(__props) {
7184
- const {
7185
- selectionAabb,
7186
- drawboardAabb,
7187
- aabbToDrawboardAabb,
7188
- t,
7189
- exec
7190
- } = useEditor();
7191
- const isActive = computed(() => {
7192
- return selectionAabb.value.width && selectionAabb.value.height && !isOverlappingAabb(
7193
- drawboardAabb.value,
7194
- aabbToDrawboardAabb(selectionAabb.value)
7195
- );
7196
- });
7197
- return (_ctx, _cache) => {
7198
- return isActive.value ? (openBlock(), createElementBlock("div", {
7199
- key: 0,
7200
- class: "mce-back-selected-aera",
7201
- onClick: _cache[0] || (_cache[0] = withModifiers(($event) => unref(exec)("scrollToSelection", { behavior: "smooth" }), ["prevent"]))
7202
- }, [
7203
- createVNode(_sfc_main$z, { icon: "$gps" }),
7204
- createElementVNode("span", null, toDisplayString(unref(t)("goBackSelectedArea")), 1)
7205
- ])) : createCommentVNode("", true);
7373
+ const modelValue = useModel(props, "modelValue");
7374
+ const model = computed({
7375
+ get: () => {
7376
+ let { left = 0, top = 0, width = 0, height = 0, rotate = 0, borderRadius = 0 } = modelValue.value ?? {};
7377
+ if (Number.isNaN(Number(width)))
7378
+ width = 0;
7379
+ if (Number.isNaN(Number(height)))
7380
+ height = 0;
7381
+ return { left, top, width, height, rotate, borderRadius };
7382
+ },
7383
+ set: (val) => modelValue.value = val
7384
+ });
7385
+ const transforming = ref(false);
7386
+ const activeHandle = ref();
7387
+ const computedHandles = computed(() => {
7388
+ const size = 8;
7389
+ const { width = 0, height = 0, borderRadius } = model.value;
7390
+ const center = { x: width / 2, y: height / 2 };
7391
+ const shape = props.handleShape;
7392
+ const lines = [
7393
+ { type: "top", points: [[0, 0], [1, 0]] },
7394
+ { type: "right", points: [[1, 0], [1, 1]] },
7395
+ { type: "bottom", points: [[0, 1], [1, 1]] },
7396
+ { type: "left", points: [[0, 0], [0, 1]] }
7397
+ ];
7398
+ const points = [
7399
+ { type: "top", point: [0.5, 0] },
7400
+ { type: "right", point: [1, 0.5] },
7401
+ { type: "bottom", point: [0.5, 1] },
7402
+ { type: "left", point: [0, 0.5] },
7403
+ { type: "top-left", point: [0, 0] },
7404
+ { type: "top-right", point: [1, 0] },
7405
+ { type: "bottom-left", point: [0, 1] },
7406
+ { type: "bottom-right", point: [1, 1] }
7407
+ ];
7408
+ const lineHandles = lines.map((item) => {
7409
+ const [p1, p2] = item.points;
7410
+ const minX = Math.min(p1[0], p2[0]) * width;
7411
+ const maxX = Math.max(p1[0], p2[0]) * width;
7412
+ const minY = Math.min(p1[1], p2[1]) * height;
7413
+ const maxY = Math.max(p1[1], p2[1]) * height;
7414
+ return {
7415
+ type: item.type,
7416
+ x: minX - size / 2,
7417
+ y: minY - size / 2,
7418
+ width: maxX - minX + size,
7419
+ height: maxY - minY + size
7420
+ };
7421
+ });
7422
+ const pointHandles = points.map((item) => {
7423
+ return {
7424
+ type: item.type,
7425
+ shape,
7426
+ x: item.point[0] * width - size / 2,
7427
+ y: item.point[1] * height - size / 2,
7428
+ width: size,
7429
+ height: size
7430
+ };
7431
+ });
7432
+ const diagonalPointHandles = pointHandles.filter((item) => item.type.split("-").length === 2);
7433
+ const rotateHandles = diagonalPointHandles.map((item) => {
7434
+ const sign = {
7435
+ x: center.x - item.x > 0 ? 1 : -1,
7436
+ y: center.y - item.y > 0 ? 1 : -1
7437
+ };
7438
+ return {
7439
+ ...item,
7440
+ shape: void 0,
7441
+ type: `rotate-${item.type}`,
7442
+ x: item.x - sign.x * size,
7443
+ y: item.y - sign.y * size
7444
+ };
7445
+ });
7446
+ const minSize = Math.min(width, height);
7447
+ const borderRadiusHandles = props.adjustableBorderRadius ? diagonalPointHandles.map((item) => {
7448
+ const sign = {
7449
+ x: center.x - item.x > 0 ? 1 : -1,
7450
+ y: center.y - item.y > 0 ? 1 : -1
7451
+ };
7452
+ const offset2 = minSize * 0.1;
7453
+ return {
7454
+ ...item,
7455
+ shape: "circle",
7456
+ type: `border-radius-${item.type}`,
7457
+ x: item.x + sign.x * Math.min(width / 2, offset2 + borderRadius),
7458
+ y: item.y + sign.y * Math.min(height / 2, offset2 + borderRadius)
7459
+ };
7460
+ }) : [];
7461
+ let handles;
7462
+ if (props.handleStrategy === "point") {
7463
+ handles = [
7464
+ // move
7465
+ ...lineHandles.map((item) => ({ ...item, type: "move" })),
7466
+ // resize
7467
+ ...pointHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
7468
+ // border-radius
7469
+ ...borderRadiusHandles,
7470
+ // rotate
7471
+ ...rotateHandles
7472
+ ];
7473
+ } else {
7474
+ handles = [
7475
+ // resize
7476
+ ...lineHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
7477
+ ...diagonalPointHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
7478
+ // border-radius
7479
+ ...borderRadiusHandles,
7480
+ // rotate
7481
+ ...rotateHandles
7482
+ ];
7483
+ }
7484
+ return handles.filter((handle) => {
7485
+ if (props.handles.includes(handle.type)) {
7486
+ return !(!props.resizable && handle.type.startsWith("resize") || !props.rotatable && handle.type.startsWith("rotate") || !props.movable && handle.type === "move");
7487
+ }
7488
+ return false;
7489
+ }).map((anchor) => {
7490
+ anchor.width = Math.max(anchor.width, 0);
7491
+ anchor.height = Math.max(anchor.height, 0);
7492
+ return anchor;
7493
+ });
7494
+ });
7495
+ const handlesRef = ref();
7496
+ const sizeStyle = computed(() => {
7497
+ const { width = 0, height = 0 } = model.value;
7498
+ return {
7499
+ width: props.initialSize && !width ? void 0 : `${width}px`,
7500
+ height: props.initialSize && !height ? void 0 : `${height}px`
7501
+ };
7502
+ });
7503
+ const style = computed(() => {
7504
+ const { left = 0, top = 0, rotate = 0 } = model.value;
7505
+ const radian = rotate * Math.PI / 180;
7506
+ const cos = Math.cos(radian);
7507
+ const sin = Math.sin(radian);
7508
+ return {
7509
+ ...sizeStyle.value,
7510
+ transform: `matrix(${cos}, ${sin}, ${-sin}, ${cos}, ${left}, ${top})`
7511
+ };
7512
+ });
7513
+ const tip = computed(() => props.tipFormat?.("size"));
7514
+ function start(event, index) {
7515
+ if (event && event.button !== void 0 && event.button !== 0) {
7516
+ return false;
7517
+ }
7518
+ event?.preventDefault();
7519
+ event?.stopPropagation();
7520
+ const { left, top, width, height, rotate, borderRadius } = model.value;
7521
+ let aspectRatio = 0;
7522
+ if (width && height) {
7523
+ aspectRatio = width / height;
7524
+ }
7525
+ const handle = index === void 0 ? { type: "move", x: 0, y: 0, width: 0, height: 0 } : computedHandles.value[index];
7526
+ activeHandle.value = handle.type;
7527
+ const isMove = handle.type === "move";
7528
+ const isRotate = handle.type.startsWith("rotate");
7529
+ const isBorderRadius = handle.type.startsWith("border-radius");
7530
+ const isHorizontal = handle.type === "resize-left" || handle.type === "resize-right";
7531
+ const isHorizontalVertical = handle.type.split("-").length === 2;
7532
+ const centerPoint = {
7533
+ x: left + width / 2,
7534
+ y: top + height / 2
7535
+ };
7536
+ const startPoint = {
7537
+ x: left,
7538
+ y: top
7539
+ };
7540
+ if (!isMove) {
7541
+ startPoint.x += handle.x + handle.width / 2;
7542
+ startPoint.y += handle.y + handle.height / 2;
7543
+ }
7544
+ const sign = {
7545
+ x: startPoint.x - centerPoint.x > 0 ? 1 : -1,
7546
+ y: startPoint.y - centerPoint.y > 0 ? 1 : -1
7547
+ };
7548
+ const rotatedStartPoint = rotatePoint(startPoint, centerPoint, rotate);
7549
+ const rotatedSymmetricPoint = {
7550
+ x: centerPoint.x * 2 - rotatedStartPoint.x,
7551
+ y: centerPoint.y * 2 - rotatedStartPoint.y
7552
+ };
7553
+ const startAngle = Math.atan2(
7554
+ rotatedStartPoint.y - centerPoint.y,
7555
+ rotatedStartPoint.x - centerPoint.x
7556
+ ) / (Math.PI / 180);
7557
+ let startClientPoint = event ? { x: event.clientX, y: event.clientY } : void 0;
7558
+ function startTransform() {
7559
+ transforming.value = true;
7560
+ emit("start", model.value);
7561
+ }
7562
+ if (!props.threshold && !transforming.value) {
7563
+ startTransform();
7564
+ }
7565
+ function onMove(event2) {
7566
+ const updated = {};
7567
+ if (!startClientPoint) {
7568
+ startClientPoint = { x: event2.clientX, y: event2.clientY };
7569
+ }
7570
+ const rotatedOffset = {
7571
+ x: event2.clientX - startClientPoint.x,
7572
+ y: event2.clientY - startClientPoint.y
7573
+ };
7574
+ if (!transforming.value) {
7575
+ if (Math.abs(rotatedOffset.x) < props.threshold && Math.abs(rotatedOffset.y) < props.threshold) {
7576
+ return;
7577
+ }
7578
+ startTransform();
7579
+ }
7580
+ const rotatedCurrentPoint = {
7581
+ x: rotatedStartPoint.x + rotatedOffset.x,
7582
+ y: rotatedStartPoint.y + rotatedOffset.y
7583
+ };
7584
+ if (isMove) {
7585
+ if (props.movable) {
7586
+ updated.left = startPoint.x + rotatedOffset.x;
7587
+ updated.top = startPoint.y + rotatedOffset.y;
7588
+ }
7589
+ } else if (isRotate) {
7590
+ if (props.rotatable) {
7591
+ const endAngle = Math.atan2(
7592
+ rotatedCurrentPoint.y - centerPoint.y,
7593
+ rotatedCurrentPoint.x - centerPoint.x
7594
+ ) / (Math.PI / 180);
7595
+ updated.rotate = (rotate + endAngle - startAngle + 360) % 360;
7596
+ }
7597
+ } else if (isBorderRadius) {
7598
+ const offset2 = rotatePoint(rotatedOffset, { x: 0, y: 0 }, -rotate);
7599
+ const _offset = Math.abs(offset2.x) < Math.abs(offset2.y) ? -sign.x * offset2.x : -sign.y * offset2.y * aspectRatio;
7600
+ updated.borderRadius = Math.min(
7601
+ Math.max(0, borderRadius + _offset),
7602
+ Math.min(width / 2, height / 2)
7603
+ );
7604
+ } else if (isHorizontalVertical) {
7605
+ const currentPoint = rotatePoint(rotatedCurrentPoint, centerPoint, -rotate);
7606
+ const newCurrentPoint = isHorizontal ? { x: currentPoint.x, y: startPoint.y } : { x: startPoint.x, y: currentPoint.y };
7607
+ const newRotatedCurrentPoint = rotatePoint(newCurrentPoint, centerPoint, rotate);
7608
+ const distance = Math.abs(getDistance(newRotatedCurrentPoint, rotatedSymmetricPoint));
7609
+ if (isHorizontal) {
7610
+ updated.width = distance;
7611
+ if (props.resizeStrategy === "lockAspectRatio" && aspectRatio) {
7612
+ updated.height = distance / aspectRatio;
7613
+ } else {
7614
+ updated.height = height;
7615
+ }
7616
+ } else {
7617
+ updated.height = distance;
7618
+ if (props.resizeStrategy === "lockAspectRatio" && aspectRatio) {
7619
+ updated.width = distance * aspectRatio;
7620
+ } else {
7621
+ updated.width = width;
7622
+ }
7623
+ }
7624
+ const newCenterPoint = getMidpoint(newRotatedCurrentPoint, rotatedSymmetricPoint);
7625
+ updated.left = newCenterPoint.x - updated.width / 2;
7626
+ updated.top = newCenterPoint.y - updated.height / 2;
7627
+ } else {
7628
+ let newRotatedCurrentPoint;
7629
+ if ((props.resizeStrategy === "lockAspectRatio" || props.resizeStrategy === "lockAspectRatioDiagonal") && aspectRatio) {
7630
+ const offset2 = rotatePoint(rotatedOffset, { x: 0, y: 0 }, -rotate);
7631
+ const _offset = Math.abs(offset2.x) < Math.abs(offset2.y) ? sign.x * offset2.x : sign.y * offset2.y * aspectRatio;
7632
+ newRotatedCurrentPoint = rotatePoint(
7633
+ {
7634
+ x: startPoint.x + sign.x * _offset,
7635
+ y: startPoint.y + sign.y * _offset / aspectRatio
7636
+ },
7637
+ centerPoint,
7638
+ rotate
7639
+ );
7640
+ } else {
7641
+ newRotatedCurrentPoint = rotatedCurrentPoint;
7642
+ }
7643
+ const newCenterPoint = getMidpoint(newRotatedCurrentPoint, rotatedSymmetricPoint);
7644
+ const points = [
7645
+ rotatePoint(newRotatedCurrentPoint, newCenterPoint, -rotate),
7646
+ rotatePoint(rotatedSymmetricPoint, newCenterPoint, -rotate)
7647
+ ];
7648
+ const [minX, maxX] = points[0].x > points[1].x ? [points[1].x, points[0].x] : [points[0].x, points[1].x];
7649
+ const [minY, maxY] = points[0].y > points[1].y ? [points[1].y, points[0].y] : [points[0].y, points[1].y];
7650
+ updated.width = maxX - minX;
7651
+ updated.height = maxY - minY;
7652
+ updated.left = minX;
7653
+ updated.top = minY;
7654
+ }
7655
+ if ("width" in updated && updated.width <= 0 || "height" in updated && updated.height <= 0) {
7656
+ return;
7657
+ }
7658
+ const oldValue = { ...model.value };
7659
+ const newValue = { ...model.value, ...updated };
7660
+ model.value = newValue;
7661
+ emit("move", newValue, oldValue);
7662
+ }
7663
+ function onEnd() {
7664
+ window.removeEventListener("pointermove", onMove);
7665
+ window.removeEventListener("pointerup", onEnd, true);
7666
+ transforming.value = false;
7667
+ activeHandle.value = void 0;
7668
+ emit("end", model.value);
7669
+ }
7670
+ window.addEventListener("pointermove", onMove);
7671
+ window.addEventListener("pointerup", onEnd, true);
7672
+ return true;
7673
+ }
7674
+ const cursorMap = {
7675
+ 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"/>',
7676
+ 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"/>',
7677
+ 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"/>'
7678
+ };
7679
+ function createCursor(type, angle) {
7680
+ const path = cursorMap[type];
7681
+ 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, "'");
7682
+ }
7683
+ function getCursor(type) {
7684
+ if (type === "move")
7685
+ return "move";
7686
+ const create = cursors[type];
7687
+ if (!create) {
7688
+ return "default";
7689
+ }
7690
+ return `url("data:image/svg+xml,${create(model.value.rotate ?? 0)}") 16 16, pointer`;
7691
+ }
7692
+ function rotatePoint(point, origin, angle) {
7693
+ const radian = angle * Math.PI / 180;
7694
+ const cos = Math.cos(radian);
7695
+ const sin = Math.sin(radian);
7696
+ return {
7697
+ x: (point.x - origin.x) * cos - (point.y - origin.y) * sin + origin.x,
7698
+ y: (point.x - origin.x) * sin + (point.y - origin.y) * cos + origin.y
7699
+ };
7700
+ }
7701
+ function getMidpoint(point1, point2) {
7702
+ return {
7703
+ x: (point2.x + point1.x) / 2,
7704
+ y: (point2.y + point1.y) / 2
7705
+ };
7706
+ }
7707
+ function getDistance(point1, point2) {
7708
+ const dx = point2.x - point1.x;
7709
+ const dy = point2.y - point1.y;
7710
+ return (dx + dy >= 0 ? 1 : -1) * Math.sqrt(dx * dx + dy * dy);
7711
+ }
7712
+ onMounted(async () => {
7713
+ const vm = getCurrentInstance();
7714
+ const root = vm?.proxy?.$el;
7715
+ if (root && props.initialSize) {
7716
+ await nextTick();
7717
+ let width;
7718
+ let height;
7719
+ const style2 = getComputedStyle(root);
7720
+ if (style2.width.endsWith("px") && style2.height.endsWith("px")) {
7721
+ width = Number(style2.width.replace("px", ""));
7722
+ height = Number(style2.height.replace("px", ""));
7723
+ } else {
7724
+ ({ width, height } = root.getBoundingClientRect());
7725
+ }
7726
+ if (width && height) {
7727
+ model.value = { ...model.value, width, height };
7728
+ } else if ("ResizeObserver" in globalThis) {
7729
+ const observer = new ResizeObserver(([entry]) => {
7730
+ if (entry.contentRect.width && entry.contentRect.height) {
7731
+ model.value = {
7732
+ ...model.value,
7733
+ width: entry.contentRect.width,
7734
+ height: entry.contentRect.height
7735
+ };
7736
+ observer.unobserve(root);
7737
+ }
7738
+ });
7739
+ observer.observe(root);
7740
+ }
7741
+ }
7742
+ });
7743
+ __expose({
7744
+ start,
7745
+ activeHandle,
7746
+ transforming
7747
+ });
7748
+ function Diagonal() {
7749
+ const handle = activeHandle.value;
7750
+ if (!handle || !handle.startsWith("resize")) {
7751
+ return void 0;
7752
+ }
7753
+ switch (props.resizeStrategy) {
7754
+ case "lockAspectRatio":
7755
+ break;
7756
+ case "lockAspectRatioDiagonal":
7757
+ if (handle.split("-").length === 2) {
7758
+ return void 0;
7759
+ }
7760
+ break;
7761
+ default:
7762
+ return void 0;
7763
+ }
7764
+ if (handle === "resize-top" || handle === "resize-right" || handle === "resize-top-right" || handle === "resize-bottom-left") {
7765
+ return h("line", {
7766
+ class: "mce-transformable__diagonal",
7767
+ x1: "100%",
7768
+ y1: "0",
7769
+ x2: "0",
7770
+ y2: "100%"
7771
+ });
7772
+ } else if (handle === "resize-left" || handle === "resize-bottom" || handle === "resize-top-left" || handle === "resize-bottom-right") {
7773
+ return h("line", {
7774
+ class: "mce-transformable__diagonal",
7775
+ x1: "0",
7776
+ y1: "0",
7777
+ x2: "100%",
7778
+ y2: "100%"
7779
+ });
7780
+ }
7781
+ return void 0;
7782
+ }
7783
+ return (_ctx, _cache) => {
7784
+ return openBlock(), createBlock(resolveDynamicComponent(__props.tag), {
7785
+ class: normalizeClass(["mce-transformable", [
7786
+ transforming.value && "mce-transformable--transforming",
7787
+ props.hideUi && "mce-transformable--hide-ui",
7788
+ __props.resizeStrategy && `mce-transformable--${__props.resizeStrategy}`,
7789
+ activeHandle.value && `mce-transformable--${activeHandle.value}`,
7790
+ activeHandle.value === "move" && "mce-transformable--moving",
7791
+ activeHandle.value?.startsWith("resize") && "mce-transformable--resizing",
7792
+ activeHandle.value?.startsWith("rotate") && "mce-transformable--rotateing",
7793
+ props.borderStyle && `mce-transformable--${props.borderStyle}`
7794
+ ]]),
7795
+ style: normalizeStyle(style.value)
7796
+ }, {
7797
+ default: withCtx(() => [
7798
+ renderSlot(_ctx.$slots, "default", {
7799
+ value: unref(modelValue),
7800
+ props: {
7801
+ onPointerdown: start
7802
+ },
7803
+ start
7804
+ }),
7805
+ (openBlock(), createElementBlock("svg", _hoisted_1$j, [
7806
+ _cache[0] || (_cache[0] = createElementVNode("rect", {
7807
+ width: "100%",
7808
+ height: "100%",
7809
+ fill: "none",
7810
+ class: "mce-transformable__rect"
7811
+ }, null, -1)),
7812
+ createElementVNode("rect", {
7813
+ class: "mce-transformable__rect",
7814
+ width: "100%",
7815
+ height: "100%",
7816
+ fill: "none",
7817
+ rx: model.value.borderRadius,
7818
+ ry: model.value.borderRadius
7819
+ }, null, 8, _hoisted_2$8),
7820
+ createVNode(Diagonal),
7821
+ createElementVNode("g", null, [
7822
+ (openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value, (handle, index) => {
7823
+ return openBlock(), createElementBlock(Fragment, { key: index }, [
7824
+ handle.shape ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
7825
+ handle.shape === "rect" ? (openBlock(), createElementBlock("rect", {
7826
+ key: 0,
7827
+ x: handle.x,
7828
+ y: handle.y,
7829
+ width: handle.width,
7830
+ height: handle.height,
7831
+ "aria-label": handle.type,
7832
+ class: "mce-transformable__handle"
7833
+ }, null, 8, _hoisted_3$6)) : (openBlock(), createElementBlock("circle", {
7834
+ key: 1,
7835
+ cx: handle.x + handle.width / 2,
7836
+ cy: handle.y + handle.width / 2,
7837
+ r: handle.width / 2,
7838
+ "aria-label": handle.type,
7839
+ class: "mce-transformable__handle"
7840
+ }, null, 8, _hoisted_4$3))
7841
+ ], 64)) : createCommentVNode("", true)
7842
+ ], 64);
7843
+ }), 128))
7844
+ ]),
7845
+ createElementVNode("g", _hoisted_5$2, [
7846
+ (openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value, (handle, index) => {
7847
+ return openBlock(), createElementBlock("rect", {
7848
+ key: index,
7849
+ ref_for: true,
7850
+ ref_key: "handlesRef",
7851
+ ref: handlesRef,
7852
+ x: handle.x,
7853
+ y: handle.y,
7854
+ width: handle.width,
7855
+ height: handle.height,
7856
+ "aria-label": handle.type,
7857
+ class: "mce-transformable__handle-rect",
7858
+ cursor: transforming.value ? "auto" : getCursor(handle.type),
7859
+ onPointerdown: (event) => start(event, index)
7860
+ }, null, 40, _hoisted_6$2);
7861
+ }), 128))
7862
+ ]),
7863
+ createElementVNode("g", _hoisted_7$2, [
7864
+ renderSlot(_ctx.$slots, "svg", { box: model.value })
7865
+ ])
7866
+ ])),
7867
+ tip.value ? (openBlock(), createElementBlock("div", _hoisted_8$1, toDisplayString(tip.value), 1)) : createCommentVNode("", true)
7868
+ ]),
7869
+ _: 3
7870
+ }, 8, ["class", "style"]);
7206
7871
  };
7207
7872
  }
7208
7873
  });
7209
- const _hoisted_1$h = ["data-name"];
7210
- const _sfc_main$q = /* @__PURE__ */ defineComponent({
7211
- __name: "Hover",
7212
- setup(__props) {
7213
- const {
7214
- selection,
7215
- hoverElement,
7216
- getObbInDrawboard
7217
- } = useEditor();
7218
- const hoverElementObb = computed(() => getObbInDrawboard(hoverElement.value));
7874
+ const _hoisted_1$i = { class: "mce-cropper" };
7875
+ const _sfc_main$v = /* @__PURE__ */ defineComponent({
7876
+ __name: "Cropper",
7877
+ props: /* @__PURE__ */ mergeModels({
7878
+ image: {},
7879
+ minScale: { default: 0.1 },
7880
+ maxScale: { default: 3 }
7881
+ }, {
7882
+ "modelValue": { default: () => ({}) },
7883
+ "modelModifiers": {},
7884
+ "style": { default: () => ({}) },
7885
+ "styleModifiers": {}
7886
+ }),
7887
+ emits: /* @__PURE__ */ mergeModels(["start", "end", "update:transform"], ["update:modelValue", "update:style"]),
7888
+ setup(__props, { emit: __emit }) {
7889
+ const props = __props;
7890
+ const emit = __emit;
7891
+ const cropRect = useModel(__props, "modelValue");
7892
+ const styleModel = useModel(__props, "style");
7893
+ const rootBox = ref({ width: 0, height: 0 });
7894
+ const { state: imageRef } = useImage(
7895
+ computed(() => ({
7896
+ src: props.image
7897
+ }))
7898
+ );
7899
+ const backup = cloneDeep(cropRect.value);
7900
+ const canvasRef = useTemplateRef("canvasRef");
7901
+ const computedCropRect = computed({
7902
+ get: () => {
7903
+ const { left = 0, top = 0, right = 0, bottom = 0 } = cropRect.value;
7904
+ return { left, top, right, bottom };
7905
+ },
7906
+ set: (val) => cropRect.value = val
7907
+ });
7908
+ const inverseMat = computed(() => {
7909
+ const { left, top, right, bottom } = computedCropRect.value;
7910
+ const sx = 1 / (1 - left - right);
7911
+ const sy = 1 / (1 - top - bottom);
7912
+ const tx = -left;
7913
+ const ty = -top;
7914
+ return { sx, sy, tx, ty };
7915
+ });
7916
+ const sourceTransform = computed({
7917
+ get: () => {
7918
+ const { sx, sy, tx, ty } = inverseMat.value;
7919
+ const { scaleX = 1, scaleY = 1 } = styleModel.value;
7920
+ const { width, height } = rootBox.value;
7921
+ return {
7922
+ width: sx * width,
7923
+ height: sy * height,
7924
+ left: tx * scaleX * (sx * width),
7925
+ top: ty * scaleY * (sy * height)
7926
+ };
7927
+ },
7928
+ set: (newValue) => {
7929
+ const { width, height } = rootBox.value;
7930
+ const { scaleX = 1, scaleY = 1 } = styleModel.value;
7931
+ const transform = {
7932
+ sx: newValue.width / width,
7933
+ sy: newValue.height / height,
7934
+ tx: newValue.left / newValue.width / scaleX,
7935
+ ty: newValue.top / newValue.height / scaleY
7936
+ };
7937
+ const left = -transform.tx;
7938
+ const top = -transform.ty;
7939
+ const w = 1 - 1 / transform.sx;
7940
+ const h2 = 1 - 1 / transform.sy;
7941
+ const right = w - left;
7942
+ const bottom = h2 - top;
7943
+ computedCropRect.value = { left, top, right, bottom };
7944
+ }
7945
+ });
7946
+ const scale = computed({
7947
+ get: () => inverseMat.value.sx,
7948
+ set: (value) => {
7949
+ const transform = inverseMat.value;
7950
+ const rate = transform.sx / value;
7951
+ const left = -transform.tx;
7952
+ const top = -transform.ty;
7953
+ const w = 1 - 1 / value;
7954
+ const h2 = 1 - 1 / transform.sy * rate;
7955
+ const right = w - left;
7956
+ const bottom = h2 - top;
7957
+ computedCropRect.value = { left, top, right, bottom };
7958
+ }
7959
+ });
7960
+ onBeforeMount(() => emit("start"));
7961
+ onBeforeUnmount(() => emit("end"));
7962
+ const sourceStyle = computed(() => {
7963
+ const { sx, sy, tx, ty } = inverseMat.value;
7964
+ const { scaleX = 1, scaleY = 1 } = styleModel.value;
7965
+ return {
7966
+ transform: [
7967
+ `scale(${sx}, ${sy})`,
7968
+ `translate(${tx * scaleX * 100}%, ${ty * scaleY * 100}%)`
7969
+ ].join(" ")
7970
+ };
7971
+ });
7972
+ watch([canvasRef, imageRef], render2);
7973
+ watch(computedCropRect, render2, { deep: true });
7974
+ watch([() => styleModel.value.scaleX, () => styleModel.value.scaleY], render2);
7975
+ function render2() {
7976
+ const ctx = canvasRef.value?.getContext("2d");
7977
+ if (!ctx || !imageRef.value)
7978
+ return;
7979
+ const { scaleX = 1, scaleY = 1 } = styleModel.value;
7980
+ const { naturalWidth, naturalHeight } = imageRef.value;
7981
+ ctx.canvas.width = naturalWidth;
7982
+ ctx.canvas.height = naturalHeight;
7983
+ ctx.clearRect(0, 0, naturalWidth, naturalHeight);
7984
+ ctx.globalAlpha = 0.4;
7985
+ ctx.scale(scaleX, scaleY);
7986
+ ctx.drawImage(imageRef.value, 0, 0, naturalWidth, naturalHeight);
7987
+ }
7988
+ function ok() {
7989
+ emit("end");
7990
+ }
7991
+ function cancel() {
7992
+ cropRect.value = backup;
7993
+ ok();
7994
+ }
7995
+ function onResizeObserver(entries) {
7996
+ const { width, height } = entries[0].contentRect;
7997
+ rootBox.value = { width, height };
7998
+ }
7999
+ function applySourceTransformToStyle() {
8000
+ const { left = 0, top = 0, width = 0, height = 0 } = styleModel.value;
8001
+ const { sx, sy, tx, ty } = inverseMat.value;
8002
+ cropRect.value = {};
8003
+ styleModel.value = {
8004
+ ...styleModel.value,
8005
+ width: sx * width,
8006
+ height: sy * height,
8007
+ left: left + tx * (sx * width),
8008
+ top: top + ty * (sy * height)
8009
+ };
8010
+ ok();
8011
+ }
7219
8012
  return (_ctx, _cache) => {
7220
- return unref(hoverElement) && !unref(hoverElement).equal(unref(selection)[0]) ? (openBlock(), createElementBlock("div", {
7221
- key: 0,
7222
- class: "mce-hover",
7223
- "data-name": unref(hoverElement).name,
7224
- style: normalizeStyle({
7225
- borderColor: "currentcolor",
7226
- ...unref(boundingBoxToStyle)(hoverElementObb.value)
8013
+ return withDirectives((openBlock(), createElementBlock("div", _hoisted_1$i, [
8014
+ createElementVNode("div", {
8015
+ class: "mce-cropper__source",
8016
+ style: normalizeStyle(sourceStyle.value)
8017
+ }, [
8018
+ createElementVNode("canvas", {
8019
+ ref_key: "canvasRef",
8020
+ ref: canvasRef
8021
+ }, null, 512)
8022
+ ], 4),
8023
+ createVNode(_sfc_main$w, {
8024
+ modelValue: sourceTransform.value,
8025
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => sourceTransform.value = $event),
8026
+ class: "mce-cropper__transformable",
8027
+ rotatable: false
8028
+ }, {
8029
+ default: withCtx(({ props: slotProps }) => [
8030
+ createElementVNode("div", mergeProps({ class: "mce-cropper__transformable_rect" }, slotProps), null, 16)
8031
+ ]),
8032
+ _: 1
8033
+ }, 8, ["modelValue"]),
8034
+ renderSlot(_ctx.$slots, "default", {
8035
+ scale: scale.value,
8036
+ ok,
8037
+ cancel,
8038
+ applySourceTransformToStyle
7227
8039
  })
7228
- }, null, 12, _hoisted_1$h)) : createCommentVNode("", true);
8040
+ ])), [
8041
+ [unref(vResizeObserver), onResizeObserver]
8042
+ ]);
7229
8043
  };
7230
8044
  }
7231
8045
  });
7232
- const _hoisted_1$g = { class: "mce-btn" };
7233
- const _sfc_main$p = /* @__PURE__ */ defineComponent({
7234
- __name: "Btn",
8046
+ const _sfc_main$u = /* @__PURE__ */ defineComponent({
8047
+ __name: "ForegroundCropper",
7235
8048
  setup(__props) {
8049
+ const {
8050
+ state,
8051
+ setState,
8052
+ elementSelection
8053
+ } = useEditor();
8054
+ const element = computed(() => elementSelection.value[0]);
7236
8055
  return (_ctx, _cache) => {
7237
- return openBlock(), createElementBlock("div", _hoisted_1$g, [
7238
- renderSlot(_ctx.$slots, "default")
7239
- ]);
8056
+ return unref(state) === "cropping" && element.value?.foreground.isValid() ? (openBlock(), createBlock(_sfc_main$v, {
8057
+ key: 0,
8058
+ modelValue: element.value.foreground.cropRect,
8059
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => element.value.foreground.cropRect = $event),
8060
+ style: normalizeStyle(element.value.style.toJSON()),
8061
+ image: element.value.foreground.image,
8062
+ class: "pointer-events-auto",
8063
+ "onUpdate:style": _cache[1] || (_cache[1] = (val) => element.value.style.setProperties(val)),
8064
+ onEnd: _cache[2] || (_cache[2] = () => unref(setState)(void 0))
8065
+ }, null, 8, ["modelValue", "style", "image"])) : createCommentVNode("", true);
7240
8066
  };
7241
8067
  }
7242
8068
  });
7243
- const _hoisted_1$f = { class: "mce-layer__name" };
7244
- const _hoisted_2$8 = { class: "mce-layer__action" };
7245
- const _sfc_main$o = /* @__PURE__ */ defineComponent({
7246
- ...{
7247
- name: "MceLayer",
7248
- inheritAttrs: false
8069
+ const _sfc_main$t = /* @__PURE__ */ defineComponent({
8070
+ __name: "Frame",
8071
+ props: {
8072
+ "modelValue": { required: true },
8073
+ "modelModifiers": {}
7249
8074
  },
7250
- __name: "Layer",
7251
- props: /* @__PURE__ */ mergeModels({
7252
- root: Boolean,
7253
- node: {
7254
- type: Object,
7255
- required: true
7256
- },
7257
- active: Boolean,
7258
- indent: {
7259
- type: Number,
7260
- default: 0
7261
- }
7262
- }, {
7263
- "opened": { default: false },
7264
- "openedModifiers": {}
7265
- }),
7266
- emits: ["update:opened"],
8075
+ emits: ["update:modelValue"],
7267
8076
  setup(__props) {
7268
- const props = __props;
8077
+ const frame = useModel(__props, "modelValue");
8078
+ const input = useTemplateRef("inputTpl");
7269
8079
  const {
7270
- isElement,
7271
- isFrame,
7272
- isVisible,
7273
- setVisible,
7274
- isLock,
7275
- setLock,
7276
- selection,
7277
- nodes,
7278
- nodeIndexMap,
7279
- zoomTo,
8080
+ getObbInDrawboard,
7280
8081
  hoverElement,
8082
+ selection,
8083
+ state,
8084
+ config,
7281
8085
  exec
7282
8086
  } = useEditor();
7283
- const opened = useModel(__props, "opened");
7284
- const dom = ref();
7285
- const {
7286
- selecting,
7287
- sortedSelection
7288
- } = useLayerItem({
7289
- id: props.node.id,
7290
- opened,
7291
- node: computed(() => props.node),
7292
- dom: computed(() => dom.value)
7293
- });
7294
- const isFrist = computed(() => sortedSelection.value[0]?.equal(props.node));
7295
- const isLast = computed(() => {
7296
- const last = sortedSelection.value[sortedSelection.value.length - 1];
7297
- if (last) {
7298
- if (last.equal(props.node)) {
7299
- if (!opened.value || !props.node?.children.length)
7300
- return true;
7301
- } else if (last.equal(props.node?.parent)) ;
7302
- }
7303
- return false;
7304
- });
7305
- const isActive = computed(() => selection.value.some((v) => v.equal(props.node)));
7306
- const inputDom = ref();
7307
- const isHoverElement = computed(() => props.node?.equal(hoverElement.value));
7308
- const hovering = ref(false);
7309
8087
  const editing = ref(false);
7310
- const editValue = ref();
7311
- const thumbnailIcon = computed(() => {
7312
- const node = props.node;
7313
- if (isFrame(node)) {
7314
- return "$frame";
7315
- } else if (node.children.length) {
7316
- return "$group";
7317
- } else if (isElement(node)) {
7318
- if (node.foreground.isValid() && node.foreground.image) {
7319
- return "$image";
7320
- }
7321
- if (node.text.isValid()) {
7322
- return "$text";
7323
- }
7324
- }
7325
- return "$shape";
7326
- });
7327
- function onMousedown() {
7328
- }
7329
- function onClickExpand() {
7330
- opened.value = !opened.value;
7331
- }
7332
- function onClickContent(e) {
7333
- selecting.value = true;
7334
- if (isElement(props.node)) {
7335
- if (e.shiftKey) {
7336
- const _nodes = [
7337
- ...selection.value.filter((v) => !v.equal(props.node)),
7338
- props.node
7339
- ];
7340
- let min;
7341
- let max;
7342
- _nodes.forEach((el) => {
7343
- const index = nodeIndexMap.get(el.id);
7344
- if (index !== void 0) {
7345
- min = min === void 0 ? index : Math.min(min, index);
7346
- max = max === void 0 ? index : Math.max(max, index);
7347
- }
7348
- });
7349
- if (min !== void 0 && max !== void 0) {
7350
- let _selection = nodes.value.slice(min, max + 1);
7351
- const result = new Set(_selection.map((node) => node.id));
7352
- const parents = /* @__PURE__ */ new Set();
7353
- _selection.forEach((node) => node.parent && parents.add(node.parent));
7354
- parents.forEach((parent) => {
7355
- if (parent.children.every((ch) => result.has(ch.id))) {
7356
- const ids = new Set(parent.children.map((ch) => ch.id));
7357
- _selection = [
7358
- ..._selection.filter((v) => !ids.has(v.id)),
7359
- parent
7360
- ];
7361
- }
7362
- });
7363
- selection.value = _selection;
7364
- }
7365
- } else if (e.ctrlKey || e.metaKey) {
7366
- const filtered = selection.value.filter((v) => !v.equal(props.node));
7367
- if (filtered.length !== selection.value.length) {
7368
- selection.value = filtered;
7369
- } else {
7370
- selection.value = [...filtered, props.node];
7371
- }
7372
- } else {
7373
- selection.value = [props.node];
7374
- }
7375
- }
7376
- nextTick().then(() => {
7377
- selecting.value = false;
7378
- });
7379
- }
7380
- function onDblclickThumbnail(e) {
7381
- e.stopPropagation();
7382
- if (isElement(props.node)) {
7383
- zoomTo("selection", {
7384
- behavior: "smooth"
7385
- });
7386
- }
7387
- }
7388
- function onDblclickContent() {
8088
+ async function onDblclick() {
7389
8089
  editing.value = true;
7390
- editValue.value = props.node.name;
7391
- nextTick().then(() => {
7392
- inputDom.value?.focus();
7393
- });
7394
- }
7395
- function onMouseenter() {
7396
- if (isElement(props.node)) {
7397
- hoverElement.value = props.node;
7398
- hovering.value = true;
7399
- }
7400
- }
7401
- function onMouseleave() {
7402
- hoverElement.value = void 0;
7403
- hovering.value = false;
7404
- }
7405
- function onContextmenu(e) {
7406
- if (isElement(props.node)) {
7407
- if (!selection.value.some((v) => v.equal(props.node))) {
7408
- selection.value = [props.node];
7409
- }
7410
- exec("openContextMenu", e);
8090
+ await nextTick();
8091
+ if (input.value) {
8092
+ input.value.focus();
8093
+ input.value.select();
7411
8094
  }
7412
8095
  }
7413
- function onInputBlur() {
7414
- console.log("onInputBlur");
7415
- editing.value = false;
7416
- if (editValue.value) {
7417
- props.node.name = editValue.value;
7418
- editValue.value = void 0;
8096
+ async function onPointerdown(ev) {
8097
+ if (!editing.value) {
8098
+ selection.value = [frame.value];
8099
+ await nextTick();
8100
+ exec("startTransform", ev);
7419
8101
  }
7420
8102
  }
7421
8103
  return (_ctx, _cache) => {
7422
- const _component_MceLayer = resolveComponent("MceLayer");
7423
- return openBlock(), createElementBlock(Fragment, null, [
7424
- createElementVNode("div", {
7425
- ref_key: "dom",
7426
- ref: dom,
7427
- class: normalizeClass(["mce-layer", [
7428
- props.root && "mce-layer--root",
7429
- (__props.active || isActive.value) && "mce-layer--active",
7430
- isFrist.value && "mce-layer--first",
7431
- isLast.value && "mce-layer--last",
7432
- opened.value && "mce-layer--open",
7433
- isHoverElement.value && "mce-layer--hover"
7434
- ]]),
7435
- style: normalizeStyle({
7436
- "--indent-padding": `${props.indent * 16}px`
7437
- }),
7438
- onMousedown,
7439
- onMouseenter,
7440
- onMouseleave,
7441
- onContextmenu
8104
+ return withDirectives((openBlock(), createElementBlock("div", {
8105
+ style: normalizeStyle(unref(boundingBoxToStyle)(unref(getObbInDrawboard)(frame.value))),
8106
+ class: normalizeClass(["mce-frame", [
8107
+ unref(config).frameOutline && "mce-frame--outline"
8108
+ ]])
8109
+ }, [
8110
+ withDirectives(createElementVNode("div", {
8111
+ class: "mce-frame__name",
8112
+ onDblclick,
8113
+ onPointerdown,
8114
+ onPointerenter: _cache[2] || (_cache[2] = ($event) => !unref(state) && (hoverElement.value = frame.value)),
8115
+ onPointerleave: _cache[3] || (_cache[3] = ($event) => !unref(state) && (hoverElement.value = void 0))
7442
8116
  }, [
7443
- createElementVNode("div", {
7444
- class: "mce-layer__expand",
7445
- onClick: onClickExpand
7446
- }, [
7447
- props.node.children.length ? (openBlock(), createBlock(_sfc_main$z, {
7448
- key: 0,
7449
- icon: "$arrowRight"
7450
- })) : createCommentVNode("", true)
7451
- ]),
7452
- createElementVNode("div", {
7453
- class: "mce-layer__content",
7454
- onClick: onClickContent,
7455
- onDblclick: onDblclickContent
7456
- }, [
7457
- createElementVNode("div", {
7458
- class: "mce-layer__thumbnail",
7459
- onDblclick: onDblclickThumbnail
7460
- }, [
7461
- createVNode(_sfc_main$z, { icon: thumbnailIcon.value }, null, 8, ["icon"])
7462
- ], 32),
7463
- createElementVNode("div", _hoisted_1$f, [
7464
- withDirectives(createElementVNode("input", {
7465
- ref_key: "inputDom",
7466
- ref: inputDom,
7467
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => editValue.value = $event),
7468
- type: "text",
7469
- class: "mce-layer__input",
7470
- autofocus: "",
7471
- onBlur: onInputBlur
7472
- }, null, 544), [
7473
- [vShow, editing.value],
7474
- [vModelText, editValue.value]
7475
- ]),
7476
- createElementVNode("div", {
7477
- style: normalizeStyle({ visibility: editing.value ? "hidden" : void 0 })
7478
- }, toDisplayString(editValue.value || props.node.name || props.node.id), 5)
7479
- ]),
7480
- createElementVNode("div", _hoisted_2$8, [
7481
- props.root ? (openBlock(), createElementBlock("div", {
7482
- key: 0,
7483
- class: normalizeClass(["mce-btn", {
7484
- "mce-btn--hide": !hovering.value && !unref(isLock)(props.node)
7485
- }]),
7486
- onClick: _cache[1] || (_cache[1] = ($event) => unref(setLock)(props.node, !unref(isLock)(props.node)))
7487
- }, [
7488
- createVNode(_sfc_main$z, {
7489
- icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
7490
- }, null, 8, ["icon"])
7491
- ], 2)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
7492
- createVNode(_sfc_main$p, {
7493
- class: normalizeClass({
7494
- "mce-btn--hide": !hovering.value && !unref(isLock)(props.node)
7495
- }),
7496
- onClick: _cache[2] || (_cache[2] = withModifiers(($event) => unref(setLock)(props.node, !unref(isLock)(props.node)), ["prevent", "stop"]))
7497
- }, {
7498
- default: withCtx(() => [
7499
- createVNode(_sfc_main$z, {
7500
- icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
7501
- }, null, 8, ["icon"])
7502
- ]),
7503
- _: 1
7504
- }, 8, ["class"]),
7505
- createVNode(_sfc_main$p, {
7506
- class: normalizeClass({
7507
- "mce-btn--hide": !hovering.value && unref(isVisible)(props.node)
7508
- }),
7509
- onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(setVisible)(props.node, !unref(isVisible)(props.node)), ["prevent", "stop"]))
7510
- }, {
7511
- default: withCtx(() => [
7512
- createVNode(_sfc_main$z, {
7513
- icon: unref(isVisible)(props.node) ? "$visible" : "$unvisible"
7514
- }, null, 8, ["icon"])
7515
- ]),
7516
- _: 1
7517
- }, 8, ["class"])
7518
- ], 64))
7519
- ])
7520
- ], 32)
7521
- ], 38),
7522
- opened.value ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.node.children, (child, key) => {
7523
- return openBlock(), createBlock(_component_MceLayer, {
7524
- key,
7525
- node: child,
7526
- indent: __props.root ? props.indent : props.indent + 1,
7527
- active: __props.active || isActive.value
7528
- }, null, 8, ["node", "indent", "active"]);
7529
- }), 128)) : createCommentVNode("", true)
7530
- ], 64);
8117
+ createElementVNode("div", null, toDisplayString(frame.value.name), 1),
8118
+ withDirectives(createElementVNode("input", {
8119
+ ref: "inputTpl",
8120
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => frame.value.name = $event),
8121
+ onBlur: _cache[1] || (_cache[1] = ($event) => editing.value = false)
8122
+ }, null, 544), [
8123
+ [vShow, editing.value],
8124
+ [vModelText, frame.value.name]
8125
+ ])
8126
+ ], 544), [
8127
+ [vShow, unref(config).viewMode === "edgeless"]
8128
+ ])
8129
+ ], 6)), [
8130
+ [vShow, frame.value.visible]
8131
+ ]);
7531
8132
  };
7532
8133
  }
7533
8134
  });
7534
- const _hoisted_1$e = { class: "mce-layers" };
7535
- const _hoisted_2$7 = { class: "mce-layers__wrapper" };
7536
- const _sfc_main$n = /* @__PURE__ */ defineComponent({
7537
- __name: "Layers",
8135
+ const _sfc_main$s = /* @__PURE__ */ defineComponent({
8136
+ __name: "Frames",
7538
8137
  setup(__props) {
7539
8138
  const {
7540
- root,
7541
- selection,
7542
- state,
7543
- nodeIndexMap
8139
+ frames
7544
8140
  } = useEditor();
7545
- const sortedSelection = computed(() => {
7546
- return selection.value.map((node) => {
7547
- return {
7548
- node,
7549
- index: nodeIndexMap.get(node.id) ?? 0
7550
- };
7551
- }).sort((a, b) => a.index - b.index).map((v) => v.node);
7552
- });
8141
+ return (_ctx, _cache) => {
8142
+ return openBlock(true), createElementBlock(Fragment, null, renderList(unref(frames), (frame, key) => {
8143
+ return openBlock(), createBlock(_sfc_main$t, {
8144
+ key,
8145
+ "model-value": frame
8146
+ }, null, 8, ["model-value"]);
8147
+ }), 128);
8148
+ };
8149
+ }
8150
+ });
8151
+ const _sfc_main$r = /* @__PURE__ */ defineComponent({
8152
+ __name: "GoBackSelectedArea",
8153
+ setup(__props) {
7553
8154
  const {
7554
- selecting,
7555
- openedItems,
7556
- domItems
7557
- } = createLayer({
7558
- sortedSelection
7559
- });
7560
- watch(selection, (selection2) => {
7561
- if (state.value === "selecting" || selecting.value) {
7562
- return;
7563
- }
7564
- let last;
7565
- selection2.forEach((node) => {
7566
- node.findAncestor((ancestor) => {
7567
- const opened = openedItems.get(ancestor.id);
7568
- if (opened) {
7569
- opened.value = true;
7570
- }
7571
- return false;
7572
- });
7573
- last = node;
7574
- });
7575
- if (last) {
7576
- nextTick().then(() => {
7577
- domItems.get(last.id)?.value?.scrollIntoView({
7578
- block: "center"
7579
- });
7580
- });
7581
- }
8155
+ selectionAabb,
8156
+ drawboardAabb,
8157
+ aabbToDrawboardAabb,
8158
+ t,
8159
+ exec
8160
+ } = useEditor();
8161
+ const isActive = computed(() => {
8162
+ return selectionAabb.value.width && selectionAabb.value.height && !isOverlappingAabb(
8163
+ drawboardAabb.value,
8164
+ aabbToDrawboardAabb(selectionAabb.value)
8165
+ );
7582
8166
  });
7583
8167
  return (_ctx, _cache) => {
7584
- return openBlock(), createElementBlock("div", _hoisted_1$e, [
7585
- createElementVNode("div", _hoisted_2$7, [
7586
- createVNode(_sfc_main$o, {
7587
- root: true,
7588
- node: unref(root),
7589
- opened: true
7590
- }, null, 8, ["node"])
7591
- ])
7592
- ]);
8168
+ return isActive.value ? (openBlock(), createElementBlock("div", {
8169
+ key: 0,
8170
+ class: "mce-back-selected-aera",
8171
+ onClick: _cache[0] || (_cache[0] = withModifiers(($event) => unref(exec)("scrollToSelection", { behavior: "smooth" }), ["prevent"]))
8172
+ }, [
8173
+ createVNode(_sfc_main$C, { icon: "$gps" }),
8174
+ createElementVNode("span", null, toDisplayString(unref(t)("goBackSelectedArea")), 1)
8175
+ ])) : createCommentVNode("", true);
8176
+ };
8177
+ }
8178
+ });
8179
+ const _hoisted_1$h = ["data-name"];
8180
+ const _sfc_main$q = /* @__PURE__ */ defineComponent({
8181
+ __name: "Hover",
8182
+ setup(__props) {
8183
+ const {
8184
+ selection,
8185
+ hoverElement,
8186
+ getObbInDrawboard
8187
+ } = useEditor();
8188
+ const hoverElementObb = computed(() => getObbInDrawboard(hoverElement.value));
8189
+ return (_ctx, _cache) => {
8190
+ return unref(hoverElement) && !unref(hoverElement).equal(unref(selection)[0]) ? (openBlock(), createElementBlock("div", {
8191
+ key: 0,
8192
+ class: "mce-hover",
8193
+ "data-name": unref(hoverElement).name,
8194
+ style: normalizeStyle({
8195
+ borderColor: "currentcolor",
8196
+ ...unref(boundingBoxToStyle)(hoverElementObb.value)
8197
+ })
8198
+ }, null, 12, _hoisted_1$h)) : createCommentVNode("", true);
7593
8199
  };
7594
8200
  }
7595
8201
  });
7596
- const _sfc_main$m = /* @__PURE__ */ defineComponent({
7597
- __name: "Tooltip",
7598
- props: /* @__PURE__ */ mergeModels({
7599
- ...makeMceOverlayProps({
7600
- location: "right",
7601
- offset: 8
7602
- })
7603
- }, {
7604
- "modelValue": { type: Boolean },
7605
- "modelModifiers": {}
7606
- }),
7607
- emits: ["update:modelValue"],
7608
- setup(__props, { expose: __expose }) {
7609
- const props = __props;
7610
- const isActive = useModel(__props, "modelValue");
7611
- const overlay = useTemplateRef("overlayTpl");
7612
- function updateLocation() {
7613
- overlay.value?.updateLocation();
7614
- }
7615
- __expose({
7616
- updateLocation
7617
- });
8202
+ const _hoisted_1$g = { class: "mce-btn" };
8203
+ const _sfc_main$p = /* @__PURE__ */ defineComponent({
8204
+ __name: "Btn",
8205
+ setup(__props) {
7618
8206
  return (_ctx, _cache) => {
7619
- return openBlock(), createBlock(_sfc_main$y, {
7620
- ref: "overlayTpl",
7621
- modelValue: isActive.value,
7622
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isActive.value = $event),
7623
- class: "mce-tooltip",
7624
- location: props.location,
7625
- offset: props.offset,
7626
- target: props.target,
7627
- attach: props.attach
7628
- }, createSlots({
7629
- default: withCtx(() => [
7630
- isActive.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
7631
- ]),
7632
- _: 2
7633
- }, [
7634
- _ctx.$slots.activator ? {
7635
- name: "activator",
7636
- fn: withCtx((activatorProps) => [
7637
- renderSlot(_ctx.$slots, "activator", normalizeProps(guardReactiveProps(activatorProps)))
7638
- ]),
7639
- key: "0"
7640
- } : void 0
7641
- ]), 1032, ["modelValue", "location", "offset", "target", "attach"]);
8207
+ return openBlock(), createElementBlock("div", _hoisted_1$g, [
8208
+ renderSlot(_ctx.$slots, "default")
8209
+ ]);
7642
8210
  };
7643
8211
  }
7644
8212
  });
7645
- const _hoisted_1$d = ["width", "height"];
7646
- const _hoisted_2$6 = ["onDblclick", "onMousedown", "onMousemove"];
7647
- const _hoisted_3$6 = { style: { "font-size": "12px", "text-wrap": "nowrap" } };
7648
- const _sfc_main$l = /* @__PURE__ */ defineComponent({
8213
+ const _hoisted_1$f = { class: "mce-layer__name" };
8214
+ const _hoisted_2$7 = { class: "mce-layer__action" };
8215
+ const _sfc_main$o = /* @__PURE__ */ defineComponent({
7649
8216
  ...{
8217
+ name: "MceLayer",
7650
8218
  inheritAttrs: false
7651
8219
  },
7652
- __name: "Ruler",
7653
- props: {
7654
- size: { default: 16 },
7655
- vertical: { type: Boolean },
7656
- zoom: { default: 1 },
7657
- position: { default: 0 },
7658
- unit: { default: 50 },
7659
- unitFractions: { default: () => [1, 2, 5, 10] },
7660
- selected: {},
7661
- pixelRatio: { default: window.devicePixelRatio || 1 },
7662
- refline: { type: Boolean },
7663
- axis: { type: Boolean },
7664
- labelFormat: { type: Function, default: (tick) => String(tick) }
7665
- },
7666
- setup(__props, { expose: __expose }) {
8220
+ __name: "Layer",
8221
+ props: /* @__PURE__ */ mergeModels({
8222
+ root: Boolean,
8223
+ node: {
8224
+ type: Object,
8225
+ required: true
8226
+ },
8227
+ active: Boolean,
8228
+ indent: {
8229
+ type: Number,
8230
+ default: 0
8231
+ }
8232
+ }, {
8233
+ "opened": { default: false },
8234
+ "openedModifiers": {}
8235
+ }),
8236
+ emits: ["update:opened"],
8237
+ setup(__props) {
7667
8238
  const props = __props;
7668
- const attrs = useAttrs();
7669
- const pixelRatio = computed(() => props.pixelRatio);
7670
- const tipText = ref();
7671
- const tipPos = ref({ x: 0, y: 0 });
7672
- const canvas = useTemplateRef("canvasTpl");
7673
- const offscreenCanvas = "OffscreenCanvas" in window ? new OffscreenCanvas(props.size, props.size) : document.createElement("canvas");
7674
- const ctx = offscreenCanvas.getContext("2d");
7675
- const box = ref();
7676
- const colors = reactive({
7677
- text: "#000",
7678
- border: "#000"
8239
+ const {
8240
+ isElement,
8241
+ isFrame,
8242
+ isVisible,
8243
+ setVisible,
8244
+ isLock,
8245
+ setLock,
8246
+ selection,
8247
+ nodes,
8248
+ nodeIndexMap,
8249
+ zoomTo,
8250
+ hoverElement,
8251
+ exec
8252
+ } = useEditor();
8253
+ const opened = useModel(__props, "opened");
8254
+ const dom = ref();
8255
+ const {
8256
+ selecting,
8257
+ sortedSelection
8258
+ } = useLayerItem({
8259
+ id: props.node.id,
8260
+ opened,
8261
+ node: computed(() => props.node),
8262
+ dom: computed(() => dom.value)
7679
8263
  });
7680
- function drawSelected() {
7681
- if (!props.selected?.width || !props.selected?.height)
7682
- return;
7683
- ctx.fillStyle = "#6165FD20";
7684
- const offset2 = props.vertical ? props.selected.top : props.selected.left;
7685
- const length = props.vertical ? props.selected.height : props.selected.width;
7686
- ctx.fillRect(offset2, 0, length, props.size);
7687
- }
7688
- function drawAxis(start2, end2, size, color) {
7689
- ctx.lineWidth = size;
7690
- ctx.strokeStyle = color;
7691
- ctx.beginPath();
7692
- ctx.moveTo(start2[0], start2[1]);
7693
- ctx.lineTo(end2[0], end2[1]);
7694
- ctx.stroke();
7695
- }
7696
- function drawTick(tick, len, direction = 1) {
7697
- const x1 = tick;
7698
- const y1 = props.size;
7699
- const x2 = tick;
7700
- const y2 = props.size - len * direction;
7701
- ctx.moveTo(x1, y1);
7702
- ctx.lineTo(x2, y2);
7703
- }
7704
- function drawText(content, tick, top, size) {
7705
- ctx.font = `${size}px sans-serif`;
7706
- ctx.textAlign = "left";
7707
- ctx.textBaseline = "bottom";
7708
- const x2 = tick;
7709
- const y2 = props.size - top;
7710
- ctx.save();
7711
- if (props.vertical) {
7712
- ctx.translate(0, props.size);
7713
- ctx.scale(1, -1);
7714
- }
7715
- ctx.fillText(content, x2, y2);
7716
- ctx.restore();
7717
- }
7718
- const unit = computed(() => {
7719
- const idealUnit = Math.max(props.unit / props.zoom, 1);
7720
- const unitFractions = props.unitFractions;
7721
- const exponent = Math.floor(Math.log10(idealUnit));
7722
- const fraction = idealUnit / 10 ** exponent;
7723
- let niceFraction = unitFractions[unitFractions.length - 1];
7724
- for (const cur of unitFractions) {
7725
- if (fraction <= cur) {
7726
- niceFraction = cur;
7727
- break;
7728
- }
8264
+ const isFrist = computed(() => sortedSelection.value[0]?.equal(props.node));
8265
+ const isLast = computed(() => {
8266
+ const last = sortedSelection.value[sortedSelection.value.length - 1];
8267
+ if (last) {
8268
+ if (last.equal(props.node)) {
8269
+ if (!opened.value || !props.node?.children.length)
8270
+ return true;
8271
+ } else if (last.equal(props.node?.parent)) ;
7729
8272
  }
7730
- return niceFraction * 10 ** exponent;
7731
- });
7732
- const start = computed(() => {
7733
- const value = props.position / props.zoom;
7734
- return Math.floor(value / unit.value) * unit.value;
7735
- });
7736
- const end = computed(() => {
7737
- const len = (props.vertical ? box.value?.height : box.value?.width) ?? 0;
7738
- const value = len / props.zoom;
7739
- return start.value + Math.ceil(value / unit.value) * unit.value;
8273
+ return false;
7740
8274
  });
7741
- function numToPx(num) {
7742
- return Math.round(num * props.zoom - props.position);
7743
- }
7744
- function pxToNum(px) {
7745
- return Math.round((px + props.position) / props.zoom);
7746
- }
7747
- function render2() {
7748
- const cvs = canvas.value;
7749
- if (!cvs || !offscreenCanvas.width || !offscreenCanvas.height)
7750
- return;
7751
- ctx.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
7752
- ctx.save();
7753
- ctx.scale(pixelRatio.value, pixelRatio.value);
7754
- if (props.vertical) {
7755
- ctx.scale(1, -1);
7756
- ctx.translate(0, 0);
7757
- ctx.rotate(-Math.PI / 2);
7758
- }
7759
- drawSelected();
7760
- if (props.axis) {
7761
- drawAxis(
7762
- [0, props.size],
7763
- [props.vertical ? cvs.height : cvs.width, props.size],
7764
- 2,
7765
- colors.border
7766
- );
7767
- }
7768
- const drawPrimary = (tick, label) => {
7769
- drawTick(tick, 10);
7770
- drawText(label, tick + 2, 4, 8);
7771
- };
7772
- const drawSecondary = (tick) => drawTick(tick, 4);
7773
- let inc = unit.value / 10;
7774
- inc = (inc > 0 ? 1 : -1) * Math.max(1, Math.abs(inc));
7775
- ctx.beginPath();
7776
- ctx.lineWidth = 1;
7777
- ctx.strokeStyle = colors.text;
7778
- ctx.fillStyle = colors.text;
7779
- for (let tick = start.value; tick <= end.value; tick += inc) {
7780
- if (tick % unit.value === 0) {
7781
- drawPrimary(numToPx(tick), props.labelFormat(tick));
8275
+ const isActive = computed(() => selection.value.some((v) => v.equal(props.node)));
8276
+ const inputDom = ref();
8277
+ const isHoverElement = computed(() => props.node?.equal(hoverElement.value));
8278
+ const hovering = ref(false);
8279
+ const editing = ref(false);
8280
+ const editValue = ref();
8281
+ const thumbnailIcon = computed(() => {
8282
+ const node = props.node;
8283
+ if (isFrame(node)) {
8284
+ return "$frame";
8285
+ } else if (node.children.length) {
8286
+ return "$group";
8287
+ } else if (isElement(node)) {
8288
+ if (node.foreground.isValid() && node.foreground.image) {
8289
+ return "$image";
7782
8290
  }
7783
- }
7784
- ctx.stroke();
7785
- ctx.beginPath();
7786
- ctx.lineWidth = 1;
7787
- ctx.strokeStyle = colors.border;
7788
- for (let tick = start.value; tick <= end.value; tick += inc) {
7789
- if (tick % unit.value === 0) ;
7790
- else if (tick % inc === 0) {
7791
- drawSecondary(numToPx(tick));
8291
+ if (node.text.isValid()) {
8292
+ return "$text";
7792
8293
  }
7793
8294
  }
7794
- ctx.stroke();
7795
- ctx.restore();
7796
- if ("transferToImageBitmap" in offscreenCanvas) {
7797
- cvs.getContext("bitmaprenderer").transferFromImageBitmap(offscreenCanvas.transferToImageBitmap());
7798
- } else {
7799
- const mainCtx = cvs.getContext("2d");
7800
- if (mainCtx) {
7801
- mainCtx.clearRect(0, 0, cvs.width, cvs.height);
7802
- mainCtx.drawImage(offscreenCanvas, 0, 0);
8295
+ return "$shape";
8296
+ });
8297
+ function onMousedown() {
8298
+ }
8299
+ function onClickExpand() {
8300
+ opened.value = !opened.value;
8301
+ }
8302
+ function onClickContent(e) {
8303
+ selecting.value = true;
8304
+ if (isElement(props.node)) {
8305
+ if (e.shiftKey) {
8306
+ const _nodes = [
8307
+ ...selection.value.filter((v) => !v.equal(props.node)),
8308
+ props.node
8309
+ ];
8310
+ let min;
8311
+ let max;
8312
+ _nodes.forEach((el) => {
8313
+ const index = nodeIndexMap.get(el.id);
8314
+ if (index !== void 0) {
8315
+ min = min === void 0 ? index : Math.min(min, index);
8316
+ max = max === void 0 ? index : Math.max(max, index);
8317
+ }
8318
+ });
8319
+ if (min !== void 0 && max !== void 0) {
8320
+ let _selection = nodes.value.slice(min, max + 1);
8321
+ const result = new Set(_selection.map((node) => node.id));
8322
+ const parents = /* @__PURE__ */ new Set();
8323
+ _selection.forEach((node) => node.parent && parents.add(node.parent));
8324
+ parents.forEach((parent) => {
8325
+ if (parent.children.every((ch) => result.has(ch.id))) {
8326
+ const ids = new Set(parent.children.map((ch) => ch.id));
8327
+ _selection = [
8328
+ ..._selection.filter((v) => !ids.has(v.id)),
8329
+ parent
8330
+ ];
8331
+ }
8332
+ });
8333
+ selection.value = _selection;
8334
+ }
8335
+ } else if (e.ctrlKey || e.metaKey) {
8336
+ const filtered = selection.value.filter((v) => !v.equal(props.node));
8337
+ if (filtered.length !== selection.value.length) {
8338
+ selection.value = filtered;
8339
+ } else {
8340
+ selection.value = [...filtered, props.node];
8341
+ }
8342
+ } else {
8343
+ selection.value = [props.node];
7803
8344
  }
7804
8345
  }
8346
+ nextTick().then(() => {
8347
+ selecting.value = false;
8348
+ });
7805
8349
  }
7806
- watch(
7807
- [canvas, () => props.zoom, () => props.position, () => props.selected],
7808
- () => {
7809
- render2();
7810
- },
7811
- { immediate: true, deep: true }
7812
- );
7813
- const resize = useDebounceFn(() => {
7814
- if (!canvas.value)
7815
- return;
7816
- const _box = canvas.value.parentElement.getBoundingClientRect();
7817
- offscreenCanvas.width = canvas.value.width = _box.width * pixelRatio.value;
7818
- offscreenCanvas.height = canvas.value.height = _box.height * pixelRatio.value;
7819
- canvas.value.style.width = `${_box.width}px`;
7820
- canvas.value.style.height = `${_box.height}px`;
7821
- box.value = _box;
7822
- render2();
7823
- }, 50);
7824
- onMounted(() => {
7825
- resize();
7826
- const dom = canvas.value;
7827
- if (dom) {
7828
- const style = window.getComputedStyle(dom);
7829
- colors.text = style.getPropertyValue("--text-color").trim();
7830
- colors.border = style.getPropertyValue("--border-color").trim();
8350
+ function onDblclickThumbnail(e) {
8351
+ e.stopPropagation();
8352
+ if (isElement(props.node)) {
8353
+ zoomTo("selection", {
8354
+ behavior: "smooth"
8355
+ });
7831
8356
  }
7832
- });
7833
- onBeforeUnmount(() => {
7834
- offscreenCanvas.width = 0;
7835
- offscreenCanvas.height = 0;
7836
- });
7837
- const savedLines = ref([]);
7838
- const tempLine = ref();
7839
- const lines = computed(() => {
7840
- const res = [...savedLines.value];
7841
- if (typeof tempLine.value === "number")
7842
- res.unshift(tempLine.value);
7843
- return res;
7844
- });
7845
- function getTick(e) {
7846
- return pxToNum(
7847
- props.vertical ? e.clientY - box.value.top : e.clientX - box.value.left
7848
- );
7849
8357
  }
7850
- function onMousedown(e) {
7851
- const tick = getTick(e);
7852
- if (props.refline) {
7853
- savedLines.value.push(tick);
7854
- }
8358
+ function onDblclickContent() {
8359
+ editing.value = true;
8360
+ editValue.value = props.node.name;
8361
+ nextTick().then(() => {
8362
+ inputDom.value?.focus();
8363
+ });
7855
8364
  }
7856
- function onMousemove(e, temp = false) {
7857
- const tick = getTick(e);
7858
- if (props.refline && temp) {
7859
- tempLine.value = tick;
8365
+ function onMouseenter() {
8366
+ if (isElement(props.node)) {
8367
+ hoverElement.value = props.node;
8368
+ hovering.value = true;
7860
8369
  }
7861
- tipText.value = props.labelFormat(tick);
7862
- tipPos.value = { x: e.clientX, y: e.clientY };
7863
8370
  }
7864
- function onLeave() {
7865
- tempLine.value = void 0;
7866
- tipText.value = void 0;
8371
+ function onMouseleave() {
8372
+ hoverElement.value = void 0;
8373
+ hovering.value = false;
7867
8374
  }
7868
- function onReflineDblclick(index) {
7869
- savedLines.value.splice(index, 1);
8375
+ function onContextmenu(e) {
8376
+ if (isElement(props.node)) {
8377
+ if (!selection.value.some((v) => v.equal(props.node))) {
8378
+ selection.value = [props.node];
8379
+ }
8380
+ exec("openContextMenu", e);
8381
+ }
7870
8382
  }
7871
- function onReflineMousedown(e, index) {
7872
- e.stopPropagation();
7873
- e.preventDefault();
7874
- const move = (e2) => {
7875
- savedLines.value[index] = getTick(e2);
7876
- };
7877
- const up = () => {
7878
- window.removeEventListener("mousemove", move);
7879
- window.removeEventListener("mouseup", up);
7880
- };
7881
- window.addEventListener("mousemove", move);
7882
- window.addEventListener("mouseup", up);
8383
+ function onInputBlur() {
8384
+ console.log("onInputBlur");
8385
+ editing.value = false;
8386
+ if (editValue.value) {
8387
+ props.node.name = editValue.value;
8388
+ editValue.value = void 0;
8389
+ }
7883
8390
  }
7884
- __expose({
7885
- box
7886
- });
7887
8391
  return (_ctx, _cache) => {
8392
+ const _component_MceLayer = resolveComponent("MceLayer");
7888
8393
  return openBlock(), createElementBlock(Fragment, null, [
7889
- withDirectives((openBlock(), createElementBlock("div", mergeProps({
7890
- class: ["mce-ruler", [
7891
- `mce-ruler--${props.vertical ? "vertical" : "horizontal"}`
7892
- ]],
7893
- style: { "--size": `${props.size}px` }
7894
- }, unref(attrs), {
8394
+ createElementVNode("div", {
8395
+ ref_key: "dom",
8396
+ ref: dom,
8397
+ class: normalizeClass(["mce-layer", [
8398
+ props.root && "mce-layer--root",
8399
+ (__props.active || isActive.value) && "mce-layer--active",
8400
+ isFrist.value && "mce-layer--first",
8401
+ isLast.value && "mce-layer--last",
8402
+ opened.value && "mce-layer--open",
8403
+ isHoverElement.value && "mce-layer--hover"
8404
+ ]]),
8405
+ style: normalizeStyle({
8406
+ "--indent-padding": `${props.indent * 16}px`
8407
+ }),
7895
8408
  onMousedown,
7896
- onMousemove: _cache[0] || (_cache[0] = ($event) => onMousemove($event, true)),
7897
- onMouseleave: onLeave
7898
- }), [
7899
- createElementVNode("canvas", {
7900
- ref: "canvasTpl",
7901
- class: "mce-ruler__canvas",
7902
- width: props.size,
7903
- height: props.size
7904
- }, null, 8, _hoisted_1$d)
7905
- ], 16)), [
7906
- [unref(vResizeObserver), unref(resize)]
7907
- ]),
7908
- (openBlock(true), createElementBlock(Fragment, null, renderList(lines.value, (item, index) => {
7909
- return openBlock(), createElementBlock("div", {
7910
- key: index,
7911
- class: normalizeClass(["mce-ruler-refline", {
7912
- "mce-ruler-refline--vertical": props.vertical,
7913
- "mce-ruler-refline--horizontal": !props.vertical,
7914
- "mce-ruler-refline--temp": item === tempLine.value
7915
- }]),
7916
- style: normalizeStyle({
7917
- [props.vertical ? "height" : "width"]: "0",
7918
- [props.vertical ? "width" : "height"]: "100%",
7919
- [props.vertical ? "top" : "left"]: `${numToPx(item)}px`,
7920
- [props.vertical ? "left" : "top"]: 0
7921
- }),
7922
- onDblclick: ($event) => onReflineDblclick(index),
7923
- onMousedown: ($event) => onReflineMousedown($event, index),
7924
- onMousemove: () => tipText.value = `${item}`,
7925
- onMouseleave: onLeave
7926
- }, null, 46, _hoisted_2$6);
7927
- }), 128)),
7928
- createVNode(_sfc_main$m, {
7929
- "model-value": !!tipText.value,
7930
- target: tipPos.value,
7931
- offset: 24
7932
- }, {
7933
- default: withCtx(() => [
7934
- createElementVNode("div", _hoisted_3$6, toDisplayString(tipText.value), 1)
8409
+ onMouseenter,
8410
+ onMouseleave,
8411
+ onContextmenu
8412
+ }, [
8413
+ createElementVNode("div", {
8414
+ class: "mce-layer__expand",
8415
+ onClick: onClickExpand
8416
+ }, [
8417
+ props.node.children.length ? (openBlock(), createBlock(_sfc_main$C, {
8418
+ key: 0,
8419
+ icon: "$arrowRight"
8420
+ })) : createCommentVNode("", true)
7935
8421
  ]),
7936
- _: 1
7937
- }, 8, ["model-value", "target"])
8422
+ createElementVNode("div", {
8423
+ class: "mce-layer__content",
8424
+ onClick: onClickContent,
8425
+ onDblclick: onDblclickContent
8426
+ }, [
8427
+ createElementVNode("div", {
8428
+ class: "mce-layer__thumbnail",
8429
+ onDblclick: onDblclickThumbnail
8430
+ }, [
8431
+ createVNode(_sfc_main$C, { icon: thumbnailIcon.value }, null, 8, ["icon"])
8432
+ ], 32),
8433
+ createElementVNode("div", _hoisted_1$f, [
8434
+ withDirectives(createElementVNode("input", {
8435
+ ref_key: "inputDom",
8436
+ ref: inputDom,
8437
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => editValue.value = $event),
8438
+ type: "text",
8439
+ class: "mce-layer__input",
8440
+ autofocus: "",
8441
+ onBlur: onInputBlur
8442
+ }, null, 544), [
8443
+ [vShow, editing.value],
8444
+ [vModelText, editValue.value]
8445
+ ]),
8446
+ createElementVNode("div", {
8447
+ style: normalizeStyle({ visibility: editing.value ? "hidden" : void 0 })
8448
+ }, toDisplayString(editValue.value || props.node.name || props.node.id), 5)
8449
+ ]),
8450
+ createElementVNode("div", _hoisted_2$7, [
8451
+ props.root ? (openBlock(), createElementBlock("div", {
8452
+ key: 0,
8453
+ class: normalizeClass(["mce-btn", {
8454
+ "mce-btn--hide": !hovering.value && !unref(isLock)(props.node)
8455
+ }]),
8456
+ onClick: _cache[1] || (_cache[1] = ($event) => unref(setLock)(props.node, !unref(isLock)(props.node)))
8457
+ }, [
8458
+ createVNode(_sfc_main$C, {
8459
+ icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
8460
+ }, null, 8, ["icon"])
8461
+ ], 2)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
8462
+ createVNode(_sfc_main$p, {
8463
+ class: normalizeClass({
8464
+ "mce-btn--hide": !hovering.value && !unref(isLock)(props.node)
8465
+ }),
8466
+ onClick: _cache[2] || (_cache[2] = withModifiers(($event) => unref(setLock)(props.node, !unref(isLock)(props.node)), ["prevent", "stop"]))
8467
+ }, {
8468
+ default: withCtx(() => [
8469
+ createVNode(_sfc_main$C, {
8470
+ icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
8471
+ }, null, 8, ["icon"])
8472
+ ]),
8473
+ _: 1
8474
+ }, 8, ["class"]),
8475
+ createVNode(_sfc_main$p, {
8476
+ class: normalizeClass({
8477
+ "mce-btn--hide": !hovering.value && unref(isVisible)(props.node)
8478
+ }),
8479
+ onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(setVisible)(props.node, !unref(isVisible)(props.node)), ["prevent", "stop"]))
8480
+ }, {
8481
+ default: withCtx(() => [
8482
+ createVNode(_sfc_main$C, {
8483
+ icon: unref(isVisible)(props.node) ? "$visible" : "$unvisible"
8484
+ }, null, 8, ["icon"])
8485
+ ]),
8486
+ _: 1
8487
+ }, 8, ["class"])
8488
+ ], 64))
8489
+ ])
8490
+ ], 32)
8491
+ ], 38),
8492
+ opened.value ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.node.children, (child, key) => {
8493
+ return openBlock(), createBlock(_component_MceLayer, {
8494
+ key,
8495
+ node: child,
8496
+ indent: __props.root ? props.indent : props.indent + 1,
8497
+ active: __props.active || isActive.value
8498
+ }, null, 8, ["node", "indent", "active"]);
8499
+ }), 128)) : createCommentVNode("", true)
7938
8500
  ], 64);
7939
8501
  };
7940
8502
  }
7941
8503
  });
7942
- const _hoisted_1$c = { class: "mce-rulers" };
7943
- const _sfc_main$k = /* @__PURE__ */ defineComponent({
7944
- ...{
7945
- inheritAttrs: false
7946
- },
7947
- __name: "Rulers",
8504
+ const _hoisted_1$e = { class: "mce-layers" };
8505
+ const _hoisted_2$6 = { class: "mce-layers__wrapper" };
8506
+ const _sfc_main$n = /* @__PURE__ */ defineComponent({
8507
+ __name: "Layers",
7948
8508
  setup(__props) {
7949
8509
  const {
7950
- camera,
7951
- getAabbInDrawboard,
7952
- selection
8510
+ root,
8511
+ selection,
8512
+ state,
8513
+ nodeIndexMap
7953
8514
  } = useEditor();
7954
- const activeAabb = computed(() => getAabbInDrawboard(selection.value));
8515
+ const sortedSelection = computed(() => {
8516
+ return selection.value.map((node) => {
8517
+ return {
8518
+ node,
8519
+ index: nodeIndexMap.get(node.id) ?? 0
8520
+ };
8521
+ }).sort((a, b) => a.index - b.index).map((v) => v.node);
8522
+ });
8523
+ const {
8524
+ selecting,
8525
+ openedItems,
8526
+ domItems
8527
+ } = createLayer({
8528
+ sortedSelection
8529
+ });
8530
+ watch(selection, (selection2) => {
8531
+ if (state.value === "selecting" || selecting.value) {
8532
+ return;
8533
+ }
8534
+ let last;
8535
+ selection2.forEach((node) => {
8536
+ node.findAncestor((ancestor) => {
8537
+ const opened = openedItems.get(ancestor.id);
8538
+ if (opened) {
8539
+ opened.value = true;
8540
+ }
8541
+ return false;
8542
+ });
8543
+ last = node;
8544
+ });
8545
+ if (last) {
8546
+ nextTick().then(() => {
8547
+ domItems.get(last.id)?.value?.scrollIntoView({
8548
+ block: "center"
8549
+ });
8550
+ });
8551
+ }
8552
+ });
7955
8553
  return (_ctx, _cache) => {
7956
- return openBlock(), createElementBlock("div", _hoisted_1$c, [
7957
- createVNode(_sfc_main$l, {
7958
- refline: "",
7959
- zoom: unref(camera).zoom.x,
7960
- position: unref(camera).position.x,
7961
- selected: activeAabb.value,
7962
- axis: "",
7963
- size: 16
7964
- }, null, 8, ["zoom", "position", "selected"]),
7965
- createVNode(_sfc_main$l, {
7966
- refline: "",
7967
- zoom: unref(camera).zoom.y,
7968
- position: unref(camera).position.y,
7969
- selected: activeAabb.value,
7970
- axis: "",
7971
- vertical: "",
7972
- size: 16
7973
- }, null, 8, ["zoom", "position", "selected"]),
7974
- _cache[0] || (_cache[0] = createElementVNode("div", { class: "mce-rulers__left-top" }, null, -1))
8554
+ return openBlock(), createElementBlock("div", _hoisted_1$e, [
8555
+ createElementVNode("div", _hoisted_2$6, [
8556
+ createVNode(_sfc_main$o, {
8557
+ root: true,
8558
+ node: unref(root),
8559
+ opened: true
8560
+ }, null, 8, ["node"])
8561
+ ])
7975
8562
  ]);
7976
8563
  };
7977
8564
  }
7978
8565
  });
7979
- const _hoisted_1$b = {
7980
- ref: "trackTplRef",
7981
- class: "mce-scrollbar__track"
8566
+ const _export_sfc = (sfc, props) => {
8567
+ const target = sfc.__vccOpts || sfc;
8568
+ for (const [key, val] of props) {
8569
+ target[key] = val;
8570
+ }
8571
+ return target;
7982
8572
  };
7983
- const _sfc_main$j = /* @__PURE__ */ defineComponent({
7984
- __name: "Scrollbar",
8573
+ const _sfc_main$m = {};
8574
+ const _hoisted_1$d = {
8575
+ class: "mce-made-with",
8576
+ href: "https://github.com/qq15725/mce",
8577
+ target: "_blank"
8578
+ };
8579
+ function _sfc_render$1(_ctx, _cache) {
8580
+ return openBlock(), createElementBlock("a", _hoisted_1$d, [..._cache[0] || (_cache[0] = [
8581
+ createElementVNode("div", null, "MADE WITH", -1),
8582
+ createElementVNode("div", null, "MCE", -1)
8583
+ ])]);
8584
+ }
8585
+ const MadeWith = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$1]]);
8586
+ const _sfc_main$l = /* @__PURE__ */ defineComponent({
8587
+ __name: "Tooltip",
7985
8588
  props: /* @__PURE__ */ mergeModels({
7986
- length: {},
7987
- vertical: { type: Boolean },
7988
- size: {},
7989
- offset: {}
8589
+ ...makeMceOverlayProps({
8590
+ location: "right",
8591
+ offset: 8
8592
+ })
7990
8593
  }, {
7991
- "modelValue": { required: true },
8594
+ "modelValue": { type: Boolean },
7992
8595
  "modelModifiers": {}
7993
8596
  }),
7994
- emits: /* @__PURE__ */ mergeModels(["scroll"], ["update:modelValue"]),
7995
- setup(__props, { emit: __emit }) {
8597
+ emits: ["update:modelValue"],
8598
+ setup(__props, { expose: __expose }) {
7996
8599
  const props = __props;
7997
- const emit = __emit;
7998
- const position = useModel(__props, "modelValue");
7999
- const track = useTemplateRef("trackTplRef");
8000
- const thumb = useTemplateRef("thumbTplRef");
8001
- const trackLength = ref(0);
8002
- const contentLength = computed(() => {
8003
- return props.length + trackLength.value + Math.abs(position.value) * 2;
8004
- });
8005
- const thumbLength = computed(() => {
8006
- return Math.max(0.05, Math.min(1, trackLength.value / contentLength.value));
8007
- });
8008
- const thumbPosition = computed(() => {
8009
- return (Math.abs(position.value) + position.value) / (contentLength.value - trackLength.value) * (1 - thumbLength.value);
8010
- });
8011
- const resize = useDebounceFn(() => {
8012
- const box = track.value?.getBoundingClientRect() ?? { width: 0, height: 0 };
8013
- trackLength.value = props.vertical ? box.height : box.width;
8014
- }, 50);
8015
- const lerp = (a, b, t) => a * (1 - t) + b * t;
8016
- const thumbToTrack = (thumbLength2, thumbPosition2) => lerp(thumbLength2 / 2, 1 - thumbLength2 / 2, thumbPosition2);
8017
- const start = computed(() => thumbToTrack(thumbLength.value, thumbPosition.value));
8018
- const end = computed(() => 1 - start.value - thumbLength.value);
8019
- const thumbTop = computed(() => props.vertical ? `${start.value * 100}%` : "0%");
8020
- const thumbBottom = computed(() => props.vertical ? `${end.value * 100}%` : "50%");
8021
- const thumbLeft = computed(() => props.vertical ? "0%" : `${start.value * 100}%`);
8022
- const thumbRight = computed(() => props.vertical ? "50%" : `${end.value * 100}%`);
8023
- function update(val) {
8024
- emit("scroll", val - position.value);
8025
- position.value = val;
8026
- }
8027
- function amount(val) {
8028
- update(position.value + val);
8600
+ const isActive = useModel(__props, "modelValue");
8601
+ const overlay = useTemplateRef("overlayTpl");
8602
+ function updateLocation() {
8603
+ overlay.value?.updateLocation();
8029
8604
  }
8030
- const isActive = ref(false);
8031
- watch(track, (track2, oldTrack) => {
8032
- function onMousedown(event) {
8033
- if (!thumb.value?.contains(event.target)) {
8034
- return;
8035
- }
8036
- isActive.value = true;
8037
- let last = event;
8038
- event.stopPropagation();
8039
- function onMousemove(event2) {
8040
- const offset2 = {
8041
- x: last.clientX - event2.clientX,
8042
- y: last.clientY - event2.clientY
8043
- };
8044
- last = event2;
8045
- amount((props.vertical ? offset2.y : offset2.x) / (trackLength.value * (1 - thumbLength.value)) * contentLength.value * -1);
8046
- }
8047
- function onMouseup() {
8048
- isActive.value = false;
8049
- window.removeEventListener("mousemove", onMousemove);
8050
- window.removeEventListener("mouseup", onMouseup);
8051
- }
8052
- window.addEventListener("mousemove", onMousemove);
8053
- window.addEventListener("mouseup", onMouseup);
8054
- }
8055
- oldTrack?.removeEventListener("mousedown", onMousedown);
8056
- track2?.addEventListener("mousedown", onMousedown);
8057
- });
8058
- return (_ctx, _cache) => {
8059
- return withDirectives((openBlock(), createElementBlock("div", {
8060
- class: normalizeClass(["mce-scrollbar", {
8061
- "mce-scrollbar--vertical": props.vertical,
8062
- "mce-scrollbar--horizontal": !props.vertical
8063
- }]),
8064
- style: normalizeStyle({
8065
- [props.vertical ? "height" : "width"]: `calc(100% - ${props.size + props.offset}px)`,
8066
- [props.vertical ? "width" : "height"]: `${props.size}px`,
8067
- [props.vertical ? "top" : "left"]: `${props.offset}px`
8068
- })
8605
+ __expose({
8606
+ updateLocation
8607
+ });
8608
+ return (_ctx, _cache) => {
8609
+ return openBlock(), createBlock(_sfc_main$B, {
8610
+ ref: "overlayTpl",
8611
+ modelValue: isActive.value,
8612
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isActive.value = $event),
8613
+ class: "mce-tooltip",
8614
+ location: props.location,
8615
+ offset: props.offset,
8616
+ target: props.target,
8617
+ attach: props.attach
8618
+ }, createSlots({
8619
+ default: withCtx(() => [
8620
+ isActive.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
8621
+ ]),
8622
+ _: 2
8069
8623
  }, [
8070
- createElementVNode("div", _hoisted_1$b, [
8071
- createElementVNode("div", {
8072
- ref: "thumbTplRef",
8073
- class: normalizeClass(["mce-scrollbar__thumb", {
8074
- "mce-scrollbar__thumb--active": isActive.value
8075
- }]),
8076
- style: normalizeStyle({
8077
- top: thumbTop.value,
8078
- bottom: thumbBottom.value,
8079
- left: thumbLeft.value,
8080
- right: thumbRight.value
8081
- })
8082
- }, null, 6)
8083
- ], 512)
8084
- ], 6)), [
8085
- [unref(vResizeObserver), unref(resize)]
8086
- ]);
8624
+ _ctx.$slots.activator ? {
8625
+ name: "activator",
8626
+ fn: withCtx((activatorProps) => [
8627
+ renderSlot(_ctx.$slots, "activator", normalizeProps(guardReactiveProps(activatorProps)))
8628
+ ]),
8629
+ key: "0"
8630
+ } : void 0
8631
+ ]), 1032, ["modelValue", "location", "offset", "target", "attach"]);
8087
8632
  };
8088
8633
  }
8089
8634
  });
8090
- const _sfc_main$i = /* @__PURE__ */ defineComponent({
8635
+ const _hoisted_1$c = ["width", "height"];
8636
+ const _hoisted_2$5 = ["onDblclick", "onMousedown", "onMousemove"];
8637
+ const _hoisted_3$5 = { style: { "font-size": "12px", "text-wrap": "nowrap" } };
8638
+ const _sfc_main$k = /* @__PURE__ */ defineComponent({
8091
8639
  ...{
8092
8640
  inheritAttrs: false
8093
8641
  },
8094
- __name: "Scrollbars",
8095
- props: {
8096
- infinite: { type: Boolean, default: true },
8097
- offset: { default: 0 },
8098
- size: { default: 8 }
8099
- },
8100
- setup(__props) {
8101
- const props = __props;
8102
- const {
8103
- camera,
8104
- viewAabb
8105
- } = useEditor();
8106
- return (_ctx, _cache) => {
8107
- return openBlock(), createElementBlock(Fragment, null, [
8108
- createVNode(_sfc_main$j, mergeProps(props, {
8109
- modelValue: unref(camera).position.y,
8110
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(camera).position.y = $event),
8111
- vertical: "",
8112
- length: unref(viewAabb).height * unref(camera).zoom.y
8113
- }), null, 16, ["modelValue", "length"]),
8114
- createVNode(_sfc_main$j, mergeProps(props, {
8115
- modelValue: unref(camera).position.x,
8116
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => unref(camera).position.x = $event),
8117
- length: unref(viewAabb).width * unref(camera).zoom.x
8118
- }), null, 16, ["modelValue", "length"])
8119
- ], 64);
8120
- };
8121
- }
8122
- });
8123
- const _hoisted_1$a = { class: "mce-transformable__svg" };
8124
- const _hoisted_2$5 = ["rx", "ry"];
8125
- const _hoisted_3$5 = {
8126
- key: 0,
8127
- class: "mce-transformable__diagonal",
8128
- x1: "100%",
8129
- y1: "0",
8130
- x2: "0",
8131
- y2: "100%"
8132
- };
8133
- const _hoisted_4$3 = {
8134
- key: 1,
8135
- class: "mce-transformable__diagonal",
8136
- x1: "0",
8137
- y1: "0",
8138
- x2: "100%",
8139
- y2: "100%"
8140
- };
8141
- const _hoisted_5$2 = ["x", "y", "width", "height", "aria-label"];
8142
- const _hoisted_6$2 = ["cx", "cy", "r", "aria-label"];
8143
- const _hoisted_7$2 = { "pointer-events": "all" };
8144
- const _hoisted_8$1 = ["x", "y", "width", "height", "aria-label", "cursor", "onPointerdown"];
8145
- const _hoisted_9$1 = {
8146
- "pointer-events": "all",
8147
- class: "mce-transformable__svg-slot"
8148
- };
8149
- const _hoisted_10$1 = {
8150
- key: 0,
8151
- class: "mce-transformable__tip"
8152
- };
8153
- const _sfc_main$h = /* @__PURE__ */ defineComponent({
8154
- __name: "Transformable",
8642
+ __name: "Ruler",
8155
8643
  props: {
8156
- tag: { default: "div" },
8157
- modelValue: {},
8158
- movable: { type: Boolean, default: true },
8159
- rotatable: { type: Boolean, default: true },
8160
- resizable: { type: Boolean, default: true },
8161
- adjustableBorderRadius: { type: Boolean, default: false },
8162
- threshold: { default: 0 },
8163
- resizeStrategy: {},
8164
- handleStrategy: {},
8165
- handleShape: { default: "rect" },
8166
- hideUi: { type: Boolean },
8167
- handles: { default: () => [
8168
- "move",
8169
- // resize
8170
- "resize-left",
8171
- "resize-top",
8172
- "resize-right",
8173
- "resize-bottom",
8174
- "resize-top-left",
8175
- "resize-top-right",
8176
- "resize-bottom-right",
8177
- "resize-bottom-left",
8178
- // border-radius
8179
- "border-radius-top-left",
8180
- "border-radius-top-right",
8181
- "border-radius-bottom-left",
8182
- "border-radius-bottom-right",
8183
- // rotate
8184
- "rotate-top-left",
8185
- "rotate-top-right",
8186
- "rotate-bottom-left",
8187
- "rotate-bottom-right"
8188
- ] },
8189
- initialSize: { type: Boolean },
8190
- borderStyle: {},
8191
- tipFormat: {}
8192
- },
8193
- emits: ["update:modelValue", "start", "move", "end"],
8194
- setup(__props, { expose: __expose, emit: __emit }) {
8195
- const props = __props;
8196
- const emit = __emit;
8197
- const cursors = {
8198
- "rotate-top-left": (angle) => createCursor("rotate", 360 + angle),
8199
- "rotate-top-right": (angle) => createCursor("rotate", 90 + angle),
8200
- "rotate-bottom-left": (angle) => createCursor("rotate", 270 + angle),
8201
- "rotate-bottom-right": (angle) => createCursor("rotate", 180 + angle),
8202
- "resize-left": (angle) => createCursor("resizeXy", 180 + angle),
8203
- "resize-top": (angle) => createCursor("resizeXy", 90 + angle),
8204
- "resize-right": (angle) => createCursor("resizeXy", 180 + angle),
8205
- "resize-bottom": (angle) => createCursor("resizeXy", 90 + angle),
8206
- "resize-top-left": (angle) => createCursor("resizeBevel", 90 + angle),
8207
- "resize-top-right": (angle) => createCursor("resizeBevel", 180 + angle),
8208
- "resize-bottom-right": (angle) => createCursor("resizeBevel", 90 + angle),
8209
- "resize-bottom-left": (angle) => createCursor("resizeBevel", 180 + angle)
8210
- };
8211
- const modelValue = useModel(props, "modelValue");
8212
- const model = computed({
8213
- get: () => {
8214
- let { left = 0, top = 0, width = 0, height = 0, rotate = 0, borderRadius = 0 } = modelValue.value ?? {};
8215
- if (Number.isNaN(Number(width)))
8216
- width = 0;
8217
- if (Number.isNaN(Number(height)))
8218
- height = 0;
8219
- return { left, top, width, height, rotate, borderRadius };
8220
- },
8221
- set: (val) => modelValue.value = val
8222
- });
8223
- const transforming = ref(false);
8224
- const activeHandle = ref();
8225
- const computedHandles = computed(() => {
8226
- const size = 8;
8227
- const { width = 0, height = 0, borderRadius } = model.value;
8228
- const center = { x: width / 2, y: height / 2 };
8229
- const shape = props.handleShape;
8230
- const lines = [
8231
- { type: "top", points: [[0, 0], [1, 0]] },
8232
- { type: "right", points: [[1, 0], [1, 1]] },
8233
- { type: "bottom", points: [[0, 1], [1, 1]] },
8234
- { type: "left", points: [[0, 0], [0, 1]] }
8235
- ];
8236
- const points = [
8237
- { type: "top", point: [0.5, 0] },
8238
- { type: "right", point: [1, 0.5] },
8239
- { type: "bottom", point: [0.5, 1] },
8240
- { type: "left", point: [0, 0.5] },
8241
- { type: "top-left", point: [0, 0] },
8242
- { type: "top-right", point: [1, 0] },
8243
- { type: "bottom-left", point: [0, 1] },
8244
- { type: "bottom-right", point: [1, 1] }
8245
- ];
8246
- const lineHandles = lines.map((item) => {
8247
- const [p1, p2] = item.points;
8248
- const minX = Math.min(p1[0], p2[0]) * width;
8249
- const maxX = Math.max(p1[0], p2[0]) * width;
8250
- const minY = Math.min(p1[1], p2[1]) * height;
8251
- const maxY = Math.max(p1[1], p2[1]) * height;
8252
- return {
8253
- type: item.type,
8254
- x: minX - size / 2,
8255
- y: minY - size / 2,
8256
- width: maxX - minX + size,
8257
- height: maxY - minY + size
8258
- };
8259
- });
8260
- const pointHandles = points.map((item) => {
8261
- return {
8262
- type: item.type,
8263
- shape,
8264
- x: item.point[0] * width - size / 2,
8265
- y: item.point[1] * height - size / 2,
8266
- width: size,
8267
- height: size
8268
- };
8269
- });
8270
- const diagonalPointHandles = pointHandles.filter((item) => item.type.split("-").length === 2);
8271
- const rotateHandles = diagonalPointHandles.map((item) => {
8272
- const sign = {
8273
- x: center.x - item.x > 0 ? 1 : -1,
8274
- y: center.y - item.y > 0 ? 1 : -1
8275
- };
8276
- return {
8277
- ...item,
8278
- shape: void 0,
8279
- type: `rotate-${item.type}`,
8280
- x: item.x - sign.x * size,
8281
- y: item.y - sign.y * size
8282
- };
8283
- });
8284
- const minSize = Math.min(width, height);
8285
- const borderRadiusHandles = props.adjustableBorderRadius ? diagonalPointHandles.map((item) => {
8286
- const sign = {
8287
- x: center.x - item.x > 0 ? 1 : -1,
8288
- y: center.y - item.y > 0 ? 1 : -1
8289
- };
8290
- const offset2 = minSize * 0.1;
8291
- return {
8292
- ...item,
8293
- shape: "circle",
8294
- type: `border-radius-${item.type}`,
8295
- x: item.x + sign.x * Math.min(width / 2, offset2 + borderRadius),
8296
- y: item.y + sign.y * Math.min(height / 2, offset2 + borderRadius)
8297
- };
8298
- }) : [];
8299
- let handles;
8300
- if (props.handleStrategy === "point") {
8301
- handles = [
8302
- // move
8303
- ...lineHandles.map((item) => ({ ...item, type: "move" })),
8304
- // resize
8305
- ...pointHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
8306
- // border-radius
8307
- ...borderRadiusHandles,
8308
- // rotate
8309
- ...rotateHandles
8310
- ];
8311
- } else {
8312
- handles = [
8313
- // resize
8314
- ...lineHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
8315
- ...diagonalPointHandles.map((item) => ({ ...item, type: `resize-${item.type}` })),
8316
- // border-radius
8317
- ...borderRadiusHandles,
8318
- // rotate
8319
- ...rotateHandles
8320
- ];
8644
+ size: { default: 16 },
8645
+ vertical: { type: Boolean },
8646
+ zoom: { default: 1 },
8647
+ position: { default: 0 },
8648
+ unit: { default: 50 },
8649
+ unitFractions: { default: () => [1, 2, 5, 10] },
8650
+ selected: {},
8651
+ pixelRatio: { default: window.devicePixelRatio || 1 },
8652
+ refline: { type: Boolean },
8653
+ axis: { type: Boolean },
8654
+ labelFormat: { type: Function, default: (tick) => String(tick) }
8655
+ },
8656
+ setup(__props, { expose: __expose }) {
8657
+ const props = __props;
8658
+ const attrs = useAttrs();
8659
+ const pixelRatio = computed(() => props.pixelRatio);
8660
+ const tipText = ref();
8661
+ const tipPos = ref({ x: 0, y: 0 });
8662
+ const canvas = useTemplateRef("canvasTpl");
8663
+ const offscreenCanvas = "OffscreenCanvas" in window ? new OffscreenCanvas(props.size, props.size) : document.createElement("canvas");
8664
+ const ctx = offscreenCanvas.getContext("2d");
8665
+ const box = ref();
8666
+ const colors = reactive({
8667
+ text: "#000",
8668
+ border: "#000"
8669
+ });
8670
+ function drawSelected() {
8671
+ if (!props.selected?.width || !props.selected?.height)
8672
+ return;
8673
+ ctx.fillStyle = "#6165FD20";
8674
+ const offset2 = props.vertical ? props.selected.top : props.selected.left;
8675
+ const length = props.vertical ? props.selected.height : props.selected.width;
8676
+ ctx.fillRect(offset2, 0, length, props.size);
8677
+ }
8678
+ function drawAxis(start2, end2, size, color) {
8679
+ ctx.lineWidth = size;
8680
+ ctx.strokeStyle = color;
8681
+ ctx.beginPath();
8682
+ ctx.moveTo(start2[0], start2[1]);
8683
+ ctx.lineTo(end2[0], end2[1]);
8684
+ ctx.stroke();
8685
+ }
8686
+ function drawTick(tick, len, direction = 1) {
8687
+ const x1 = tick;
8688
+ const y1 = props.size;
8689
+ const x2 = tick;
8690
+ const y2 = props.size - len * direction;
8691
+ ctx.moveTo(x1, y1);
8692
+ ctx.lineTo(x2, y2);
8693
+ }
8694
+ function drawText(content, tick, top, size) {
8695
+ ctx.font = `${size}px sans-serif`;
8696
+ ctx.textAlign = "left";
8697
+ ctx.textBaseline = "bottom";
8698
+ const x2 = tick;
8699
+ const y2 = props.size - top;
8700
+ ctx.save();
8701
+ if (props.vertical) {
8702
+ ctx.translate(0, props.size);
8703
+ ctx.scale(1, -1);
8321
8704
  }
8322
- return handles.filter((handle) => {
8323
- if (props.handles.includes(handle.type)) {
8324
- return !(!props.resizable && handle.type.startsWith("resize") || !props.rotatable && handle.type.startsWith("rotate") || !props.movable && handle.type === "move");
8705
+ ctx.fillText(content, x2, y2);
8706
+ ctx.restore();
8707
+ }
8708
+ const unit = computed(() => {
8709
+ const idealUnit = Math.max(props.unit / props.zoom, 1);
8710
+ const unitFractions = props.unitFractions;
8711
+ const exponent = Math.floor(Math.log10(idealUnit));
8712
+ const fraction = idealUnit / 10 ** exponent;
8713
+ let niceFraction = unitFractions[unitFractions.length - 1];
8714
+ for (const cur of unitFractions) {
8715
+ if (fraction <= cur) {
8716
+ niceFraction = cur;
8717
+ break;
8325
8718
  }
8326
- return false;
8327
- }).map((anchor) => {
8328
- anchor.width = Math.max(anchor.width, 0);
8329
- anchor.height = Math.max(anchor.height, 0);
8330
- return anchor;
8331
- });
8719
+ }
8720
+ return niceFraction * 10 ** exponent;
8332
8721
  });
8333
- const handlesRef = ref();
8334
- const sizeStyle = computed(() => {
8335
- const { width = 0, height = 0 } = model.value;
8336
- return {
8337
- width: props.initialSize && !width ? void 0 : `${width}px`,
8338
- height: props.initialSize && !height ? void 0 : `${height}px`
8339
- };
8722
+ const start = computed(() => {
8723
+ const value = props.position / props.zoom;
8724
+ return Math.floor(value / unit.value) * unit.value;
8340
8725
  });
8341
- const style = computed(() => {
8342
- const { left = 0, top = 0, rotate = 0 } = model.value;
8343
- const radian = rotate * Math.PI / 180;
8344
- const cos = Math.cos(radian);
8345
- const sin = Math.sin(radian);
8346
- return {
8347
- ...sizeStyle.value,
8348
- transform: `matrix(${cos}, ${sin}, ${-sin}, ${cos}, ${left}, ${top})`
8349
- };
8726
+ const end = computed(() => {
8727
+ const len = (props.vertical ? box.value?.height : box.value?.width) ?? 0;
8728
+ const value = len / props.zoom;
8729
+ return start.value + Math.ceil(value / unit.value) * unit.value;
8350
8730
  });
8351
- const tip = computed(() => props.tipFormat?.("size"));
8352
- function start(event, index) {
8353
- if (event && event.button !== void 0 && event.button !== 0) {
8354
- return false;
8355
- }
8356
- event?.preventDefault();
8357
- event?.stopPropagation();
8358
- const { left, top, width, height, rotate, borderRadius } = model.value;
8359
- let aspectRatio = 0;
8360
- if (width && height) {
8361
- aspectRatio = width / height;
8362
- }
8363
- const handle = index === void 0 ? { type: "move", x: 0, y: 0, width: 0, height: 0 } : computedHandles.value[index];
8364
- activeHandle.value = handle.type;
8365
- const isMove = handle.type === "move";
8366
- const isRotate = handle.type.startsWith("rotate");
8367
- const isBorderRadius = handle.type.startsWith("border-radius");
8368
- const isHorizontal = handle.type === "resize-left" || handle.type === "resize-right";
8369
- const isHorizontalVertical = handle.type.split("-").length === 2;
8370
- const centerPoint = {
8371
- x: left + width / 2,
8372
- y: top + height / 2
8373
- };
8374
- const startPoint = {
8375
- x: left,
8376
- y: top
8377
- };
8378
- if (!isMove) {
8379
- startPoint.x += handle.x + handle.width / 2;
8380
- startPoint.y += handle.y + handle.height / 2;
8381
- }
8382
- const sign = {
8383
- x: startPoint.x - centerPoint.x > 0 ? 1 : -1,
8384
- y: startPoint.y - centerPoint.y > 0 ? 1 : -1
8385
- };
8386
- const rotatedStartPoint = rotatePoint(startPoint, centerPoint, rotate);
8387
- const rotatedSymmetricPoint = {
8388
- x: centerPoint.x * 2 - rotatedStartPoint.x,
8389
- y: centerPoint.y * 2 - rotatedStartPoint.y
8390
- };
8391
- const startAngle = Math.atan2(
8392
- rotatedStartPoint.y - centerPoint.y,
8393
- rotatedStartPoint.x - centerPoint.x
8394
- ) / (Math.PI / 180);
8395
- let startClientPoint = event ? { x: event.clientX, y: event.clientY } : void 0;
8396
- function startTransform() {
8397
- transforming.value = true;
8398
- emit("start", model.value);
8399
- }
8400
- if (!props.threshold && !transforming.value) {
8401
- startTransform();
8731
+ function numToPx(num) {
8732
+ return Math.round(num * props.zoom - props.position);
8733
+ }
8734
+ function pxToNum(px) {
8735
+ return Math.round((px + props.position) / props.zoom);
8736
+ }
8737
+ function render2() {
8738
+ const cvs = canvas.value;
8739
+ if (!cvs || !offscreenCanvas.width || !offscreenCanvas.height)
8740
+ return;
8741
+ ctx.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
8742
+ ctx.save();
8743
+ ctx.scale(pixelRatio.value, pixelRatio.value);
8744
+ if (props.vertical) {
8745
+ ctx.scale(1, -1);
8746
+ ctx.translate(0, 0);
8747
+ ctx.rotate(-Math.PI / 2);
8402
8748
  }
8403
- function onMove(event2) {
8404
- const updated = {};
8405
- if (!startClientPoint) {
8406
- startClientPoint = { x: event2.clientX, y: event2.clientY };
8407
- }
8408
- const rotatedOffset = {
8409
- x: event2.clientX - startClientPoint.x,
8410
- y: event2.clientY - startClientPoint.y
8411
- };
8412
- if (!transforming.value) {
8413
- if (Math.abs(rotatedOffset.x) < props.threshold && Math.abs(rotatedOffset.y) < props.threshold) {
8414
- return;
8415
- }
8416
- startTransform();
8417
- }
8418
- const rotatedCurrentPoint = {
8419
- x: rotatedStartPoint.x + rotatedOffset.x,
8420
- y: rotatedStartPoint.y + rotatedOffset.y
8421
- };
8422
- if (isMove) {
8423
- if (props.movable) {
8424
- updated.left = startPoint.x + rotatedOffset.x;
8425
- updated.top = startPoint.y + rotatedOffset.y;
8426
- }
8427
- } else if (isRotate) {
8428
- if (props.rotatable) {
8429
- const endAngle = Math.atan2(
8430
- rotatedCurrentPoint.y - centerPoint.y,
8431
- rotatedCurrentPoint.x - centerPoint.x
8432
- ) / (Math.PI / 180);
8433
- updated.rotate = (rotate + endAngle - startAngle + 360) % 360;
8434
- }
8435
- } else if (isBorderRadius) {
8436
- const offset2 = rotatePoint(rotatedOffset, { x: 0, y: 0 }, -rotate);
8437
- const _offset = Math.abs(offset2.x) < Math.abs(offset2.y) ? -sign.x * offset2.x : -sign.y * offset2.y * aspectRatio;
8438
- updated.borderRadius = Math.min(
8439
- Math.max(0, borderRadius + _offset),
8440
- Math.min(width / 2, height / 2)
8441
- );
8442
- } else if (isHorizontalVertical) {
8443
- const currentPoint = rotatePoint(rotatedCurrentPoint, centerPoint, -rotate);
8444
- const newCurrentPoint = isHorizontal ? { x: currentPoint.x, y: startPoint.y } : { x: startPoint.x, y: currentPoint.y };
8445
- const newRotatedCurrentPoint = rotatePoint(newCurrentPoint, centerPoint, rotate);
8446
- const distance = Math.abs(getDistance(newRotatedCurrentPoint, rotatedSymmetricPoint));
8447
- if (isHorizontal) {
8448
- updated.width = distance;
8449
- if (props.resizeStrategy === "lockAspectRatio" && aspectRatio) {
8450
- updated.height = distance / aspectRatio;
8451
- } else {
8452
- updated.height = height;
8453
- }
8454
- } else {
8455
- updated.height = distance;
8456
- if (props.resizeStrategy === "lockAspectRatio" && aspectRatio) {
8457
- updated.width = distance * aspectRatio;
8458
- } else {
8459
- updated.width = width;
8460
- }
8461
- }
8462
- const newCenterPoint = getMidpoint(newRotatedCurrentPoint, rotatedSymmetricPoint);
8463
- updated.left = newCenterPoint.x - updated.width / 2;
8464
- updated.top = newCenterPoint.y - updated.height / 2;
8465
- } else {
8466
- let newRotatedCurrentPoint;
8467
- if ((props.resizeStrategy === "lockAspectRatio" || props.resizeStrategy === "lockAspectRatioDiagonal") && aspectRatio) {
8468
- const offset2 = rotatePoint(rotatedOffset, { x: 0, y: 0 }, -rotate);
8469
- const _offset = Math.abs(offset2.x) < Math.abs(offset2.y) ? sign.x * offset2.x : sign.y * offset2.y * aspectRatio;
8470
- newRotatedCurrentPoint = rotatePoint(
8471
- {
8472
- x: startPoint.x + sign.x * _offset,
8473
- y: startPoint.y + sign.y * _offset / aspectRatio
8474
- },
8475
- centerPoint,
8476
- rotate
8477
- );
8478
- } else {
8479
- newRotatedCurrentPoint = rotatedCurrentPoint;
8480
- }
8481
- const newCenterPoint = getMidpoint(newRotatedCurrentPoint, rotatedSymmetricPoint);
8482
- const points = [
8483
- rotatePoint(newRotatedCurrentPoint, newCenterPoint, -rotate),
8484
- rotatePoint(rotatedSymmetricPoint, newCenterPoint, -rotate)
8485
- ];
8486
- const [minX, maxX] = points[0].x > points[1].x ? [points[1].x, points[0].x] : [points[0].x, points[1].x];
8487
- const [minY, maxY] = points[0].y > points[1].y ? [points[1].y, points[0].y] : [points[0].y, points[1].y];
8488
- updated.width = maxX - minX;
8489
- updated.height = maxY - minY;
8490
- updated.left = minX;
8491
- updated.top = minY;
8749
+ drawSelected();
8750
+ if (props.axis) {
8751
+ drawAxis(
8752
+ [0, props.size],
8753
+ [props.vertical ? cvs.height : cvs.width, props.size],
8754
+ 2,
8755
+ colors.border
8756
+ );
8757
+ }
8758
+ const drawPrimary = (tick, label) => {
8759
+ drawTick(tick, 10);
8760
+ drawText(label, tick + 2, 4, 8);
8761
+ };
8762
+ const drawSecondary = (tick) => drawTick(tick, 4);
8763
+ let inc = unit.value / 10;
8764
+ inc = (inc > 0 ? 1 : -1) * Math.max(1, Math.abs(inc));
8765
+ ctx.beginPath();
8766
+ ctx.lineWidth = 1;
8767
+ ctx.strokeStyle = colors.text;
8768
+ ctx.fillStyle = colors.text;
8769
+ for (let tick = start.value; tick <= end.value; tick += inc) {
8770
+ if (tick % unit.value === 0) {
8771
+ drawPrimary(numToPx(tick), props.labelFormat(tick));
8492
8772
  }
8493
- if ("width" in updated && updated.width <= 0 || "height" in updated && updated.height <= 0) {
8494
- return;
8773
+ }
8774
+ ctx.stroke();
8775
+ ctx.beginPath();
8776
+ ctx.lineWidth = 1;
8777
+ ctx.strokeStyle = colors.border;
8778
+ for (let tick = start.value; tick <= end.value; tick += inc) {
8779
+ if (tick % unit.value === 0) ;
8780
+ else if (tick % inc === 0) {
8781
+ drawSecondary(numToPx(tick));
8495
8782
  }
8496
- const oldValue = { ...model.value };
8497
- const newValue = { ...model.value, ...updated };
8498
- model.value = newValue;
8499
- emit("move", newValue, oldValue);
8500
8783
  }
8501
- function onEnd() {
8502
- window.removeEventListener("pointermove", onMove);
8503
- window.removeEventListener("pointerup", onEnd, true);
8504
- transforming.value = false;
8505
- activeHandle.value = void 0;
8506
- emit("end", model.value);
8784
+ ctx.stroke();
8785
+ ctx.restore();
8786
+ if ("transferToImageBitmap" in offscreenCanvas) {
8787
+ cvs.getContext("bitmaprenderer").transferFromImageBitmap(offscreenCanvas.transferToImageBitmap());
8788
+ } else {
8789
+ const mainCtx = cvs.getContext("2d");
8790
+ if (mainCtx) {
8791
+ mainCtx.clearRect(0, 0, cvs.width, cvs.height);
8792
+ mainCtx.drawImage(offscreenCanvas, 0, 0);
8793
+ }
8507
8794
  }
8508
- window.addEventListener("pointermove", onMove);
8509
- window.addEventListener("pointerup", onEnd, true);
8510
- return true;
8511
8795
  }
8512
- const cursorMap = {
8513
- 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"/>',
8514
- 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"/>',
8515
- 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"/>'
8516
- };
8517
- function createCursor(type, angle) {
8518
- const path = cursorMap[type];
8519
- 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, "'");
8796
+ watch(
8797
+ [canvas, () => props.zoom, () => props.position, () => props.selected],
8798
+ () => {
8799
+ render2();
8800
+ },
8801
+ { immediate: true, deep: true }
8802
+ );
8803
+ const resize = useDebounceFn(() => {
8804
+ if (!canvas.value)
8805
+ return;
8806
+ const _box = canvas.value.parentElement.getBoundingClientRect();
8807
+ offscreenCanvas.width = canvas.value.width = _box.width * pixelRatio.value;
8808
+ offscreenCanvas.height = canvas.value.height = _box.height * pixelRatio.value;
8809
+ canvas.value.style.width = `${_box.width}px`;
8810
+ canvas.value.style.height = `${_box.height}px`;
8811
+ box.value = _box;
8812
+ render2();
8813
+ }, 50);
8814
+ onMounted(() => {
8815
+ resize();
8816
+ const dom = canvas.value;
8817
+ if (dom) {
8818
+ const style = window.getComputedStyle(dom);
8819
+ colors.text = style.getPropertyValue("--text-color").trim();
8820
+ colors.border = style.getPropertyValue("--border-color").trim();
8821
+ }
8822
+ });
8823
+ onBeforeUnmount(() => {
8824
+ offscreenCanvas.width = 0;
8825
+ offscreenCanvas.height = 0;
8826
+ });
8827
+ const savedLines = ref([]);
8828
+ const tempLine = ref();
8829
+ const lines = computed(() => {
8830
+ const res = [...savedLines.value];
8831
+ if (typeof tempLine.value === "number")
8832
+ res.unshift(tempLine.value);
8833
+ return res;
8834
+ });
8835
+ function getTick(e) {
8836
+ return pxToNum(
8837
+ props.vertical ? e.clientY - box.value.top : e.clientX - box.value.left
8838
+ );
8520
8839
  }
8521
- function getCursor(type) {
8522
- if (type === "move")
8523
- return "move";
8524
- const create = cursors[type];
8525
- if (!create) {
8526
- return "default";
8840
+ function onMousedown(e) {
8841
+ const tick = getTick(e);
8842
+ if (props.refline) {
8843
+ savedLines.value.push(tick);
8527
8844
  }
8528
- return `url("data:image/svg+xml,${create(model.value.rotate ?? 0)}") 16 16, pointer`;
8529
8845
  }
8530
- function rotatePoint(point, origin, angle) {
8531
- const radian = angle * Math.PI / 180;
8532
- const cos = Math.cos(radian);
8533
- const sin = Math.sin(radian);
8534
- return {
8535
- x: (point.x - origin.x) * cos - (point.y - origin.y) * sin + origin.x,
8536
- y: (point.x - origin.x) * sin + (point.y - origin.y) * cos + origin.y
8537
- };
8846
+ function onMousemove(e, temp = false) {
8847
+ const tick = getTick(e);
8848
+ if (props.refline && temp) {
8849
+ tempLine.value = tick;
8850
+ }
8851
+ tipText.value = props.labelFormat(tick);
8852
+ tipPos.value = { x: e.clientX, y: e.clientY };
8538
8853
  }
8539
- function getMidpoint(point1, point2) {
8540
- return {
8541
- x: (point2.x + point1.x) / 2,
8542
- y: (point2.y + point1.y) / 2
8854
+ function onLeave() {
8855
+ tempLine.value = void 0;
8856
+ tipText.value = void 0;
8857
+ }
8858
+ function onReflineDblclick(index) {
8859
+ savedLines.value.splice(index, 1);
8860
+ }
8861
+ function onReflineMousedown(e, index) {
8862
+ e.stopPropagation();
8863
+ e.preventDefault();
8864
+ const move = (e2) => {
8865
+ savedLines.value[index] = getTick(e2);
8866
+ };
8867
+ const up = () => {
8868
+ window.removeEventListener("mousemove", move);
8869
+ window.removeEventListener("mouseup", up);
8543
8870
  };
8871
+ window.addEventListener("mousemove", move);
8872
+ window.addEventListener("mouseup", up);
8873
+ }
8874
+ __expose({
8875
+ box
8876
+ });
8877
+ return (_ctx, _cache) => {
8878
+ return openBlock(), createElementBlock(Fragment, null, [
8879
+ withDirectives((openBlock(), createElementBlock("div", mergeProps({
8880
+ class: ["mce-ruler", [
8881
+ `mce-ruler--${props.vertical ? "vertical" : "horizontal"}`
8882
+ ]],
8883
+ style: { "--size": `${props.size}px` }
8884
+ }, unref(attrs), {
8885
+ onMousedown,
8886
+ onMousemove: _cache[0] || (_cache[0] = ($event) => onMousemove($event, true)),
8887
+ onMouseleave: onLeave
8888
+ }), [
8889
+ createElementVNode("canvas", {
8890
+ ref: "canvasTpl",
8891
+ class: "mce-ruler__canvas",
8892
+ width: props.size,
8893
+ height: props.size
8894
+ }, null, 8, _hoisted_1$c)
8895
+ ], 16)), [
8896
+ [unref(vResizeObserver), unref(resize)]
8897
+ ]),
8898
+ (openBlock(true), createElementBlock(Fragment, null, renderList(lines.value, (item, index) => {
8899
+ return openBlock(), createElementBlock("div", {
8900
+ key: index,
8901
+ class: normalizeClass(["mce-ruler-refline", {
8902
+ "mce-ruler-refline--vertical": props.vertical,
8903
+ "mce-ruler-refline--horizontal": !props.vertical,
8904
+ "mce-ruler-refline--temp": item === tempLine.value
8905
+ }]),
8906
+ style: normalizeStyle({
8907
+ [props.vertical ? "height" : "width"]: "0",
8908
+ [props.vertical ? "width" : "height"]: "100%",
8909
+ [props.vertical ? "top" : "left"]: `${numToPx(item)}px`,
8910
+ [props.vertical ? "left" : "top"]: 0
8911
+ }),
8912
+ onDblclick: ($event) => onReflineDblclick(index),
8913
+ onMousedown: ($event) => onReflineMousedown($event, index),
8914
+ onMousemove: () => tipText.value = `${item}`,
8915
+ onMouseleave: onLeave
8916
+ }, null, 46, _hoisted_2$5);
8917
+ }), 128)),
8918
+ createVNode(_sfc_main$l, {
8919
+ "model-value": !!tipText.value,
8920
+ target: tipPos.value,
8921
+ offset: 24
8922
+ }, {
8923
+ default: withCtx(() => [
8924
+ createElementVNode("div", _hoisted_3$5, toDisplayString(tipText.value), 1)
8925
+ ]),
8926
+ _: 1
8927
+ }, 8, ["model-value", "target"])
8928
+ ], 64);
8929
+ };
8930
+ }
8931
+ });
8932
+ const _hoisted_1$b = { class: "mce-rulers" };
8933
+ const _sfc_main$j = /* @__PURE__ */ defineComponent({
8934
+ ...{
8935
+ inheritAttrs: false
8936
+ },
8937
+ __name: "Rulers",
8938
+ setup(__props) {
8939
+ const {
8940
+ camera,
8941
+ getAabbInDrawboard,
8942
+ selection
8943
+ } = useEditor();
8944
+ const activeAabb = computed(() => getAabbInDrawboard(selection.value));
8945
+ return (_ctx, _cache) => {
8946
+ return openBlock(), createElementBlock("div", _hoisted_1$b, [
8947
+ createVNode(_sfc_main$k, {
8948
+ refline: "",
8949
+ zoom: unref(camera).zoom.x,
8950
+ position: unref(camera).position.x,
8951
+ selected: activeAabb.value,
8952
+ axis: "",
8953
+ size: 16
8954
+ }, null, 8, ["zoom", "position", "selected"]),
8955
+ createVNode(_sfc_main$k, {
8956
+ refline: "",
8957
+ zoom: unref(camera).zoom.y,
8958
+ position: unref(camera).position.y,
8959
+ selected: activeAabb.value,
8960
+ axis: "",
8961
+ vertical: "",
8962
+ size: 16
8963
+ }, null, 8, ["zoom", "position", "selected"]),
8964
+ _cache[0] || (_cache[0] = createElementVNode("div", { class: "mce-rulers__left-top" }, null, -1))
8965
+ ]);
8966
+ };
8967
+ }
8968
+ });
8969
+ const _hoisted_1$a = {
8970
+ ref: "trackTplRef",
8971
+ class: "mce-scrollbar__track"
8972
+ };
8973
+ const _sfc_main$i = /* @__PURE__ */ defineComponent({
8974
+ __name: "Scrollbar",
8975
+ props: /* @__PURE__ */ mergeModels({
8976
+ length: {},
8977
+ vertical: { type: Boolean },
8978
+ size: {},
8979
+ offset: {}
8980
+ }, {
8981
+ "modelValue": { required: true },
8982
+ "modelModifiers": {}
8983
+ }),
8984
+ emits: /* @__PURE__ */ mergeModels(["scroll"], ["update:modelValue"]),
8985
+ setup(__props, { emit: __emit }) {
8986
+ const props = __props;
8987
+ const emit = __emit;
8988
+ const position = useModel(__props, "modelValue");
8989
+ const track = useTemplateRef("trackTplRef");
8990
+ const thumb = useTemplateRef("thumbTplRef");
8991
+ const trackLength = ref(0);
8992
+ const contentLength = computed(() => {
8993
+ return props.length + trackLength.value + Math.abs(position.value) * 2;
8994
+ });
8995
+ const thumbLength = computed(() => {
8996
+ return Math.max(0.05, Math.min(1, trackLength.value / contentLength.value));
8997
+ });
8998
+ const thumbPosition = computed(() => {
8999
+ return (Math.abs(position.value) + position.value) / (contentLength.value - trackLength.value) * (1 - thumbLength.value);
9000
+ });
9001
+ const resize = useDebounceFn(() => {
9002
+ const box = track.value?.getBoundingClientRect() ?? { width: 0, height: 0 };
9003
+ trackLength.value = props.vertical ? box.height : box.width;
9004
+ }, 50);
9005
+ const lerp = (a, b, t) => a * (1 - t) + b * t;
9006
+ const thumbToTrack = (thumbLength2, thumbPosition2) => lerp(thumbLength2 / 2, 1 - thumbLength2 / 2, thumbPosition2);
9007
+ const start = computed(() => thumbToTrack(thumbLength.value, thumbPosition.value));
9008
+ const end = computed(() => 1 - start.value - thumbLength.value);
9009
+ const thumbTop = computed(() => props.vertical ? `${start.value * 100}%` : "0%");
9010
+ const thumbBottom = computed(() => props.vertical ? `${end.value * 100}%` : "50%");
9011
+ const thumbLeft = computed(() => props.vertical ? "0%" : `${start.value * 100}%`);
9012
+ const thumbRight = computed(() => props.vertical ? "50%" : `${end.value * 100}%`);
9013
+ function update(val) {
9014
+ emit("scroll", val - position.value);
9015
+ position.value = val;
8544
9016
  }
8545
- function getDistance(point1, point2) {
8546
- const dx = point2.x - point1.x;
8547
- const dy = point2.y - point1.y;
8548
- return (dx + dy >= 0 ? 1 : -1) * Math.sqrt(dx * dx + dy * dy);
9017
+ function amount(val) {
9018
+ update(position.value + val);
8549
9019
  }
8550
- onMounted(async () => {
8551
- const vm = getCurrentInstance();
8552
- const root = vm?.proxy?.$el;
8553
- if (root && props.initialSize) {
8554
- await nextTick();
8555
- let width;
8556
- let height;
8557
- const style2 = getComputedStyle(root);
8558
- if (style2.width.endsWith("px") && style2.height.endsWith("px")) {
8559
- width = Number(style2.width.replace("px", ""));
8560
- height = Number(style2.height.replace("px", ""));
8561
- } else {
8562
- ({ width, height } = root.getBoundingClientRect());
9020
+ const isActive = ref(false);
9021
+ watch(track, (track2, oldTrack) => {
9022
+ function onMousedown(event) {
9023
+ if (!thumb.value?.contains(event.target)) {
9024
+ return;
8563
9025
  }
8564
- if (width && height) {
8565
- model.value = { ...model.value, width, height };
8566
- } else if ("ResizeObserver" in globalThis) {
8567
- const observer = new ResizeObserver(([entry]) => {
8568
- if (entry.contentRect.width && entry.contentRect.height) {
8569
- model.value = {
8570
- ...model.value,
8571
- width: entry.contentRect.width,
8572
- height: entry.contentRect.height
8573
- };
8574
- observer.unobserve(root);
8575
- }
8576
- });
8577
- observer.observe(root);
9026
+ isActive.value = true;
9027
+ let last = event;
9028
+ event.stopPropagation();
9029
+ function onMousemove(event2) {
9030
+ const offset2 = {
9031
+ x: last.clientX - event2.clientX,
9032
+ y: last.clientY - event2.clientY
9033
+ };
9034
+ last = event2;
9035
+ amount((props.vertical ? offset2.y : offset2.x) / (trackLength.value * (1 - thumbLength.value)) * contentLength.value * -1);
9036
+ }
9037
+ function onMouseup() {
9038
+ isActive.value = false;
9039
+ window.removeEventListener("mousemove", onMousemove);
9040
+ window.removeEventListener("mouseup", onMouseup);
8578
9041
  }
9042
+ window.addEventListener("mousemove", onMousemove);
9043
+ window.addEventListener("mouseup", onMouseup);
8579
9044
  }
8580
- });
8581
- __expose({
8582
- start,
8583
- activeHandle,
8584
- transforming
9045
+ oldTrack?.removeEventListener("mousedown", onMousedown);
9046
+ track2?.addEventListener("mousedown", onMousedown);
8585
9047
  });
8586
9048
  return (_ctx, _cache) => {
8587
- return openBlock(), createBlock(resolveDynamicComponent(__props.tag), {
8588
- class: normalizeClass(["mce-transformable", [
8589
- transforming.value && "mce-transformable--transforming",
8590
- props.hideUi && "mce-transformable--hide-ui",
8591
- __props.resizeStrategy && `mce-transformable--${__props.resizeStrategy}`,
8592
- activeHandle.value && `mce-transformable--${activeHandle.value}`,
8593
- activeHandle.value === "move" && "mce-transformable--moving",
8594
- activeHandle.value?.startsWith("resize") && "mce-transformable--resizing",
8595
- activeHandle.value?.startsWith("rotate") && "mce-transformable--rotateing",
8596
- props.borderStyle && `mce-transformable--${props.borderStyle}`
8597
- ]]),
8598
- style: normalizeStyle(style.value)
8599
- }, {
8600
- default: withCtx(() => [
8601
- renderSlot(_ctx.$slots, "default", {
8602
- value: unref(modelValue),
8603
- props: {
8604
- onPointerdown: start
8605
- },
8606
- start
8607
- }),
8608
- (openBlock(), createElementBlock("svg", _hoisted_1$a, [
8609
- _cache[0] || (_cache[0] = createElementVNode("rect", {
8610
- width: "100%",
8611
- height: "100%",
8612
- fill: "none",
8613
- class: "mce-transformable__rect"
8614
- }, null, -1)),
8615
- createElementVNode("rect", {
8616
- class: "mce-transformable__rect",
8617
- width: "100%",
8618
- height: "100%",
8619
- fill: "none",
8620
- rx: model.value.borderRadius,
8621
- ry: model.value.borderRadius
8622
- }, null, 8, _hoisted_2$5),
8623
- activeHandle.value === "resize-top" || activeHandle.value === "resize-right" || activeHandle.value === "resize-top-right" || activeHandle.value === "resize-bottom-left" ? (openBlock(), createElementBlock("line", _hoisted_3$5)) : activeHandle.value === "resize-left" || activeHandle.value === "resize-bottom" || activeHandle.value === "resize-top-left" || activeHandle.value === "resize-bottom-right" ? (openBlock(), createElementBlock("line", _hoisted_4$3)) : createCommentVNode("", true),
8624
- createElementVNode("g", null, [
8625
- (openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value, (handle, index) => {
8626
- return openBlock(), createElementBlock(Fragment, { key: index }, [
8627
- handle.shape ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
8628
- handle.shape === "rect" ? (openBlock(), createElementBlock("rect", {
8629
- key: 0,
8630
- x: handle.x,
8631
- y: handle.y,
8632
- width: handle.width,
8633
- height: handle.height,
8634
- "aria-label": handle.type,
8635
- class: "mce-transformable__handle"
8636
- }, null, 8, _hoisted_5$2)) : (openBlock(), createElementBlock("circle", {
8637
- key: 1,
8638
- cx: handle.x + handle.width / 2,
8639
- cy: handle.y + handle.width / 2,
8640
- r: handle.width / 2,
8641
- "aria-label": handle.type,
8642
- class: "mce-transformable__handle"
8643
- }, null, 8, _hoisted_6$2))
8644
- ], 64)) : createCommentVNode("", true)
8645
- ], 64);
8646
- }), 128))
8647
- ]),
8648
- createElementVNode("g", _hoisted_7$2, [
8649
- (openBlock(true), createElementBlock(Fragment, null, renderList(computedHandles.value, (handle, index) => {
8650
- return openBlock(), createElementBlock("rect", {
8651
- key: index,
8652
- ref_for: true,
8653
- ref_key: "handlesRef",
8654
- ref: handlesRef,
8655
- x: handle.x,
8656
- y: handle.y,
8657
- width: handle.width,
8658
- height: handle.height,
8659
- "aria-label": handle.type,
8660
- class: "mce-transformable__handle-rect",
8661
- cursor: transforming.value ? "auto" : getCursor(handle.type),
8662
- onPointerdown: (event) => start(event, index)
8663
- }, null, 40, _hoisted_8$1);
8664
- }), 128))
8665
- ]),
8666
- createElementVNode("g", _hoisted_9$1, [
8667
- renderSlot(_ctx.$slots, "svg", { box: model.value })
8668
- ])
8669
- ])),
8670
- tip.value ? (openBlock(), createElementBlock("div", _hoisted_10$1, toDisplayString(tip.value), 1)) : createCommentVNode("", true)
8671
- ]),
8672
- _: 3
8673
- }, 8, ["class", "style"]);
9049
+ return withDirectives((openBlock(), createElementBlock("div", {
9050
+ class: normalizeClass(["mce-scrollbar", {
9051
+ "mce-scrollbar--vertical": props.vertical,
9052
+ "mce-scrollbar--horizontal": !props.vertical
9053
+ }]),
9054
+ style: normalizeStyle({
9055
+ [props.vertical ? "height" : "width"]: `calc(100% - ${props.size + props.offset}px)`,
9056
+ [props.vertical ? "width" : "height"]: `${props.size}px`,
9057
+ [props.vertical ? "top" : "left"]: `${props.offset}px`
9058
+ })
9059
+ }, [
9060
+ createElementVNode("div", _hoisted_1$a, [
9061
+ createElementVNode("div", {
9062
+ ref: "thumbTplRef",
9063
+ class: normalizeClass(["mce-scrollbar__thumb", {
9064
+ "mce-scrollbar__thumb--active": isActive.value
9065
+ }]),
9066
+ style: normalizeStyle({
9067
+ top: thumbTop.value,
9068
+ bottom: thumbBottom.value,
9069
+ left: thumbLeft.value,
9070
+ right: thumbRight.value
9071
+ })
9072
+ }, null, 6)
9073
+ ], 512)
9074
+ ], 6)), [
9075
+ [unref(vResizeObserver), unref(resize)]
9076
+ ]);
9077
+ };
9078
+ }
9079
+ });
9080
+ const _sfc_main$h = /* @__PURE__ */ defineComponent({
9081
+ ...{
9082
+ inheritAttrs: false
9083
+ },
9084
+ __name: "Scrollbars",
9085
+ props: {
9086
+ infinite: { type: Boolean, default: true },
9087
+ offset: { default: 0 },
9088
+ size: { default: 8 }
9089
+ },
9090
+ setup(__props) {
9091
+ const props = __props;
9092
+ const {
9093
+ camera,
9094
+ viewAabb
9095
+ } = useEditor();
9096
+ return (_ctx, _cache) => {
9097
+ return openBlock(), createElementBlock(Fragment, null, [
9098
+ createVNode(_sfc_main$i, mergeProps(props, {
9099
+ modelValue: unref(camera).position.y,
9100
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(camera).position.y = $event),
9101
+ vertical: "",
9102
+ length: unref(viewAabb).height * unref(camera).zoom.y
9103
+ }), null, 16, ["modelValue", "length"]),
9104
+ createVNode(_sfc_main$i, mergeProps(props, {
9105
+ modelValue: unref(camera).position.x,
9106
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => unref(camera).position.x = $event),
9107
+ length: unref(viewAabb).width * unref(camera).zoom.x
9108
+ }), null, 16, ["modelValue", "length"])
9109
+ ], 64);
8674
9110
  };
8675
9111
  }
8676
9112
  });
@@ -8838,7 +9274,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
8838
9274
  })
8839
9275
  }, null, 4);
8840
9276
  }), 128)),
8841
- selectionTransform.value.width && selectionTransform.value.height ? (openBlock(), createBlock(_sfc_main$h, {
9277
+ selectionTransform.value.width && selectionTransform.value.height ? (openBlock(), createBlock(_sfc_main$w, {
8842
9278
  key: 1,
8843
9279
  ref: "transformableRef",
8844
9280
  modelValue: selectionTransform.value,
@@ -8907,7 +9343,7 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
8907
9343
  ...props.defaultTransform
8908
9344
  });
8909
9345
  return (_ctx, _cache) => {
8910
- return openBlock(), createBlock(_sfc_main$h, {
9346
+ return openBlock(), createBlock(_sfc_main$w, {
8911
9347
  modelValue: transform.value,
8912
9348
  "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => transform.value = $event),
8913
9349
  class: "mce-float-panel",
@@ -8923,7 +9359,7 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
8923
9359
  onClick: _cache[0] || (_cache[0] = ($event) => isActive.value = false)
8924
9360
  }, {
8925
9361
  default: withCtx(() => [
8926
- createVNode(_sfc_main$z, { icon: "$close" })
9362
+ createVNode(_sfc_main$C, { icon: "$close" })
8927
9363
  ]),
8928
9364
  _: 1
8929
9365
  })
@@ -9073,13 +9509,6 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
9073
9509
  };
9074
9510
  }
9075
9511
  });
9076
- const _export_sfc = (sfc, props) => {
9077
- const target = sfc.__vccOpts || sfc;
9078
- for (const [key, val] of props) {
9079
- target[key] = val;
9080
- }
9081
- return target;
9082
- };
9083
9512
  const ProgressIndicator = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-c4234331"]]);
9084
9513
  const _hoisted_1$6 = { class: "mce-statusbar" };
9085
9514
  const _hoisted_2$3 = { class: "mce-statusbar__main" };
@@ -9127,7 +9556,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
9127
9556
  ])
9128
9557
  ], 64)) : unref(state) === "transforming" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
9129
9558
  createElementVNode("div", _hoisted_8, [
9130
- createVNode(_sfc_main$z, { icon: "$mouseRightClick" })
9559
+ createVNode(_sfc_main$C, { icon: "$mouseRightClick" })
9131
9560
  ]),
9132
9561
  _cache[2] || (_cache[2] = createElementVNode("span", null, " / ", -1)),
9133
9562
  createElementVNode("div", _hoisted_9, [
@@ -9141,7 +9570,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
9141
9570
  ])
9142
9571
  ], 64)) : unref(state) ? (openBlock(), createElementBlock("span", _hoisted_13, toDisplayString(unref(t)(unref(state))), 1)) : (openBlock(), createElementBlock(Fragment, { key: 3 }, [
9143
9572
  createElementVNode("div", _hoisted_14, [
9144
- createVNode(_sfc_main$z, { icon: "$mouseLeftClick" }),
9573
+ createVNode(_sfc_main$C, { icon: "$mouseLeftClick" }),
9145
9574
  createElementVNode("span", null, toDisplayString(unref(t)("selectObject")), 1)
9146
9575
  ]),
9147
9576
  _cache[4] || (_cache[4] = createElementVNode("span", null, " + ", -1)),
@@ -9151,7 +9580,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
9151
9580
  ]),
9152
9581
  _cache[5] || (_cache[5] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
9153
9582
  createElementVNode("div", _hoisted_17, [
9154
- createVNode(_sfc_main$z, { icon: "$mouseLeftClick" }),
9583
+ createVNode(_sfc_main$C, { icon: "$mouseLeftClick" }),
9155
9584
  createElementVNode("span", null, toDisplayString(unref(t)("selectArea")), 1)
9156
9585
  ]),
9157
9586
  _cache[6] || (_cache[6] = createElementVNode("span", null, " + ", -1)),
@@ -9161,7 +9590,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
9161
9590
  ]),
9162
9591
  _cache[7] || (_cache[7] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
9163
9592
  createElementVNode("div", _hoisted_20, [
9164
- createVNode(_sfc_main$z, { icon: "$mouseLeftClick" }),
9593
+ createVNode(_sfc_main$C, { icon: "$mouseLeftClick" }),
9165
9594
  createElementVNode("span", null, toDisplayString(unref(t)("dragSelected")), 1)
9166
9595
  ])
9167
9596
  ], 64))
@@ -9236,7 +9665,11 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
9236
9665
  const editor = textEditor.value;
9237
9666
  editor.set(element.text.base);
9238
9667
  await nextTick();
9239
- return editor.pointerdown(e);
9668
+ if (editor.pointerDown(e)) {
9669
+ editor.selectAll();
9670
+ return true;
9671
+ }
9672
+ return false;
9240
9673
  }
9241
9674
  onBeforeMount(() => registerCommand({ command: "startTyping", handle: startTyping }));
9242
9675
  onBeforeUnmount(() => unregisterCommand("startTyping"));
@@ -9480,7 +9913,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
9480
9913
  class: "mce-timeline__play",
9481
9914
  onClick: toggle
9482
9915
  }, [
9483
- createVNode(_sfc_main$z, {
9916
+ createVNode(_sfc_main$C, {
9484
9917
  icon: paused.value ? "$play" : "$pause"
9485
9918
  }, null, 8, ["icon"])
9486
9919
  ])
@@ -9509,7 +9942,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
9509
9942
  }, [
9510
9943
  createElementVNode("div", _hoisted_5, [
9511
9944
  createElementVNode("div", _hoisted_6, [
9512
- createVNode(_sfc_main$l, {
9945
+ createVNode(_sfc_main$k, {
9513
9946
  ref: "rulerTpl",
9514
9947
  zoom: 1 / unref(msPerPx) * fps.value,
9515
9948
  unit: 100,
@@ -9574,14 +10007,13 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9574
10007
  ...makeMceStrategyProps({
9575
10008
  resizeStrategy: defaultResizeStrategy,
9576
10009
  activeStrategy: defaultActiveStrategy,
10010
+ doubleclickStrategy: defaultDoubleclickStrategy,
9577
10011
  hoverStrategy: defaultHoverStrategy
9578
10012
  }),
9579
10013
  editor: Editor
9580
10014
  },
9581
- emits: ["dblclick:drawboard"],
9582
- setup(__props, { emit: __emit }) {
10015
+ setup(__props) {
9583
10016
  const props = __props;
9584
- const emit = __emit;
9585
10017
  let editor;
9586
10018
  if (props.editor) {
9587
10019
  editor = provideEditor(props.editor);
@@ -9590,6 +10022,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9590
10022
  }
9591
10023
  provide(IconsSymbol, createIcons());
9592
10024
  const {
10025
+ showMadeWith,
9593
10026
  config,
9594
10027
  drawboardDom,
9595
10028
  renderEngine,
@@ -9644,25 +10077,20 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9644
10077
  renderEngine.value.off("pointermove", onPointermove);
9645
10078
  renderEngine.value.off("pointerover", onPointerover);
9646
10079
  });
9647
- function isExcluded(element) {
9648
- return isFrame(element);
9649
- }
9650
10080
  function onHover(event) {
9651
10081
  let cursor;
9652
10082
  let hovered;
9653
- if (isPointInsideAabb(
10083
+ if (elementSelection.value.length > 1 && isPointInsideAabb(
9654
10084
  { x: event.clientX, y: event.clientY },
9655
10085
  getAabbInDrawboard(elementSelection.value)
9656
10086
  )) {
9657
10087
  cursor = "move";
9658
10088
  } else {
9659
10089
  const element = event.target;
9660
- const oldElement = elementSelection.value[0];
9661
10090
  const result = props.hoverStrategy({
9662
10091
  element,
9663
- oldElement,
9664
10092
  event,
9665
- isExcluded
10093
+ editor
9666
10094
  });
9667
10095
  if (result && !(result instanceof Element2D)) {
9668
10096
  hovered = result.element;
@@ -9678,11 +10106,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9678
10106
  if (downEvent.srcElement !== drawboardDom.value && downEvent.srcElement.dataset?.pointerdown_to_drawboard === void 0 || camera.value.spaceKey || ![0, 2].includes(downEvent.button)) {
9679
10107
  return;
9680
10108
  }
9681
- const oldElement = elementSelection.value[0];
9682
10109
  const element = downEvent.target;
9683
10110
  const start = { x: downEvent.clientX, y: downEvent.clientY };
9684
10111
  let current = { ...start };
9685
10112
  let dragging = false;
10113
+ let selecting = false;
9686
10114
  let isUp = false;
9687
10115
  let selected = [];
9688
10116
  let ctxState;
@@ -9694,9 +10122,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9694
10122
  if (!inSelection) {
9695
10123
  const result = props.activeStrategy({
9696
10124
  element,
9697
- oldElement,
9698
10125
  event: downEvent,
9699
- isExcluded
10126
+ editor
9700
10127
  });
9701
10128
  if (result && !(result instanceof Element2D)) {
9702
10129
  selected = result.element ? [result.element] : [];
@@ -9710,9 +10137,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9710
10137
  function onDrag(event) {
9711
10138
  const result = props.activeStrategy({
9712
10139
  element,
9713
- oldElement,
9714
10140
  event,
9715
- isExcluded
10141
+ editor
9716
10142
  });
9717
10143
  if (result && !(result instanceof Element2D)) {
9718
10144
  selected = result.element ? [result.element] : [];
@@ -9722,6 +10148,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9722
10148
  elementSelection.value = selected;
9723
10149
  }
9724
10150
  function onSelectArea() {
10151
+ selecting = true;
9725
10152
  if (state.value !== "selecting") {
9726
10153
  state.value = "selecting";
9727
10154
  }
@@ -9736,9 +10163,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9736
10163
  function onActivate() {
9737
10164
  const result = props.activeStrategy({
9738
10165
  element,
9739
- oldElement,
9740
10166
  event: downEvent,
9741
- isExcluded: () => false
10167
+ editor
9742
10168
  });
9743
10169
  let _element;
9744
10170
  if (result && !(result instanceof Element2D)) {
@@ -9788,12 +10214,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9788
10214
  }
9789
10215
  }
9790
10216
  }
9791
- async function onUp(_event) {
10217
+ async function onUp(upEvent) {
9792
10218
  if (state.value) {
9793
10219
  state.value = void 0;
9794
10220
  }
9795
10221
  if (!dragging) {
9796
- if (element) {
10222
+ if (element && !selecting) {
9797
10223
  onActivate();
9798
10224
  }
9799
10225
  elementSelection.value = selected;
@@ -9801,7 +10227,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9801
10227
  if (selected[0] && !isLock(selected[0])) {
9802
10228
  switch (ctxState) {
9803
10229
  case "typing": {
9804
- await exec("startTyping", _event);
10230
+ await exec("startTyping", upEvent);
9805
10231
  break;
9806
10232
  }
9807
10233
  }
@@ -9843,6 +10269,18 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9843
10269
  }
9844
10270
  }
9845
10271
  }
10272
+ async function onDoubleclick(event) {
10273
+ const state2 = props.doubleclickStrategy({
10274
+ event,
10275
+ editor
10276
+ });
10277
+ switch (state2) {
10278
+ case "typing": {
10279
+ await exec("startTyping", event);
10280
+ break;
10281
+ }
10282
+ }
10283
+ }
9846
10284
  return (_ctx, _cache) => {
9847
10285
  return openBlock(), createBlock(_sfc_main$d, { class: "mce-editor" }, {
9848
10286
  default: withCtx(() => [
@@ -9854,17 +10292,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9854
10292
  ref: drawboardDom,
9855
10293
  class: "mce-editor__drawboard",
9856
10294
  "data-pixel-ratio": unref(renderEngine).pixelRatio,
9857
- onDblclick: _cache[1] || (_cache[1] = ($event) => emit("dblclick:drawboard", $event)),
10295
+ onDblclick: _cache[1] || (_cache[1] = ($event) => onDoubleclick($event)),
9858
10296
  onScroll,
9859
10297
  onWheel: _cache[2] || (_cache[2] = withModifiers(() => {
9860
10298
  }, ["prevent"]))
9861
10299
  }, [
9862
10300
  createElementVNode("canvas", _hoisted_2, null, 512),
9863
10301
  createVNode(_sfc_main$8, { ref: "textEditorTpl" }, null, 512),
9864
- createVNode(_sfc_main$A),
10302
+ createVNode(_sfc_main$D),
9865
10303
  createVNode(_sfc_main$q),
9866
10304
  createVNode(_sfc_main$s),
9867
- createVNode(_sfc_main$v),
10305
+ createVNode(_sfc_main$y),
9868
10306
  createVNode(_sfc_main$g, {
9869
10307
  ref: "selectorTpl",
9870
10308
  "selected-area": selectedArea.value,
@@ -9874,25 +10312,38 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9874
10312
  renderSlot(_ctx.$slots, "transformer", { box })
9875
10313
  ]),
9876
10314
  default: withCtx(({ box }) => [
10315
+ createVNode(_sfc_main$u),
9877
10316
  renderSlot(_ctx.$slots, "selector", { box })
9878
10317
  ]),
9879
10318
  _: 3
9880
10319
  }, 8, ["selected-area", "resize-strategy"]),
9881
- unref(config).scrollbar ? (openBlock(), createBlock(_sfc_main$i, { key: 0 })) : createCommentVNode("", true),
9882
- _ctx.$slots.floatbar ? (openBlock(), createBlock(_sfc_main$u, {
10320
+ unref(config).scrollbar ? (openBlock(), createBlock(_sfc_main$h, { key: 0 })) : createCommentVNode("", true),
10321
+ _ctx.$slots.floatbar || _ctx.$slots["floatbar-top"] ? (openBlock(), createBlock(_sfc_main$x, {
9883
10322
  key: 1,
10323
+ location: "top-start",
9884
10324
  target: unref(state) === "typing" ? textEditor.value?.textEditor : selector.value?.transformable?.$el
9885
10325
  }, {
9886
10326
  default: withCtx(() => [
9887
- renderSlot(_ctx.$slots, "floatbar")
10327
+ renderSlot(_ctx.$slots, "floatbar"),
10328
+ renderSlot(_ctx.$slots, "floatbar-top")
10329
+ ]),
10330
+ _: 3
10331
+ }, 8, ["target"])) : createCommentVNode("", true),
10332
+ _ctx.$slots["floatbar-bottom"] ? (openBlock(), createBlock(_sfc_main$x, {
10333
+ key: 2,
10334
+ location: "bottom-start",
10335
+ target: selector.value?.transformable?.$el
10336
+ }, {
10337
+ default: withCtx(() => [
10338
+ renderSlot(_ctx.$slots, "floatbar-bottom")
9888
10339
  ]),
9889
10340
  _: 3
9890
10341
  }, 8, ["target"])) : createCommentVNode("", true),
9891
- createVNode(_sfc_main$w),
10342
+ createVNode(_sfc_main$z),
9892
10343
  createVNode(_sfc_main$r),
9893
- unref(config).ruler ? (openBlock(), createBlock(_sfc_main$k, { key: 2 })) : createCommentVNode("", true),
10344
+ unref(config).ruler ? (openBlock(), createBlock(_sfc_main$j, { key: 3 })) : createCommentVNode("", true),
9894
10345
  unref(config).layers ? (openBlock(), createBlock(_sfc_main$e, {
9895
- key: 3,
10346
+ key: 4,
9896
10347
  modelValue: unref(config).layers,
9897
10348
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(config).layers = $event),
9898
10349
  title: unref(t)("layers"),
@@ -9908,6 +10359,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9908
10359
  ]),
9909
10360
  _: 1
9910
10361
  }, 8, ["modelValue", "title", "default-transform"])) : createCommentVNode("", true),
10362
+ unref(showMadeWith) ? (openBlock(), createBlock(MadeWith, { key: 5 })) : createCommentVNode("", true),
9911
10363
  createVNode(Toolbelt),
9912
10364
  renderSlot(_ctx.$slots, "drawboard")
9913
10365
  ], 40, _hoisted_1)
@@ -9971,7 +10423,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
9971
10423
  updateLocation
9972
10424
  });
9973
10425
  return (_ctx, _cache) => {
9974
- return openBlock(), createBlock(_sfc_main$y, {
10426
+ return openBlock(), createBlock(_sfc_main$B, {
9975
10427
  ref: "overlayTpl",
9976
10428
  modelValue: isActive.value,
9977
10429
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isActive.value = $event),
@@ -9995,6 +10447,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
9995
10447
  }
9996
10448
  });
9997
10449
  export {
10450
+ _sfc_main$v as Cropper,
9998
10451
  _sfc_main as Dialog,
9999
10452
  Doc,
10000
10453
  Editor,
@@ -10011,12 +10464,12 @@ export {
10011
10464
  MceMenuSymbol,
10012
10465
  MceOverlaySymbol,
10013
10466
  MceSvgIcon,
10014
- _sfc_main$x as Menu,
10467
+ _sfc_main$A as Menu,
10015
10468
  Model,
10016
- _sfc_main$l as Ruler,
10469
+ _sfc_main$k as Ruler,
10017
10470
  SUPPORTS_CLIPBOARD,
10018
- _sfc_main$j as Scrollbar,
10019
- _sfc_main$h as Transformable,
10471
+ _sfc_main$i as Scrollbar,
10472
+ _sfc_main$w as Transformable,
10020
10473
  USER_AGENT,
10021
10474
  boundingBoxToStyle,
10022
10475
  consoleError,
@@ -10028,6 +10481,7 @@ export {
10028
10481
  createLayout,
10029
10482
  createTextElement,
10030
10483
  defaultActiveStrategy,
10484
+ defaultDoubleclickStrategy,
10031
10485
  defaultHoverStrategy,
10032
10486
  defaultResizeStrategy,
10033
10487
  defineMixin,