mce 0.14.3 → 0.15.0

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
- import { Node as Node$1, Element2D, Timeline, Engine, Camera2D, DrawboardEffect, IN_BROWSER, clamp, assets, TimelineNode, Transform2D, DEG_TO_RAD, render, customNodes, Animation, IN_MAC_OS } from "modern-canvas";
2
- import { reactive, computed, watch, markRaw, ref, warn, shallowRef, onBeforeUnmount, defineComponent, createElementBlock, createCommentVNode, unref, openBlock, normalizeStyle, toDisplayString, createVNode, useAttrs, createBlock, resolveDynamicComponent, normalizeClass, mergeProps, createElementVNode, inject, toValue, getCurrentInstance, provide, readonly, toRef, onMounted, useId, onDeactivated, onActivated, onScopeDispose, useModel, useTemplateRef, withDirectives, vShow, vModelText, nextTick, Fragment, renderList, renderSlot, mergeModels, resolveComponent, withCtx, withModifiers, Teleport, createTextVNode, createSlots, normalizeProps, guardReactiveProps, onBeforeMount, h, isRef, useSlots } from "vue";
1
+ import { Node as Node$1, Element2D, Timeline, Engine, Camera2D, DrawboardEffect, IN_BROWSER, clamp, assets, TimelineNode, Transform2D, Obb2D, Aabb2D, render, Vector2 as Vector2$1, customNodes, Animation, IN_MAC_OS } from "modern-canvas";
2
+ import { reactive, computed, watch, markRaw, ref, warn, shallowRef, onBeforeUnmount, defineComponent, createElementBlock, createCommentVNode, unref, openBlock, normalizeStyle, toDisplayString, createVNode, useAttrs, createBlock, resolveDynamicComponent, normalizeClass, mergeProps, createElementVNode, inject, toValue, getCurrentInstance, provide, useId, readonly, toRef, onMounted, onDeactivated, onActivated, onScopeDispose, useModel, useTemplateRef, withDirectives, vShow, vModelText, nextTick, Fragment, renderList, renderSlot, mergeModels, resolveComponent, withModifiers, withCtx, Teleport, createTextVNode, createSlots, normalizeProps, guardReactiveProps, onBeforeMount, h, isRef, useSlots } from "vue";
3
3
  import { useFileDialog, useEventListener, isClient, onClickOutside, useDebounceFn, useResizeObserver as useResizeObserver$1, useLocalStorage, useImage } from "@vueuse/core";
4
- import { getObjectValueByPath, setObjectValueByPath, Observable, Reactivable, idGenerator, property, normalizeElement, normalizeTextContent, normalizeCRLF, isEqualObject } from "modern-idoc";
4
+ import { getObjectValueByPath, setObjectValueByPath, Observable, Reactivable, idGenerator, property, 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";
@@ -495,58 +495,13 @@ var __decorateClass = (decorators, target, key, kind) => {
495
495
  if (result) __defProp(target, key, result);
496
496
  return result;
497
497
  };
498
- function initYElement(yMap, element = {}, parentId, regenId = false) {
499
- const normalized = normalizeElement({
500
- ...element,
501
- id: regenId ? void 0 : element.id,
502
- meta: {
503
- inCanvasIs: "Element2D",
504
- ...element?.meta ?? {}
505
- }
506
- });
507
- const id = normalized.id;
508
- const yChildrenIds = new Y.Array();
509
- for (const key in normalized) {
510
- yMap.set(key, normalized[key]);
511
- }
512
- yMap.set("id", id);
513
- yMap.set("parentId", parentId);
514
- yMap.set("name", normalized.name ?? id);
515
- yMap.set("childrenIds", yChildrenIds);
516
- yMap.set("meta", new Y.Map(Object.entries(normalized.meta ?? {})));
517
- const inCanvasIs = normalized?.meta?.inCanvasIs;
518
- if (inCanvasIs === "Element2D" || inCanvasIs === "Lottie2D") {
519
- yMap.set("style", new Y.Map(Object.entries(normalized.style ?? {})));
520
- yMap.set("background", new Y.Map(Object.entries(normalized.background ?? {})));
521
- yMap.set("shape", new Y.Map(Object.entries(normalized.shape ?? {})));
522
- yMap.set("fill", new Y.Map(Object.entries(normalized.fill ?? {})));
523
- yMap.set("outline", new Y.Map(Object.entries(normalized.outline ?? {})));
524
- yMap.set("text", new Y.Map(Object.entries(normalized.text ?? {})));
525
- yMap.set("foreground", new Y.Map(Object.entries(normalized.foreground ?? {})));
526
- yMap.set("shadow", new Y.Map(Object.entries(normalized.shadow ?? {})));
527
- }
528
- return {
529
- normalized,
530
- yChildrenIds
531
- };
532
- }
533
- function iElementToYNodes(element, parentId, regenId = false) {
534
- const results = [];
535
- const yNode = new Y.Map();
536
- const { normalized, yChildrenIds } = initYElement(yNode, element, parentId, regenId);
537
- const id = normalized.id;
538
- results.push({ id, node: yNode });
539
- normalized.children?.forEach((iChild) => {
540
- const result = iElementToYNodes(iChild, id, regenId);
541
- yChildrenIds.push([result[0].id]);
542
- results.push(...result);
543
- });
544
- return results;
545
- }
546
498
  class Doc extends Model {
547
499
  _yChildren;
548
500
  _yChildrenIds;
549
- root = reactive(new Node$1());
501
+ root = reactive(new Node$1({
502
+ id: "root",
503
+ name: "Doc"
504
+ }));
550
505
  _nodeMap = /* @__PURE__ */ new Map();
551
506
  get meta() {
552
507
  return this.root.meta;
@@ -562,6 +517,8 @@ class Doc extends Model {
562
517
  this._yChildren,
563
518
  this._yChildrenIds
564
519
  ]);
520
+ this._yProps.set("id", this.root.id);
521
+ this._yProps.set("name", this.root.name);
565
522
  }
566
523
  setProperties(properties) {
567
524
  if (properties) {
@@ -578,20 +535,13 @@ class Doc extends Model {
578
535
  }
579
536
  async load(initFn) {
580
537
  return super.load(async () => {
538
+ this._proxyNode(
539
+ this.root,
540
+ this._yProps,
541
+ this._yChildrenIds
542
+ );
543
+ this._yChildren.observe(this._yChildrenChange.bind(this));
581
544
  await initFn?.();
582
- this._proxyProps(this.root, this._yProps);
583
- const meta = this._yProps.get("meta");
584
- if (meta) {
585
- this._proxyProps(this.root.meta, meta, true);
586
- }
587
- this._proxyChildren(this.root, this._yChildrenIds);
588
- this._yChildrenIds.forEach((id) => {
589
- const yNode = this._yChildren.get(id);
590
- if (yNode) {
591
- this._getOrCreateNode(yNode);
592
- }
593
- });
594
- this._yChildren.observe(this._onChildrenChange.bind(this));
595
545
  });
596
546
  }
597
547
  _isSelfTransaction(transaction) {
@@ -599,11 +549,11 @@ class Doc extends Model {
599
549
  }
600
550
  _debug(..._args) {
601
551
  }
602
- _onChildrenChange(event, transaction) {
552
+ _yChildrenChange(event, transaction) {
603
553
  if (this._isSelfTransaction(transaction)) {
604
554
  return;
605
555
  }
606
- this._debug("_onChildrenChange", event);
556
+ this._debug("yChildrenChange", event);
607
557
  const { keysChanged, changes } = event;
608
558
  keysChanged.forEach((key) => {
609
559
  const change = changes.keys.get(key);
@@ -611,7 +561,7 @@ class Doc extends Model {
611
561
  switch (change?.action) {
612
562
  case "add":
613
563
  if (yNode) {
614
- this._getOrCreateNode(yNode);
564
+ this._initYNode(yNode);
615
565
  }
616
566
  break;
617
567
  case "delete":
@@ -623,6 +573,7 @@ class Doc extends Model {
623
573
  }
624
574
  reset() {
625
575
  super.reset();
576
+ this.root.resetProperties();
626
577
  this._yChildren.clear();
627
578
  this._yChildrenIds.delete(0, this._yChildrenIds.length);
628
579
  this._nodeMap.clear();
@@ -630,92 +581,57 @@ class Doc extends Model {
630
581
  this.indexeddb?.clearData();
631
582
  return this;
632
583
  }
633
- _addNode(node, options = {}) {
584
+ _addNode(data, options = {}) {
634
585
  const { parentId, index, regenId } = options;
635
- const yNodes = iElementToYNodes(node, parentId, regenId);
636
- yNodes.forEach((result) => this._yChildren.set(result.id, result.node));
637
- const _nodeMap = yNodes.map((result) => this._getOrCreateNode(result.node));
638
- const first = _nodeMap[0];
639
586
  let parent;
640
- let childrenIds;
641
587
  if (parentId && parentId !== this.root.id) {
642
- parent = this._nodeMap.get(parentId);
643
- childrenIds = this._yChildren.get(parentId)?.get("childrenIds");
588
+ parent = this._nodeMap.get(parentId) ?? this.root;
644
589
  } else {
645
590
  parent = this.root;
646
- childrenIds = this._yChildrenIds;
647
591
  }
648
- if (parent && childrenIds) {
649
- if (index === void 0) {
650
- childrenIds.push([first.id]);
651
- parent.appendChild(first);
652
- } else {
653
- childrenIds.insert(index, [first.id]);
654
- parent.moveChild(first, index);
592
+ const value = {
593
+ ...data,
594
+ meta: {
595
+ inCanvasIs: "Element2D",
596
+ ...data?.meta ?? {}
655
597
  }
598
+ };
599
+ if (regenId) {
600
+ delete value.id;
601
+ }
602
+ const node = reactive(Node$1.parse(value));
603
+ if (index === void 0) {
604
+ parent.appendChild(node);
605
+ } else {
606
+ parent.moveChild(node, index);
656
607
  }
657
- return first;
608
+ this._proxyNode(node);
609
+ return node;
658
610
  }
659
- addNode(node, options) {
660
- return this.transact(() => this._addNode(node, options));
611
+ addNode(data, options) {
612
+ return this.transact(() => this._addNode(data, options));
661
613
  }
662
- addNodes(nodes, options) {
663
- return this.transact(() => nodes.map((element) => this._addNode(element, options)));
614
+ addNodes(dataItems, options) {
615
+ return this.transact(() => dataItems.map((data) => this._addNode(data, options)));
664
616
  }
665
617
  set(source) {
666
- const { children = [], meta = {}, ...props } = source;
618
+ const { children = [], meta = {}, ..._props } = source;
619
+ const props = {
620
+ id: this.root.id,
621
+ name: this.root.name,
622
+ ..._props
623
+ };
667
624
  this.reset();
668
- this.addNodes(children);
669
625
  this.setProperties(props);
670
626
  this._yProps.clear();
671
627
  for (const key in props) {
672
628
  this._yProps.set(key, props[key]);
673
629
  }
674
630
  this._yProps.set("meta", new Y.Map(Object.entries(meta)));
631
+ this._transacting = true;
632
+ this.addNodes(children);
675
633
  return this;
676
634
  }
677
- _deleteNode(id) {
678
- const node = this._nodeMap.get(id);
679
- const yNode = this._yChildren.get(id);
680
- if (!yNode || !node) {
681
- return;
682
- }
683
- const parentId = yNode.get("parentId");
684
- const parentChildrenIds = parentId ? this._yChildren.get(parentId)?.get("childrenIds") : this._yChildrenIds;
685
- if (parentChildrenIds) {
686
- const index = parentChildrenIds.toJSON().indexOf(id);
687
- if (index > -1) {
688
- parentChildrenIds.delete(index);
689
- }
690
- }
691
- yNode.get("childrenIds").forEach((id2) => this._deleteNode(id2));
692
- node.remove();
693
- }
694
- deleteNode(id) {
695
- this.transact(() => this._deleteNode(id));
696
- }
697
- getNode(id) {
698
- return this._nodeMap.get(id);
699
- }
700
- moveNode(id, toIndex) {
701
- const node = this._nodeMap.get(id);
702
- if (!node) {
703
- return;
704
- }
705
- const parent = node.parent;
706
- const childrenIds = parent?.id ? this._yChildren.get(parent.id)?.get("childrenIds") : this._yChildrenIds;
707
- if (!childrenIds) {
708
- return;
709
- }
710
- const fromIndex = childrenIds.toJSON().indexOf(id);
711
- childrenIds.delete(fromIndex, 1);
712
- childrenIds.insert(toIndex, [id]);
713
- if (parent && !parent.equal(this.root)) {
714
- parent.moveChild(node, toIndex);
715
- } else {
716
- this.root.moveChild(node, toIndex);
717
- }
718
- }
719
635
  _proxyProps(obj, yMap, isMeta = false) {
720
636
  const accessor = {
721
637
  getProperty: (key) => yMap.doc ? yMap.get(key) : void 0,
@@ -775,45 +691,80 @@ class Doc extends Model {
775
691
  yMap.observe(observeFn);
776
692
  }
777
693
  _proxyChildren(node, childrenIds) {
778
- childrenIds.forEach((id) => {
779
- const child = this._yChildren.get(id);
780
- if (child) {
781
- node.appendChild(this._getOrCreateNode(child));
694
+ node.on("addChild", (child, newIndex) => {
695
+ if (this._transacting === false) {
696
+ return;
782
697
  }
698
+ this.transact(() => {
699
+ childrenIds.insert(newIndex, [child.id]);
700
+ this._debug(`addChild ${child.id}`, child.name, newIndex);
701
+ });
783
702
  });
784
- const observeFn = (event, transaction) => {
785
- if (this._isSelfTransaction(transaction)) {
703
+ node.on("removeChild", (child, oldIndex) => {
704
+ if (this._transacting === false) {
786
705
  return;
787
706
  }
788
- this._debug("_proxyChildren", event, node);
789
- const children = node.children;
707
+ this.transact(() => {
708
+ const index = childrenIds.toJSON().indexOf(child.id);
709
+ if (index > -1) {
710
+ childrenIds.delete(index, 1);
711
+ }
712
+ this._debug(`removeChild ${child.id}`, child.name, oldIndex);
713
+ });
714
+ });
715
+ node.children.forEach((child) => {
716
+ this._proxyNode(child);
717
+ });
718
+ const cachedChildrenIds = childrenIds.toArray();
719
+ const observeFn = (event, transaction) => {
720
+ const skip = this._isSelfTransaction(transaction);
721
+ this._debug(`yChildren ${node.id} changes`, event.changes.delta);
790
722
  let retain = 0;
791
723
  event.changes.delta.forEach((action) => {
792
724
  if (action.retain !== void 0) {
793
725
  retain += action.retain;
794
726
  }
795
727
  if (action.delete) {
796
- for (let i = retain; i < retain + action.delete; i++) {
797
- children[i]?.remove();
728
+ if (!skip) {
729
+ for (let i = retain; i < retain + action.delete; i++) {
730
+ const id = cachedChildrenIds[i];
731
+ if (!id) {
732
+ continue;
733
+ }
734
+ const child = this._nodeMap.get(id);
735
+ if (child && child.parent?.equal(node) && child.getIndex() === i) {
736
+ this.transact(() => {
737
+ child.remove();
738
+ this._debug(`yChildren remove ${child.id}`, child.name, i);
739
+ }, false);
740
+ }
741
+ }
798
742
  }
743
+ cachedChildrenIds.splice(retain, action.delete);
799
744
  }
800
745
  if (action.insert) {
801
- const ids = Array.isArray(action.insert) ? action.insert : [action.insert];
802
- ids.forEach((id, index) => {
803
- let child = this._nodeMap.get(id);
804
- const cb = (child2) => {
805
- node.moveChild(child2, retain + index);
806
- };
807
- if (child) {
808
- cb(child);
809
- } else {
810
- setTimeout(() => {
811
- child = this._nodeMap.get(id);
812
- child && cb(child);
813
- }, 0);
814
- }
815
- });
816
- retain += ids.length;
746
+ const insert = Array.isArray(action.insert) ? action.insert : [action.insert];
747
+ if (!skip) {
748
+ insert.forEach((id, index) => {
749
+ let child = this._nodeMap.get(id);
750
+ const cb = (child2) => {
751
+ this.transact(() => {
752
+ node.moveChild(child2, retain + index);
753
+ this._debug(`yChildren insert ${child2.id}`, child2.name, retain + index);
754
+ }, false);
755
+ };
756
+ if (child) {
757
+ cb(child);
758
+ } else {
759
+ setTimeout(() => {
760
+ child = this._nodeMap.get(id);
761
+ child && cb(child);
762
+ }, 0);
763
+ }
764
+ });
765
+ }
766
+ cachedChildrenIds.splice(retain, 0, ...insert);
767
+ retain += insert.length;
817
768
  }
818
769
  });
819
770
  };
@@ -822,35 +773,71 @@ class Doc extends Model {
822
773
  node._childrenIdsObserveFn = markRaw(observeFn);
823
774
  childrenIds.observe(observeFn);
824
775
  }
825
- _proxyNode(node, yEle) {
826
- this._proxyProps(node, yEle);
827
- const meta = yEle.get("meta");
828
- if (meta) {
829
- this._proxyProps(node.meta, meta, true);
776
+ _proxyNode(node, yNode, yChildrenIds) {
777
+ const id = node.id;
778
+ if (!yNode) {
779
+ yNode = this._yChildren.get(id);
830
780
  }
831
- if (node instanceof Element2D) {
832
- [
833
- "style",
834
- "background",
835
- "shape",
836
- "fill",
837
- "outline",
838
- "text",
839
- "foreground",
840
- "shadow"
841
- ].forEach((key) => {
842
- const yMap = yEle.get(key);
843
- if (yMap) {
844
- this._proxyProps(node[key], yMap);
845
- }
781
+ if (!yNode) {
782
+ yNode = new Y.Map(Object.entries({
783
+ ...node.getProperties(),
784
+ id
785
+ }));
786
+ this._yChildren.set(id, yNode);
787
+ this.undoManager.addToScope(yNode);
788
+ }
789
+ if (!this._nodeMap.has(id)) {
790
+ this._nodeMap.set(id, node);
791
+ yNode.set("parentId", node.parent?.id);
792
+ node.on("parented", () => {
793
+ yNode.set("parentId", node.parent?.id);
846
794
  });
847
- node._text = markRaw(node._text);
848
- node.text.update();
849
- node.requestRender();
795
+ node.on("destroy", () => {
796
+ this._nodeMap.delete(node.id);
797
+ this._debug("destroy", node.id);
798
+ });
799
+ this._proxyProps(node, yNode);
800
+ let meta = yNode.get("meta");
801
+ if (!meta || !(meta instanceof Y.Map)) {
802
+ meta = new Y.Map(Object.entries(node.meta.getProperties()));
803
+ yNode.set("meta", meta);
804
+ }
805
+ this._proxyProps(node.meta, meta, true);
806
+ if (node instanceof Element2D) {
807
+ [
808
+ "style",
809
+ "background",
810
+ "shape",
811
+ "fill",
812
+ "outline",
813
+ "text",
814
+ "foreground",
815
+ "shadow"
816
+ ].forEach((key) => {
817
+ let yMap = yNode.get(key);
818
+ if (!yMap || !(yMap instanceof Y.Map)) {
819
+ yMap = new Y.Map(Object.entries(node[key].getProperties()));
820
+ yNode.set(key, yMap);
821
+ }
822
+ this._proxyProps(node[key], yMap);
823
+ });
824
+ node._text = markRaw(node._text);
825
+ node.text.update();
826
+ node.requestRender();
827
+ }
828
+ if (!yChildrenIds) {
829
+ yChildrenIds = yNode.get("childrenIds");
830
+ }
831
+ if (!yChildrenIds) {
832
+ yChildrenIds = new Y.Array();
833
+ yChildrenIds.push(node.children.map((c) => c.id));
834
+ yNode.set("childrenIds", yChildrenIds);
835
+ }
836
+ this._proxyChildren(node, yChildrenIds);
850
837
  }
851
- this._proxyChildren(node, yEle.get("childrenIds"));
838
+ return yNode;
852
839
  }
853
- _getOrCreateNode(yNode) {
840
+ _initYNode(yNode) {
854
841
  const id = yNode.get("id");
855
842
  let node = this._nodeMap.get(id);
856
843
  if (!node) {
@@ -875,7 +862,7 @@ class Doc extends Model {
875
862
  }
876
863
  }
877
864
  __decorateClass([
878
- property({ default: "doc" })
865
+ property()
879
866
  ], Doc.prototype, "name");
880
867
  const _0_context = defineMixin((editor) => {
881
868
  const fonts = markRaw(new Fonts());
@@ -1357,76 +1344,6 @@ function boundingBoxToStyle(box) {
1357
1344
  }
1358
1345
  return style;
1359
1346
  }
1360
- function isPointInsideAabb(point, box) {
1361
- const right = box.left + box.width;
1362
- const bottom = box.top + box.height;
1363
- return point.x >= box.left && point.x <= right && point.y >= box.top && point.y <= bottom;
1364
- }
1365
- function isOverlappingAabb(aabb1, aabb2, axis) {
1366
- switch (axis) {
1367
- case "horizontal":
1368
- return aabb1.left + aabb1.width >= aabb2.left && aabb2.left + aabb2.width >= aabb1.left;
1369
- case "vertical":
1370
- return aabb1.top + aabb1.height >= aabb2.top && aabb2.top + aabb2.height >= aabb1.top;
1371
- default:
1372
- return isOverlappingAabb(aabb1, aabb2, "horizontal") && isOverlappingAabb(aabb1, aabb2, "vertical");
1373
- }
1374
- }
1375
- function isOverlappingObb(box1, box2) {
1376
- if (!box1.rotate && !box2.rotate) {
1377
- return isOverlappingAabb(box1, box2);
1378
- } else {
1379
- const dotProduct = ([ax, ay], [bx, by]) => Math.abs(ax * bx + ay * by);
1380
- const createSAT = ({ width, height, rotate = 0 }) => {
1381
- rotate = -rotate % 180;
1382
- const deg = rotate / 180 * Math.PI;
1383
- const axisX = [Math.cos(deg), -Math.sin(deg)];
1384
- const axisY = [Math.sin(deg), Math.cos(deg)];
1385
- return {
1386
- axis: [axisX, axisY],
1387
- projectionRadius: (axis) => width / 2 * dotProduct(axis, axisX) + height / 2 * dotProduct(axis, axisY)
1388
- };
1389
- };
1390
- const data1 = createSAT(box1);
1391
- const data2 = createSAT(box2);
1392
- const center = [
1393
- box1.left + box1.width / 2 - (box2.left + box2.width / 2),
1394
- box1.top + box1.height / 2 - (box2.top + box2.height / 2)
1395
- ];
1396
- for (const axis of [...data1.axis, ...data2.axis]) {
1397
- if (data1.projectionRadius(axis) + data2.projectionRadius(axis) < dotProduct(axis, center)) {
1398
- return false;
1399
- }
1400
- }
1401
- return true;
1402
- }
1403
- }
1404
- function minBoundingBox(rects) {
1405
- if (rects.length < 2) {
1406
- return {
1407
- left: rects[0]?.left ?? 0,
1408
- top: rects[0]?.top ?? 0,
1409
- width: rects[0]?.width ?? 0,
1410
- height: rects[0]?.height ?? 0
1411
- };
1412
- }
1413
- const res = rects.slice(1).reduce(
1414
- (acc, rect) => {
1415
- acc.x1 = Math.min(acc.x1, rect.left);
1416
- acc.y1 = Math.min(acc.y1, rect.top);
1417
- acc.x2 = Math.max(acc.x2, rect.left + rect.width);
1418
- acc.y2 = Math.max(acc.y2, rect.top + rect.height);
1419
- return acc;
1420
- },
1421
- {
1422
- x1: rects[0].left,
1423
- y1: rects[0].top,
1424
- x2: rects[0].left + rects[0].width,
1425
- y2: rects[0].top + rects[0].height
1426
- }
1427
- );
1428
- return { left: res.x1, top: res.y1, width: res.x2 - res.x1, height: res.y2 - res.y1 };
1429
- }
1430
1347
  function consoleWarn(message) {
1431
1348
  warn(`mce: ${message}`);
1432
1349
  }
@@ -1896,29 +1813,31 @@ const _2_box = defineMixin((editor) => {
1896
1813
  getAncestorFrame
1897
1814
  } = editor;
1898
1815
  function obbToFit(element) {
1899
- const minmax = {
1900
- minX: Number.MAX_SAFE_INTEGER,
1901
- minY: Number.MAX_SAFE_INTEGER,
1902
- maxX: Number.MIN_SAFE_INTEGER,
1903
- maxY: Number.MIN_SAFE_INTEGER
1816
+ const min = {
1817
+ x: Number.MAX_SAFE_INTEGER,
1818
+ y: Number.MAX_SAFE_INTEGER
1819
+ };
1820
+ const max = {
1821
+ x: Number.MIN_SAFE_INTEGER,
1822
+ y: Number.MIN_SAFE_INTEGER
1904
1823
  };
1905
1824
  let flag = false;
1906
1825
  element.children.forEach((child) => {
1907
1826
  if (isElement(child)) {
1908
- const _minmax = child.getAabb().toMinmax();
1909
- minmax.minX = Math.min(minmax.minX, _minmax.minX);
1910
- minmax.minY = Math.min(minmax.minY, _minmax.minY);
1911
- minmax.maxX = Math.max(minmax.maxX, _minmax.maxX);
1912
- minmax.maxY = Math.max(minmax.maxY, _minmax.maxY);
1827
+ const { min: _min, max: _max } = child.getAabb().toMinmax();
1828
+ min.x = Math.min(min.x, _min.x);
1829
+ min.y = Math.min(min.y, _min.y);
1830
+ max.x = Math.max(max.x, _max.x);
1831
+ max.y = Math.max(max.y, _max.y);
1913
1832
  flag = true;
1914
1833
  }
1915
1834
  });
1916
1835
  if (flag) {
1917
1836
  const box = {
1918
- left: minmax.minX,
1919
- top: minmax.minY,
1920
- width: minmax.maxX - minmax.minX,
1921
- height: minmax.maxY - minmax.minY
1837
+ left: min.x,
1838
+ top: min.y,
1839
+ width: max.x - min.x,
1840
+ height: max.y - min.y
1922
1841
  };
1923
1842
  const aabbs = {};
1924
1843
  element.children.forEach((child, index) => {
@@ -1960,21 +1879,14 @@ const _2_box = defineMixin((editor) => {
1960
1879
  if (node.length === 1) {
1961
1880
  obb = getObb(node[0]);
1962
1881
  } else {
1963
- obb = { ...getAabb(node), rotate: 0 };
1882
+ obb = new Obb2D(getAabb(node));
1964
1883
  }
1965
1884
  } else if (isElement(node)) {
1966
1885
  const style = node.style;
1967
1886
  noop([style.left, style.top, style.width, style.height, style.rotate]);
1968
- const { rect, rotation } = node.getGlobalObb();
1969
- obb = {
1970
- left: rect.left,
1971
- top: rect.top,
1972
- width: rect.width,
1973
- height: rect.height,
1974
- rotate: rotation / DEG_TO_RAD
1975
- };
1887
+ obb = node.getGlobalObb();
1976
1888
  } else {
1977
- obb = { left: 0, top: 0, width: 0, height: 0, rotate: 0 };
1889
+ obb = new Obb2D();
1978
1890
  }
1979
1891
  if (inTarget === "drawboard") {
1980
1892
  const zoom = camera.value.zoom;
@@ -2013,40 +1925,36 @@ const _2_box = defineMixin((editor) => {
2013
1925
  if (node.length === 1) {
2014
1926
  aabb = getAabb(node[0]);
2015
1927
  } else {
2016
- const minmax = {
2017
- minX: Number.MAX_SAFE_INTEGER,
2018
- minY: Number.MAX_SAFE_INTEGER,
2019
- maxX: Number.MIN_SAFE_INTEGER,
2020
- maxY: Number.MIN_SAFE_INTEGER
1928
+ const min = {
1929
+ x: Number.MAX_SAFE_INTEGER,
1930
+ y: Number.MAX_SAFE_INTEGER
1931
+ };
1932
+ const max = {
1933
+ x: Number.MIN_SAFE_INTEGER,
1934
+ y: Number.MIN_SAFE_INTEGER
2021
1935
  };
2022
1936
  node.forEach((child) => {
2023
1937
  if (isElement(child)) {
2024
1938
  const aabb2 = getAabb(child);
2025
- minmax.minX = Math.min(minmax.minX, aabb2.left);
2026
- minmax.minY = Math.min(minmax.minY, aabb2.top);
2027
- minmax.maxX = Math.max(minmax.maxX, aabb2.left + aabb2.width);
2028
- minmax.maxY = Math.max(minmax.maxY, aabb2.top + aabb2.height);
1939
+ min.x = Math.min(min.x, aabb2.left);
1940
+ min.y = Math.min(min.y, aabb2.top);
1941
+ max.x = Math.max(max.x, aabb2.left + aabb2.width);
1942
+ max.y = Math.max(max.y, aabb2.top + aabb2.height);
2029
1943
  }
2030
1944
  });
2031
- aabb = {
2032
- left: minmax.minX,
2033
- top: minmax.minY,
2034
- width: minmax.maxX - minmax.minX,
2035
- height: minmax.maxY - minmax.minY
2036
- };
1945
+ aabb = new Aabb2D(
1946
+ min.x,
1947
+ min.y,
1948
+ max.x - min.x,
1949
+ max.y - min.y
1950
+ );
2037
1951
  }
2038
1952
  } else if (isElement(node)) {
2039
1953
  const style = node.style;
2040
1954
  noop([style.left, style.top, style.width, style.height, style.rotate]);
2041
- const rect = node.getGlobalAabb();
2042
- aabb = {
2043
- left: rect.left,
2044
- top: rect.top,
2045
- width: rect.width,
2046
- height: rect.height
2047
- };
1955
+ aabb = node.getGlobalAabb();
2048
1956
  } else {
2049
- aabb = { left: 0, top: 0, width: 0, height: 0 };
1957
+ aabb = new Aabb2D();
2050
1958
  }
2051
1959
  if (inTarget === "drawboard") {
2052
1960
  aabb = aabbToDrawboardAabb(aabb);
@@ -2073,7 +1981,7 @@ const _2_box = defineMixin((editor) => {
2073
1981
  return aabb;
2074
1982
  }
2075
1983
  function aabbToDrawboardAabb(aabb) {
2076
- const _aabb = { ...aabb };
1984
+ const _aabb = new Aabb2D(aabb);
2077
1985
  const zoom = camera.value.zoom;
2078
1986
  const position = camera.value.position;
2079
1987
  _aabb.left *= zoom.x;
@@ -2616,11 +2524,63 @@ const _4_1_text = defineMixin((editor) => {
2616
2524
  TextEditor.register();
2617
2525
  };
2618
2526
  });
2619
- const _4_2_element = defineMixin((editor) => {
2527
+ const _4_2_frame = defineMixin((editor) => {
2528
+ const {
2529
+ root,
2530
+ currentFrameIndex,
2531
+ emit,
2532
+ selection,
2533
+ frames,
2534
+ config
2535
+ } = editor;
2536
+ function setCurrentFrame(index = currentFrameIndex.value) {
2537
+ index = Math.max(0, Math.min(frames.value.length - 1, index));
2538
+ const oldIndex = currentFrameIndex.value;
2539
+ currentFrameIndex.value = index;
2540
+ if (config.value.viewMode === "edgeless") {
2541
+ selection.value = [frames.value[index]];
2542
+ } else {
2543
+ selection.value = [];
2544
+ }
2545
+ emit("setCurrentFrame", index, oldIndex);
2546
+ }
2547
+ function handleElementInsideFrame(element) {
2548
+ const source = element.getGlobalAabb();
2549
+ const aArea = source.getArea();
2550
+ let flag = true;
2551
+ for (let i = 0, len = frames.value.length; i < len; i++) {
2552
+ const frame = frames.value[i];
2553
+ if (element.equal(frame)) {
2554
+ continue;
2555
+ }
2556
+ const target = frame.getGlobalAabb();
2557
+ if (source && target) {
2558
+ if (source.getIntersectionRect(target).getArea() > aArea * 0.5) {
2559
+ if (!element.findAncestor((ancestor) => ancestor.equal(frame))) {
2560
+ frame.appendChild(element);
2561
+ element.style.left = source.x - target.x;
2562
+ element.style.top = source.y - target.y;
2563
+ }
2564
+ flag = false;
2565
+ break;
2566
+ }
2567
+ }
2568
+ }
2569
+ if (flag && element.parent && !element.parent.equal(root.value)) {
2570
+ root.value.moveChild(element, 0);
2571
+ element.style.left = source.x;
2572
+ element.style.top = source.y;
2573
+ }
2574
+ }
2575
+ Object.assign(editor, {
2576
+ setCurrentFrame,
2577
+ handleElementInsideFrame
2578
+ });
2579
+ });
2580
+ const _4_3_element = defineMixin((editor) => {
2620
2581
  const {
2621
2582
  doc,
2622
2583
  rootAabb,
2623
- emit,
2624
2584
  textFontSizeToFit,
2625
2585
  textToFit,
2626
2586
  log,
@@ -2634,7 +2594,8 @@ const _4_2_element = defineMixin((editor) => {
2634
2594
  screenCenter,
2635
2595
  selection,
2636
2596
  camera,
2637
- parseAnchor
2597
+ parseAnchor,
2598
+ handleElementInsideFrame
2638
2599
  } = editor;
2639
2600
  function addElement(value, options = {}) {
2640
2601
  log("addElement", value, options);
@@ -2792,20 +2753,10 @@ const _4_2_element = defineMixin((editor) => {
2792
2753
  if (active) {
2793
2754
  selection.value = elements;
2794
2755
  }
2795
- emit("addElement", elements);
2796
- return isArray ? elements : elements[0];
2797
- }
2798
- function deleteElement(id) {
2799
- if (id === selection.value[0]?.id) {
2800
- selection.value = [];
2756
+ if (!isArray && !parent) {
2757
+ handleElementInsideFrame(elements[0]);
2801
2758
  }
2802
- doc.value.deleteNode(id);
2803
- }
2804
- function updateElement(id, properties) {
2805
- getElement(id)?.setProperties(properties);
2806
- }
2807
- function getElement(id) {
2808
- return doc.value.getNode(id);
2759
+ return isArray ? elements : elements[0];
2809
2760
  }
2810
2761
  function resizeElement(element, scaleX, scaleY, options = {}) {
2811
2762
  scaleX = Math.abs(scaleX);
@@ -2829,111 +2780,25 @@ const _4_2_element = defineMixin((editor) => {
2829
2780
  options.textFontSizeToFit && textFontSizeToFit(element, scaleX);
2830
2781
  }
2831
2782
  function selectArea(areaInDrawboard) {
2783
+ const area2 = new Obb2D(areaInDrawboard);
2832
2784
  const selected = root.value?.children.flatMap((node) => {
2833
2785
  if (isFrame(node)) {
2834
2786
  return node.children;
2835
2787
  }
2836
2788
  return [node];
2837
2789
  }).filter((node) => {
2838
- return "isVisibleInTree" in node && node.isVisibleInTree() && isOverlappingObb(areaInDrawboard, getObb(node, "drawboard")) && !isLock(node);
2790
+ return "isVisibleInTree" in node && node.isVisibleInTree() && getObb(node, "drawboard").overlapsOnAxis(area2) && !isLock(node);
2839
2791
  }) ?? [];
2840
2792
  selection.value = selected;
2841
2793
  return selected;
2842
2794
  }
2843
2795
  Object.assign(editor, {
2844
2796
  addElement,
2845
- deleteElement,
2846
- updateElement,
2847
- getElement,
2797
+ addElements: addElement,
2848
2798
  resizeElement,
2849
2799
  selectArea
2850
2800
  });
2851
2801
  });
2852
- const _4_3_frame = defineMixin((editor) => {
2853
- const {
2854
- doc,
2855
- root,
2856
- rootAabb,
2857
- currentFrameIndex,
2858
- frameThumbs,
2859
- emit,
2860
- selection,
2861
- frames,
2862
- config
2863
- } = editor;
2864
- function addFrame(value = {}, toIndex) {
2865
- const element = normalizeElement({
2866
- ...value,
2867
- id: void 0,
2868
- name: "Frame",
2869
- meta: {
2870
- ...value.meta,
2871
- inEditorIs: "Frame"
2872
- }
2873
- });
2874
- element.style ??= {};
2875
- element.style.left = rootAabb.value.left + rootAabb.value.width + config.value.frameGap;
2876
- element.style.width ||= rootAabb.value.width;
2877
- element.style.height ||= rootAabb.value.height;
2878
- const index = toIndex ?? (currentFrameIndex.value > -1 ? currentFrameIndex.value + 1 : frames.value.length - 1);
2879
- doc.value.addNode(element, { index });
2880
- setCurrentFrame(index);
2881
- emit("addFrame", index);
2882
- }
2883
- function duplicateFrame(index = currentFrameIndex.value) {
2884
- const page = root.value.children[index];
2885
- if (!page)
2886
- return;
2887
- doc.value.addNode(page.toJSON(), {
2888
- index: index + 1,
2889
- regenId: true
2890
- });
2891
- emit("duplicateFrame", index);
2892
- }
2893
- function moveFrame(fromIndex, toIndex) {
2894
- const id = root.value.children[fromIndex]?.id;
2895
- if (!id)
2896
- return;
2897
- doc.value.moveNode(id, toIndex);
2898
- frameThumbs.value.splice(
2899
- toIndex,
2900
- 0,
2901
- frameThumbs.value.splice(fromIndex, 1)[0]
2902
- );
2903
- setCurrentFrame(toIndex);
2904
- emit("moveFrame", fromIndex, toIndex);
2905
- }
2906
- function deleteFrame(index = currentFrameIndex.value) {
2907
- if (!root.value || root.value.children.length === 1) {
2908
- return;
2909
- }
2910
- const id = root.value.children[index]?.id;
2911
- if (!id)
2912
- return;
2913
- doc.value.deleteNode(id);
2914
- frameThumbs.value.splice(index, 1);
2915
- setCurrentFrame(index);
2916
- emit("deleteFrame", index);
2917
- }
2918
- function setCurrentFrame(index = currentFrameIndex.value) {
2919
- index = Math.max(0, Math.min(frames.value.length - 1, index));
2920
- const oldIndex = currentFrameIndex.value;
2921
- currentFrameIndex.value = index;
2922
- if (config.value.viewMode === "edgeless") {
2923
- selection.value = [frames.value[index]];
2924
- } else {
2925
- selection.value = [];
2926
- }
2927
- emit("setCurrentFrame", index, oldIndex);
2928
- }
2929
- Object.assign(editor, {
2930
- addFrame,
2931
- duplicateFrame,
2932
- moveFrame,
2933
- deleteFrame,
2934
- setCurrentFrame
2935
- });
2936
- });
2937
2802
  const _4_4_doc = defineMixin((editor, options) => {
2938
2803
  const {
2939
2804
  doc,
@@ -3389,8 +3254,8 @@ const mixins = [
3389
3254
  _3_view,
3390
3255
  _4_0_node,
3391
3256
  _4_1_text,
3392
- _4_2_element,
3393
- _4_3_frame,
3257
+ _4_2_frame,
3258
+ _4_3_element,
3394
3259
  _4_4_doc,
3395
3260
  _drawingTool$1,
3396
3261
  _scroll$1,
@@ -3423,7 +3288,7 @@ const _clipboard = definePlugin((editor, options) => {
3423
3288
  exec,
3424
3289
  canLoad,
3425
3290
  load,
3426
- addElement
3291
+ addElements
3427
3292
  } = editor;
3428
3293
  const copiedData = ref();
3429
3294
  const useClipboard = options.clipboard !== false && SUPPORTS_CLIPBOARD;
@@ -3485,7 +3350,7 @@ const _clipboard = definePlugin((editor, options) => {
3485
3350
  }
3486
3351
  }
3487
3352
  if (elements.length) {
3488
- addElement(elements, {
3353
+ addElements(elements, {
3489
3354
  position: "pointer",
3490
3355
  active: true,
3491
3356
  regenId: true
@@ -3536,7 +3401,7 @@ const _clipboard = definePlugin((editor, options) => {
3536
3401
  await _paste(await navigator.clipboard.read());
3537
3402
  } else if (copiedData.value) {
3538
3403
  if (Array.isArray(copiedData.value)) {
3539
- addElement(copiedData.value?.map((el) => cloneDeep(el)) ?? [], {
3404
+ addElements(copiedData.value?.map((el) => cloneDeep(el)) ?? [], {
3540
3405
  position: "pointer",
3541
3406
  active: true,
3542
3407
  regenId: true
@@ -3552,7 +3417,7 @@ const _clipboard = definePlugin((editor, options) => {
3552
3417
  if (!selection.value.length) {
3553
3418
  return;
3554
3419
  }
3555
- addElement(
3420
+ addElements(
3556
3421
  selection.value.map((v) => v.toJSON()),
3557
3422
  {
3558
3423
  parent: selection.value[0].parent,
@@ -3621,14 +3486,13 @@ const _copyAs = definePlugin((editor) => {
3621
3486
  });
3622
3487
  const _delete = definePlugin((editor) => {
3623
3488
  const {
3624
- deleteElement,
3625
3489
  selection,
3626
3490
  hoverElement
3627
3491
  } = editor;
3628
3492
  function _delete2() {
3629
3493
  if (selection.value.length) {
3630
- selection.value.forEach((element) => {
3631
- deleteElement(element.id);
3494
+ selection.value.forEach((node) => {
3495
+ node.remove();
3632
3496
  });
3633
3497
  selection.value = [];
3634
3498
  }
@@ -3879,23 +3743,36 @@ function useIcon(props) {
3879
3743
  const MceLayerKey = Symbol.for("mce:layer");
3880
3744
  const MceLayerItemKey = Symbol.for("mce:layer-item");
3881
3745
  function createLayer(options) {
3882
- const {
3883
- sortedSelection
3884
- } = options;
3885
3746
  const registered = ref([]);
3886
- const selecting = ref(false);
3747
+ const nodeItems = /* @__PURE__ */ new Map();
3887
3748
  const openedItems = reactive(/* @__PURE__ */ new Map());
3888
3749
  const domItems = reactive(/* @__PURE__ */ new Map());
3889
3750
  const rootVm = getCurrentInstance();
3751
+ const selecting = ref(false);
3752
+ const dragging = ref(false);
3753
+ const droppingItemId = ref();
3754
+ function getIdByNode(node) {
3755
+ let id;
3756
+ nodeItems.forEach((_node2, _id) => {
3757
+ if (node.equal(_node2.value)) {
3758
+ id = _id;
3759
+ }
3760
+ });
3761
+ return id;
3762
+ }
3890
3763
  provide(MceLayerKey, {
3764
+ ...options,
3891
3765
  selecting,
3892
- sortedSelection,
3893
- register: (vm, options2) => {
3766
+ dragging,
3767
+ droppingItemId,
3768
+ register: (vm, item) => {
3894
3769
  const {
3895
3770
  id,
3896
3771
  dom,
3897
- opened
3898
- } = options2;
3772
+ opened,
3773
+ node
3774
+ } = item;
3775
+ nodeItems.set(id, node);
3899
3776
  openedItems.set(id, opened);
3900
3777
  domItems.set(id, dom);
3901
3778
  registered.value.push(id);
@@ -3908,34 +3785,79 @@ function createLayer(options) {
3908
3785
  }
3909
3786
  },
3910
3787
  unregister: (id) => {
3788
+ nodeItems.delete(id);
3911
3789
  openedItems.delete(id);
3912
3790
  domItems.delete(id);
3913
3791
  registered.value = registered.value.filter((v) => v !== id);
3792
+ },
3793
+ onMousedown: (e, id) => {
3794
+ const start = { x: e.clientX, y: e.clientY };
3795
+ function onMove(e2) {
3796
+ const current = { x: e2.clientX, y: e2.clientY };
3797
+ if (!dragging.value && (Math.abs(current.x - start.x) >= 3 || Math.abs(current.y - start.y) >= 3)) {
3798
+ dragging.value = true;
3799
+ }
3800
+ if (dragging.value) {
3801
+ const targets = e2.composedPath();
3802
+ const layer = targets.find((target) => {
3803
+ return target instanceof HTMLElement && target.classList.contains("mce-layer");
3804
+ });
3805
+ const id2 = layer?.dataset?.id;
3806
+ if (id2) {
3807
+ droppingItemId.value = id2;
3808
+ }
3809
+ }
3810
+ }
3811
+ function onUp() {
3812
+ if (droppingItemId.value) {
3813
+ const from = nodeItems.get(id)?.value;
3814
+ const to = nodeItems.get(droppingItemId.value)?.value;
3815
+ if (to && from && !from.equal(to)) {
3816
+ let toIndex = to.getIndex() + 1;
3817
+ if (to.parent && from.parent && to.parent.equal(from.parent)) {
3818
+ toIndex--;
3819
+ }
3820
+ to.parent?.moveChild(
3821
+ from,
3822
+ toIndex
3823
+ );
3824
+ }
3825
+ }
3826
+ dragging.value = false;
3827
+ droppingItemId.value = void 0;
3828
+ document.removeEventListener("mousemove", onMove);
3829
+ document.removeEventListener("mouseup", onUp);
3830
+ }
3831
+ document.addEventListener("mousemove", onMove);
3832
+ document.addEventListener("mouseup", onUp);
3914
3833
  }
3915
3834
  });
3916
3835
  return {
3917
3836
  selecting,
3918
3837
  openedItems,
3919
- domItems
3838
+ domItems,
3839
+ getIdByNode
3920
3840
  };
3921
3841
  }
3922
3842
  function useLayerItem(options) {
3923
- const {
3843
+ const root = inject(MceLayerKey);
3844
+ if (!root)
3845
+ throw new Error("[mce] Could not find injected layer root");
3846
+ const id = `layer-item-${useId()}`;
3847
+ const item = {
3924
3848
  id,
3925
- opened,
3926
- dom
3927
- } = options;
3849
+ ...options
3850
+ };
3928
3851
  const vm = getCurrentInstance();
3929
3852
  provide(MceLayerItemKey, { id });
3930
- const rootLayer = inject(MceLayerKey);
3931
- const { register, unregister, ...props } = rootLayer;
3932
- register(vm, {
3853
+ root.register(vm, item);
3854
+ onBeforeUnmount(() => root.unregister(id));
3855
+ return {
3856
+ ...root,
3933
3857
  id,
3934
- dom,
3935
- opened
3936
- });
3937
- onBeforeUnmount(() => unregister(id));
3938
- return props;
3858
+ dropping: computed(() => root.droppingItemId.value === id),
3859
+ onMousedown: (e) => root.onMousedown?.(e, id)
3860
+ };
3939
3861
  }
3940
3862
  function useResizeObserver(callback, box = "content") {
3941
3863
  const resizeRef = templateRef();
@@ -4354,7 +4276,7 @@ const _sfc_main$B = /* @__PURE__ */ defineComponent({
4354
4276
  }
4355
4277
  return (_ctx, _cache) => {
4356
4278
  return withDirectives((openBlock(), createElementBlock("div", {
4357
- style: normalizeStyle(unref(boundingBoxToStyle)(unref(getObb)(frame.value, "drawboard"))),
4279
+ style: normalizeStyle(unref(getObb)(frame.value, "drawboard").toCssStyle()),
4358
4280
  class: normalizeClass(["mce-frame", [
4359
4281
  unref(config).frameOutline && "mce-frame--outline",
4360
4282
  unref(hoverElement)?.equal(frame.value) && "mce-frame--hover",
@@ -4495,7 +4417,7 @@ const _group = definePlugin((editor) => {
4495
4417
  getAabb,
4496
4418
  elementSelection,
4497
4419
  addElement,
4498
- deleteElement,
4420
+ addElements,
4499
4421
  doc
4500
4422
  } = editor;
4501
4423
  function group(inEditorIs) {
@@ -4515,7 +4437,12 @@ const _group = definePlugin((editor) => {
4515
4437
  doc.value.transact(() => {
4516
4438
  addElement({
4517
4439
  name: inEditorIs === "Frame" ? "Frame" : "Group",
4518
- style: { ...aabb },
4440
+ style: {
4441
+ left: aabb.left,
4442
+ top: aabb.top,
4443
+ width: aabb.width,
4444
+ height: aabb.height
4445
+ },
4519
4446
  children,
4520
4447
  meta: {
4521
4448
  inPptIs: "GroupShape",
@@ -4527,7 +4454,7 @@ const _group = definePlugin((editor) => {
4527
4454
  active: true,
4528
4455
  regenId: true
4529
4456
  });
4530
- elements.forEach((v) => deleteElement(v.id));
4457
+ elements.forEach((node) => node.remove());
4531
4458
  });
4532
4459
  }
4533
4460
  function ungroup() {
@@ -4543,13 +4470,13 @@ const _group = definePlugin((editor) => {
4543
4470
  return cloned;
4544
4471
  });
4545
4472
  doc.value.transact(() => {
4546
- addElement(items, {
4473
+ addElements(items, {
4547
4474
  parent: element.parent,
4548
4475
  index: element.getIndex(),
4549
4476
  active: true,
4550
4477
  regenId: true
4551
4478
  });
4552
- deleteElement(element.id);
4479
+ element.remove();
4553
4480
  });
4554
4481
  }
4555
4482
  return {
@@ -4762,11 +4689,11 @@ const _import = definePlugin((editor) => {
4762
4689
  const {
4763
4690
  load,
4764
4691
  openFileDialog,
4765
- addElement
4692
+ addElements
4766
4693
  } = editor;
4767
4694
  const _import2 = async (options = {}) => {
4768
4695
  const files = await openFileDialog({ multiple: true });
4769
- return addElement((await Promise.all(files.map((file) => load(file)))).flat(), {
4696
+ return addElements((await Promise.all(files.map((file) => load(file)))).flat(), {
4770
4697
  sizeToFit: true,
4771
4698
  ...options
4772
4699
  });
@@ -4788,10 +4715,10 @@ const _import = definePlugin((editor) => {
4788
4715
  } = editor;
4789
4716
  function onDragover(e) {
4790
4717
  e.preventDefault();
4791
- drawboardPointer.value = {
4792
- x: e.clientX - drawboardAabb.value.left,
4793
- y: e.clientY - drawboardAabb.value.top
4794
- };
4718
+ drawboardPointer.value = new Vector2$1(
4719
+ e.clientX - drawboardAabb.value.left,
4720
+ e.clientY - drawboardAabb.value.top
4721
+ );
4795
4722
  if (e.dataTransfer) {
4796
4723
  e.dataTransfer.dropEffect = "copy";
4797
4724
  }
@@ -5056,8 +4983,10 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
5056
4983
  };
5057
4984
  }
5058
4985
  });
5059
- const _hoisted_1$l = { class: "mce-layer__name" };
5060
- const _hoisted_2$c = { class: "mce-layer__action" };
4986
+ const _hoisted_1$l = ["data-id"];
4987
+ const _hoisted_2$c = { class: "mce-layer__content" };
4988
+ const _hoisted_3$b = { class: "mce-layer__prepend" };
4989
+ const _hoisted_4$5 = { class: "mce-layer__action" };
5061
4990
  const _sfc_main$x = /* @__PURE__ */ defineComponent({
5062
4991
  ...{
5063
4992
  name: "MceLayer",
@@ -5100,9 +5029,12 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5100
5029
  const dom = ref();
5101
5030
  const {
5102
5031
  selecting,
5103
- sortedSelection
5032
+ sortedSelection,
5033
+ dragging,
5034
+ dropping,
5035
+ onMousedown,
5036
+ id
5104
5037
  } = useLayerItem({
5105
- id: props.node.id,
5106
5038
  opened,
5107
5039
  node: computed(() => props.node),
5108
5040
  dom: computed(() => dom.value)
@@ -5140,12 +5072,10 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5140
5072
  }
5141
5073
  return "$shape";
5142
5074
  });
5143
- function onMousedown() {
5144
- }
5145
5075
  function onClickExpand() {
5146
5076
  opened.value = !opened.value;
5147
5077
  }
5148
- function onClickContent(e) {
5078
+ function onMousedownContent(e) {
5149
5079
  selecting.value = true;
5150
5080
  if (e.shiftKey) {
5151
5081
  const _nodes = [
@@ -5190,6 +5120,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5190
5120
  nextTick().then(() => {
5191
5121
  selecting.value = false;
5192
5122
  });
5123
+ onMousedown(e);
5193
5124
  }
5194
5125
  function onDblclickThumbnail(e) {
5195
5126
  e.stopPropagation();
@@ -5199,7 +5130,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5199
5130
  });
5200
5131
  }
5201
5132
  }
5202
- function onDblclickContent() {
5133
+ function onDblclickName() {
5203
5134
  editing.value = true;
5204
5135
  editValue.value = props.node.name;
5205
5136
  nextTick().then(() => {
@@ -5211,7 +5142,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5211
5142
  });
5212
5143
  }
5213
5144
  function onMouseenter() {
5214
- if (isElement(props.node)) {
5145
+ if (!dragging.value && isElement(props.node)) {
5215
5146
  hoverElement.value = props.node;
5216
5147
  hovering.value = true;
5217
5148
  }
@@ -5245,41 +5176,44 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5245
5176
  isFrist.value && "mce-layer--first",
5246
5177
  isLast.value && "mce-layer--last",
5247
5178
  opened.value && "mce-layer--open",
5248
- isHoverElement.value && "mce-layer--hover"
5179
+ isHoverElement.value && "mce-layer--hover",
5180
+ unref(dropping) && "mce-layer--dropping"
5249
5181
  ]]),
5250
5182
  style: normalizeStyle({
5251
5183
  "--indent-padding": `${props.indent * 16}px`
5252
5184
  }),
5253
- onMousedown,
5185
+ "data-id": unref(id),
5186
+ onMousedown: onMousedownContent,
5254
5187
  onMouseenter,
5255
5188
  onMouseleave,
5256
5189
  onContextmenu
5257
5190
  }, [
5258
- createElementVNode("div", {
5259
- class: "mce-layer__expand",
5260
- onClick: onClickExpand
5261
- }, [
5262
- props.node.children.length ? (openBlock(), createBlock(unref(_sfc_main$C), {
5263
- key: 0,
5264
- icon: "$arrowRight"
5265
- })) : createCommentVNode("", true)
5266
- ]),
5267
- createElementVNode("div", {
5268
- class: "mce-layer__content",
5269
- onClick: onClickContent,
5270
- onDblclick: onDblclickContent
5271
- }, [
5191
+ _cache[5] || (_cache[5] = createElementVNode("span", { class: "mce-layer__underlay" }, null, -1)),
5192
+ _cache[6] || (_cache[6] = createElementVNode("span", { class: "mce-layer__overlay" }, null, -1)),
5193
+ createElementVNode("div", _hoisted_2$c, [
5194
+ createElementVNode("div", _hoisted_3$b, [
5195
+ props.node.children.length ? (openBlock(), createBlock(unref(_sfc_main$C), {
5196
+ key: 0,
5197
+ icon: "$arrowRight",
5198
+ onClick: onClickExpand,
5199
+ onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {
5200
+ }, ["stop"]))
5201
+ })) : createCommentVNode("", true)
5202
+ ]),
5272
5203
  createElementVNode("div", {
5273
5204
  class: "mce-layer__thumbnail",
5274
5205
  onDblclick: onDblclickThumbnail
5275
5206
  }, [
5276
5207
  createVNode(unref(_sfc_main$C), { icon: thumbnailIcon.value }, null, 8, ["icon"])
5277
5208
  ], 32),
5278
- createElementVNode("div", _hoisted_1$l, [
5209
+ createElementVNode("div", {
5210
+ class: "mce-layer__name",
5211
+ onDblclick: onDblclickName
5212
+ }, [
5279
5213
  withDirectives(createElementVNode("input", {
5280
5214
  ref_key: "inputDom",
5281
5215
  ref: inputDom,
5282
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => editValue.value = $event),
5216
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => editValue.value = $event),
5283
5217
  type: "text",
5284
5218
  class: "mce-layer__input",
5285
5219
  autofocus: "",
@@ -5291,15 +5225,15 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5291
5225
  createElementVNode("div", {
5292
5226
  style: normalizeStyle({ visibility: editing.value ? "hidden" : void 0 })
5293
5227
  }, toDisplayString(editValue.value || props.node.name || props.node.id), 5)
5294
- ]),
5295
- createElementVNode("div", _hoisted_2$c, [
5228
+ ], 32),
5229
+ createElementVNode("div", _hoisted_4$5, [
5296
5230
  props.root ? (openBlock(), createBlock(_sfc_main$y, {
5297
5231
  key: 0,
5298
5232
  icon: "",
5299
5233
  class: normalizeClass(["mce-layer__btn", {
5300
5234
  "mce-layer__btn--hide": !hovering.value && !unref(isLock)(props.node)
5301
5235
  }]),
5302
- onClick: _cache[1] || (_cache[1] = ($event) => unref(setLock)(props.node, !unref(isLock)(props.node)))
5236
+ onClick: _cache[2] || (_cache[2] = ($event) => unref(setLock)(props.node, !unref(isLock)(props.node)))
5303
5237
  }, {
5304
5238
  default: withCtx(() => [
5305
5239
  createVNode(unref(_sfc_main$C), {
@@ -5313,7 +5247,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5313
5247
  class: normalizeClass(["mce-layer__btn", {
5314
5248
  "mce-layer__btn--hide": !hovering.value && !unref(isLock)(props.node)
5315
5249
  }]),
5316
- onClick: _cache[2] || (_cache[2] = withModifiers(($event) => unref(setLock)(props.node, !unref(isLock)(props.node)), ["prevent", "stop"]))
5250
+ onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(setLock)(props.node, !unref(isLock)(props.node)), ["prevent", "stop"]))
5317
5251
  }, {
5318
5252
  default: withCtx(() => [
5319
5253
  createVNode(unref(_sfc_main$C), {
@@ -5327,7 +5261,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5327
5261
  class: normalizeClass(["mce-layer__btn", {
5328
5262
  "mce-layer__btn--hide": !hovering.value && unref(isVisible)(props.node)
5329
5263
  }]),
5330
- onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(setVisible)(props.node, !unref(isVisible)(props.node)), ["prevent", "stop"]))
5264
+ onClick: _cache[4] || (_cache[4] = withModifiers(($event) => unref(setVisible)(props.node, !unref(isVisible)(props.node)), ["prevent", "stop"]))
5331
5265
  }, {
5332
5266
  default: withCtx(() => [
5333
5267
  createVNode(unref(_sfc_main$C), {
@@ -5338,8 +5272,8 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5338
5272
  }, 8, ["class"])
5339
5273
  ], 64))
5340
5274
  ])
5341
- ], 32)
5342
- ], 38),
5275
+ ])
5276
+ ], 46, _hoisted_1$l),
5343
5277
  opened.value ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.node.children, (child, key) => {
5344
5278
  return openBlock(), createBlock(_component_MceLayer, {
5345
5279
  key,
@@ -5374,7 +5308,8 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
5374
5308
  const {
5375
5309
  selecting,
5376
5310
  openedItems,
5377
- domItems
5311
+ domItems,
5312
+ getIdByNode
5378
5313
  } = createLayer({
5379
5314
  sortedSelection
5380
5315
  });
@@ -5385,7 +5320,7 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
5385
5320
  let last;
5386
5321
  selection2.forEach((node) => {
5387
5322
  node.findAncestor((ancestor) => {
5388
- const opened = openedItems.get(ancestor.id);
5323
+ const opened = openedItems.get(getIdByNode(ancestor) ?? "");
5389
5324
  if (opened) {
5390
5325
  opened.value = true;
5391
5326
  }
@@ -5395,7 +5330,7 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
5395
5330
  });
5396
5331
  if (last) {
5397
5332
  nextTick().then(() => {
5398
- domItems.get(last.id)?.value?.scrollIntoView({
5333
+ domItems.get(getIdByNode(last) ?? "")?.value?.scrollIntoView({
5399
5334
  block: "center"
5400
5335
  });
5401
5336
  });
@@ -5863,10 +5798,10 @@ const _sfc_main$s = /* @__PURE__ */ defineComponent({
5863
5798
  x: event.clientX,
5864
5799
  y: event.clientY
5865
5800
  };
5866
- drawboardContextMenuPointer.value = {
5867
- x: event.clientX - drawboardAabb.value.left,
5868
- y: event.clientY - drawboardAabb.value.top
5869
- };
5801
+ drawboardContextMenuPointer.value = new Vector2$1(
5802
+ event.clientX - drawboardAabb.value.left,
5803
+ event.clientY - drawboardAabb.value.top
5804
+ );
5870
5805
  updateLocation();
5871
5806
  }
5872
5807
  watch(drawboardDom, (el, old) => {
@@ -8002,16 +7937,16 @@ function getIntersectionPoint(p1, p2, q1, q2) {
8002
7937
  );
8003
7938
  }
8004
7939
  function cross(ax, ay, bx, by, cx, cy) {
8005
- return (bx - ax) * (cy - ay) - (cx - ax) * (by - ay);
7940
+ return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);
8006
7941
  }
8007
- function windingNumber(px, py, path) {
8008
- const pathsLen = path.length;
7942
+ function windingNumber(px, py, polygon) {
7943
+ const polygonLen = polygon.length;
8009
7944
  let wn = 0;
8010
- for (let i = 0, j = pathsLen - 2; i < pathsLen; j = i, i += 2) {
8011
- const xi = path[i];
8012
- const yi = path[i + 1];
8013
- const xj = path[j];
8014
- const yj = path[j + 1];
7945
+ for (let i = 0, j = polygonLen - 2; i < polygonLen; j = i, i += 2) {
7946
+ const xi = polygon[i];
7947
+ const yi = polygon[i + 1];
7948
+ const xj = polygon[j];
7949
+ const yj = polygon[j + 1];
8015
7950
  if (yi <= py) {
8016
7951
  if (yj > py && cross(xj, yj, xi, yi, px, py) > 0)
8017
7952
  wn++;
@@ -8028,41 +7963,105 @@ function distance(p1, p2) {
8028
7963
  return Math.sqrt(dx * dx + dy * dy);
8029
7964
  }
8030
7965
  function nonzeroFillRule(paths) {
8031
- const pathsLen = paths.length;
8032
- const results = paths.map((_, i) => ({
8033
- index: i,
8034
- dist: 0,
8035
- wn: 0,
8036
- parentIndex: void 0
8037
- }));
8038
- for (let i = 0; i < pathsLen; i++) {
8039
- const pointArray = paths[i];
8040
- const testPointArray = [
8041
- pointArray[0],
8042
- pointArray[1]
8043
- ];
8044
- let parent;
8045
- let totalWn = 0;
8046
- for (let j = 0; j < pathsLen; j++) {
8047
- if (i === j) {
8048
- continue;
7966
+ const results = paths.map((_, i) => ({ index: i }));
7967
+ const testPointsGroups = paths.map((path) => {
7968
+ const len = path.length;
7969
+ if (!len) {
7970
+ return [];
7971
+ }
7972
+ let xMinYAuto = [Number.MAX_SAFE_INTEGER, 0];
7973
+ let xAutoYMin = [0, Number.MAX_SAFE_INTEGER];
7974
+ let xMaxYAuto = [Number.MIN_SAFE_INTEGER, 0];
7975
+ let xAutoYMax = [0, Number.MIN_SAFE_INTEGER];
7976
+ for (let i = 0; i < len; i += 2) {
7977
+ const x = path[i];
7978
+ const y = path[i + 1];
7979
+ if (xMinYAuto[0] > x) {
7980
+ xMinYAuto = [x, y];
8049
7981
  }
8050
- let wn = 0;
8051
- for (let p = 0; p < testPointArray.length; p += 2) {
8052
- wn = windingNumber(testPointArray[p], testPointArray[p + 1], paths[j]);
7982
+ if (xAutoYMin[1] > y) {
7983
+ xAutoYMin = [x, y];
8053
7984
  }
8054
- if (wn !== 0) {
8055
- totalWn += wn;
8056
- const dist = distance(testPointArray, paths[j]);
8057
- if (!parent || dist < parent.dist) {
8058
- parent = { index: j, dist, wn };
8059
- }
7985
+ if (xMaxYAuto[0] < x) {
7986
+ xMaxYAuto = [x, y];
7987
+ }
7988
+ if (xAutoYMax[1] < y) {
7989
+ xAutoYMax = [x, y];
7990
+ }
7991
+ }
7992
+ const mid = [
7993
+ (xMinYAuto[0] + xMaxYAuto[0]) / 2,
7994
+ (xAutoYMin[1] + xAutoYMax[1]) / 2
7995
+ ];
7996
+ let xMidYMinDx;
7997
+ let xMidYMaxDx;
7998
+ let xMidYMin;
7999
+ let xMidYMax;
8000
+ let xMinYMidDy;
8001
+ let xMaxYMidDy;
8002
+ let xMinYMid;
8003
+ let xMaxYMid;
8004
+ for (let i = 0; i < len; i += 2) {
8005
+ const x = path[i];
8006
+ const y = path[i + 1];
8007
+ const _dx = Math.abs(x - mid[0]);
8008
+ const _dy = Math.abs(y - mid[1]);
8009
+ if (y < mid[1] && (!xMidYMinDx || _dx < xMidYMinDx)) {
8010
+ xMidYMinDx = _dx;
8011
+ xMidYMin = [x, y];
8012
+ }
8013
+ if (y > mid[1] && (!xMidYMaxDx || _dx < xMidYMaxDx)) {
8014
+ xMidYMaxDx = _dx;
8015
+ xMidYMax = [x, y];
8016
+ }
8017
+ if (x < mid[0] && (!xMinYMidDy || _dy < xMinYMidDy)) {
8018
+ xMinYMidDy = _dy;
8019
+ xMinYMid = [x, y];
8020
+ }
8021
+ if (x > mid[0] && (!xMaxYMidDy || _dy < xMaxYMidDy)) {
8022
+ xMaxYMidDy = _dy;
8023
+ xMaxYMid = [x, y];
8024
+ }
8025
+ }
8026
+ return [
8027
+ xMinYAuto,
8028
+ xAutoYMin,
8029
+ xMaxYAuto,
8030
+ xAutoYMax,
8031
+ xMidYMin,
8032
+ xMidYMax,
8033
+ xMinYMid,
8034
+ xMaxYMid
8035
+ ].filter(Boolean);
8036
+ });
8037
+ for (let i = 0, len = paths.length; i < len; i++) {
8038
+ const _results = [];
8039
+ const testPoints = testPointsGroups[i];
8040
+ for (let j = 0; j < len; j++) {
8041
+ if (i === j)
8042
+ continue;
8043
+ const wnMap = {};
8044
+ const wnList = [];
8045
+ for (let p = 0, pLen = testPoints.length; p < pLen; p++) {
8046
+ const [x, y] = testPoints[p];
8047
+ const winding = windingNumber(x, y, paths[j]);
8048
+ wnMap[winding] = (wnMap[winding] ?? 0) + 1;
8049
+ wnList.push(winding);
8050
+ }
8051
+ if (wnList.filter((v) => v !== 0).length > wnList.filter((v) => v === 0).length) {
8052
+ _results.push({
8053
+ index: i,
8054
+ parentIndex: j,
8055
+ winding: Number(
8056
+ Array.from(Object.entries(wnMap)).sort((a, b) => b[1] - a[1])?.[0]?.[0] ?? 0
8057
+ ),
8058
+ dist: distance(testPointsGroups[i][0], testPointsGroups[j][0])
8059
+ });
8060
8060
  }
8061
8061
  }
8062
- if (totalWn !== 0 && parent) {
8063
- results[i].dist = parent.dist;
8064
- results[i].wn = parent.wn;
8065
- results[i].parentIndex = parent.index;
8062
+ if (_results.reduce((total, item) => total + item.winding, 0) !== 0) {
8063
+ _results.sort((a, b) => a.dist - b.dist);
8064
+ results[i] = _results[0];
8066
8065
  }
8067
8066
  }
8068
8067
  return results;
@@ -10161,7 +10160,7 @@ class Path2D extends CompositeCurve {
10161
10160
  for (let i = 0; i < groupsLen; i++) {
10162
10161
  const groupA = groups[i];
10163
10162
  const pointArray = paths[i];
10164
- if (groupA.wn || !pointArray.length) {
10163
+ if (groupA.winding || !pointArray.length) {
10165
10164
  continue;
10166
10165
  }
10167
10166
  const _pointArray = pointArray.slice();
@@ -10288,8 +10287,8 @@ const _pen = definePlugin((editor) => {
10288
10287
  const box = currentPath.getBoundingBox();
10289
10288
  el.style.left = box.left;
10290
10289
  el.style.top = box.top;
10291
- el.style.width = box.width;
10292
- el.style.height = box.height;
10290
+ el.style.width = box.width || 1;
10291
+ el.style.height = box.height || 1;
10293
10292
  }
10294
10293
  };
10295
10294
  return {
@@ -10310,6 +10309,10 @@ const _pen = definePlugin((editor) => {
10310
10309
  } else {
10311
10310
  el = addElement({
10312
10311
  name: "pen",
10312
+ style: {
10313
+ width: 1,
10314
+ height: 1
10315
+ },
10313
10316
  outline: {
10314
10317
  color: "#d9d9d9",
10315
10318
  width: 5,
@@ -10328,6 +10331,7 @@ const _pen = definePlugin((editor) => {
10328
10331
  new Vector2(start.x, start.y)
10329
10332
  );
10330
10333
  currentPath.currentCurve.addCurve(currentLine);
10334
+ update();
10331
10335
  const onMove = () => {
10332
10336
  const move = getGlobalPointer();
10333
10337
  if (currentLine && move) {
@@ -10352,6 +10356,10 @@ const _pen = definePlugin((editor) => {
10352
10356
  handle: (start) => {
10353
10357
  const el2 = addElement({
10354
10358
  name: "pencil",
10359
+ style: {
10360
+ width: 1,
10361
+ height: 1
10362
+ },
10355
10363
  outline: {
10356
10364
  color: "#d9d9d9",
10357
10365
  width: 5,
@@ -10364,20 +10372,25 @@ const _pen = definePlugin((editor) => {
10364
10372
  }, {
10365
10373
  position: start
10366
10374
  });
10375
+ const parentAabb = el2.getParent()?.getGlobalAabb() ?? new Aabb2D();
10367
10376
  const path = new Path2D();
10368
- path.moveTo(start.x, start.y);
10377
+ path.moveTo(start.x - parentAabb.x, start.y - parentAabb.y);
10378
+ const update2 = () => {
10379
+ el2.shape.paths = [
10380
+ { data: path.toData() }
10381
+ ];
10382
+ const box = path.getBoundingBox();
10383
+ el2.style.left = box.left;
10384
+ el2.style.top = box.top;
10385
+ el2.style.width = box.width || 1;
10386
+ el2.style.height = box.height || 1;
10387
+ };
10388
+ update2();
10369
10389
  return {
10370
10390
  move: (move) => {
10371
- path.lineTo(move.x, move.y);
10372
- path.moveTo(move.x, move.y);
10373
- el2.shape.paths = [
10374
- { data: path.toData() }
10375
- ];
10376
- const box = path.getBoundingBox();
10377
- el2.style.left = box.left;
10378
- el2.style.top = box.top;
10379
- el2.style.width = box.width;
10380
- el2.style.height = box.height;
10391
+ path.lineTo(move.x - parentAabb.x, move.y - parentAabb.y);
10392
+ path.moveTo(move.x - parentAabb.x, move.y - parentAabb.y);
10393
+ update2();
10381
10394
  }
10382
10395
  };
10383
10396
  }
@@ -11025,8 +11038,7 @@ const _sfc_main$l = /* @__PURE__ */ defineComponent({
11025
11038
  exec
11026
11039
  } = useEditor();
11027
11040
  const isActive = computed(() => {
11028
- return selectionAabb.value.width && selectionAabb.value.height && !isOverlappingAabb(
11029
- drawboardAabb.value,
11041
+ return selectionAabb.value.width && selectionAabb.value.height && !drawboardAabb.value.overlapsOnAxis(
11030
11042
  aabbToDrawboardAabb(selectionAabb.value)
11031
11043
  );
11032
11044
  });
@@ -12322,9 +12334,9 @@ const _smartGuides = definePlugin((editor) => {
12322
12334
  const isCanvas = isCanvasLine(target);
12323
12335
  if (type !== target.type && !isCanvas)
12324
12336
  return;
12325
- if (!isOverlappingAabb(toBoundingBox(source), toBoundingBox(target), flippedAxis))
12337
+ if (!toBoundingBox(source).overlapsOnAxis(toBoundingBox(target), flippedAxis))
12326
12338
  return;
12327
- if (!isCanvas && prev && prev.box.id !== target.box.id && isOverlappingAabb(toBoundingBox(prev), toBoundingBox(target), axis)) {
12339
+ if (!isCanvas && prev && prev.box.id !== target.box.id && toBoundingBox(prev).overlapsOnAxis(toBoundingBox(target), axis)) {
12328
12340
  return;
12329
12341
  }
12330
12342
  prev = target;
@@ -12582,12 +12594,12 @@ function createLine(pos, type, box) {
12582
12594
  }
12583
12595
  function toBoundingBox(value) {
12584
12596
  const box = "box" in value ? value.box : value;
12585
- return {
12586
- left: box.hl.pos,
12587
- top: box.vt.pos,
12597
+ return new Aabb2D({
12598
+ x: box.hl.pos,
12599
+ y: box.vt.pos,
12588
12600
  width: box.hr.pos - box.hl.pos,
12589
12601
  height: box.vb.pos - box.vt.pos
12590
- };
12602
+ });
12591
12603
  }
12592
12604
  function flipType(type) {
12593
12605
  if (type === "vt")
@@ -13342,29 +13354,25 @@ const _ui = definePlugin((editor) => {
13342
13354
  }
13343
13355
  };
13344
13356
  });
13345
- const _url = definePlugin(() => {
13346
- async function isImage(url) {
13347
- try {
13348
- const response = await fetch(url, { method: "HEAD" });
13349
- const contentType = response.headers.get("Content-Type");
13350
- return contentType && contentType.startsWith("image/");
13351
- } catch (_error) {
13352
- return false;
13353
- }
13354
- }
13357
+ const _url = definePlugin((editor) => {
13358
+ const {
13359
+ load
13360
+ } = editor;
13355
13361
  return {
13356
13362
  name: "mce:url",
13357
13363
  loaders: [
13358
13364
  {
13359
13365
  name: "url",
13360
13366
  test: (source) => {
13361
- return typeof source === "string" && (source.startsWith("http") || imageExtRe.test(source));
13367
+ return typeof source === "string";
13362
13368
  },
13363
- load: async (source) => {
13364
- if (imageExtRe.test(source) || await isImage(source)) {
13365
- return await createImageElement(source);
13366
- } else {
13367
- throw new Error(`Failed to load url, ${source}`);
13369
+ load: async (url) => {
13370
+ const blob = await fetch(url).then((rep) => rep.blob());
13371
+ const file = new File([blob], url, { type: blob.type });
13372
+ try {
13373
+ return await load(file);
13374
+ } catch (error) {
13375
+ throw new Error(`Failed to load source "${url}", ${error}`);
13368
13376
  }
13369
13377
  }
13370
13378
  }
@@ -13463,7 +13471,7 @@ const _zoom = definePlugin((editor) => {
13463
13471
  useResizeObserver$1(drawboardDom, (entries) => {
13464
13472
  const { left: _left, top: _top, width, height } = entries[0].contentRect;
13465
13473
  const { left = _left, top = _top } = drawboardDom.value?.getBoundingClientRect() ?? {};
13466
- drawboardAabb.value = { left, top, width, height };
13474
+ drawboardAabb.value = new Aabb2D(left, top, width, height);
13467
13475
  exec("zoomToFit");
13468
13476
  });
13469
13477
  }
@@ -14514,7 +14522,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
14514
14522
  __name: "Selector",
14515
14523
  props: {
14516
14524
  resizeStrategy: {},
14517
- selectedArea: { default: () => ({ left: 0, top: 0, width: 0, height: 0 }) }
14525
+ selectedArea: { default: () => new Aabb2D() }
14518
14526
  },
14519
14527
  setup(__props, { expose: __expose }) {
14520
14528
  const props = __props;
@@ -14535,7 +14543,8 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
14535
14543
  isLock,
14536
14544
  config,
14537
14545
  snapThreshold,
14538
- getSnapPoints
14546
+ getSnapPoints,
14547
+ handleElementInsideFrame
14539
14548
  } = useEditor();
14540
14549
  const transformable = useTemplateRef("transformableTpl");
14541
14550
  onBeforeMount(() => {
@@ -14570,8 +14579,13 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
14570
14579
  });
14571
14580
  const _selectionTransform = computed(() => {
14572
14581
  const zoom = camera.value.zoom;
14582
+ const { left, top, width, height, rotationDegrees } = selectionObbInDrawboard.value;
14573
14583
  return {
14574
- ...selectionObbInDrawboard.value,
14584
+ left,
14585
+ top,
14586
+ width,
14587
+ height,
14588
+ rotate: rotationDegrees,
14575
14589
  borderRadius: (elementSelection.value[0]?.style.borderRadius ?? 0) * zoom.x
14576
14590
  };
14577
14591
  });
@@ -14643,6 +14657,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
14643
14657
  }
14644
14658
  return false;
14645
14659
  });
14660
+ handleElementInsideFrame(element);
14646
14661
  });
14647
14662
  }
14648
14663
  });
@@ -14680,7 +14695,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
14680
14695
  class: "mce-selector__parent-element",
14681
14696
  style: normalizeStyle({
14682
14697
  borderColor: "currentColor",
14683
- ...unref(boundingBoxToStyle)(obb)
14698
+ ...obb.toCssStyle()
14684
14699
  })
14685
14700
  }, null, 4);
14686
14701
  }), 128)),
@@ -14689,7 +14704,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
14689
14704
  class: "mce-selector__selected-area",
14690
14705
  style: normalizeStyle({
14691
14706
  borderColor: "currentcolor",
14692
- ...unref(boundingBoxToStyle)(props.selectedArea)
14707
+ ...props.selectedArea.toCssStyle()
14693
14708
  })
14694
14709
  }, null, 4)) : createCommentVNode("", true),
14695
14710
  (openBlock(true), createElementBlock(Fragment, null, renderList(selectionObbs.value, (item, index) => {
@@ -14699,7 +14714,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
14699
14714
  style: normalizeStyle({
14700
14715
  borderColor: "currentcolor",
14701
14716
  borderRadius: `${(item.element.style.borderRadius ?? 0) * unref(camera).zoom.x}px`,
14702
- ...unref(boundingBoxToStyle)(item.box)
14717
+ ...item.box.toCssStyle()
14703
14718
  })
14704
14719
  }, null, 4);
14705
14720
  }), 128)),
@@ -14938,10 +14953,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
14938
14953
  obb.left += textBox.left;
14939
14954
  obb.top += textBox.top;
14940
14955
  }
14941
- const style = boundingBoxToStyle(obb);
14942
- return {
14943
- ...style
14944
- };
14956
+ return obb.toCssStyle();
14945
14957
  });
14946
14958
  function onUpdateTextSelection(e) {
14947
14959
  textSelection.value = e.detail;
@@ -15069,7 +15081,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
15069
15081
  const selector = useTemplateRef("selectorTpl");
15070
15082
  const textEditor = useTemplateRef("textEditorTpl");
15071
15083
  const grabbing = ref(false);
15072
- const selectedArea = ref({ left: 0, top: 0, width: 0, height: 0 });
15084
+ const selectedArea = ref(new Aabb2D());
15073
15085
  const resizeStrategy = computed(() => {
15074
15086
  const first = elementSelection.value[0];
15075
15087
  if (first) {
@@ -15103,10 +15115,10 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
15103
15115
  function onHover(event) {
15104
15116
  let cursor;
15105
15117
  let hovered;
15106
- if (elementSelection.value.length > 1 && isPointInsideAabb(
15107
- { x: event.clientX, y: event.clientY },
15108
- selectionAabbInDrawboard.value
15109
- )) {
15118
+ if (elementSelection.value.length > 1 && selectionAabbInDrawboard.value.containsPoint({
15119
+ x: event.clientX,
15120
+ y: event.clientY
15121
+ })) {
15110
15122
  cursor = "move";
15111
15123
  } else {
15112
15124
  const element = event.target;
@@ -15140,10 +15152,10 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
15140
15152
  let isUp = false;
15141
15153
  let selected = [];
15142
15154
  let ctxState;
15143
- const inSelection = isPointInsideAabb({
15155
+ const inSelection = selectionAabbInDrawboard.value.containsPoint({
15144
15156
  x: start.x - drawboardAabb.value.left,
15145
15157
  y: start.y - drawboardAabb.value.top
15146
- }, selectionAabbInDrawboard.value);
15158
+ });
15147
15159
  if (downEvent.button === 2) {
15148
15160
  if (!inSelection) {
15149
15161
  const result = props.activeStrategy({
@@ -15189,12 +15201,10 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
15189
15201
  if (state.value !== "selecting") {
15190
15202
  state.value = "selecting";
15191
15203
  }
15192
- selectedArea.value = {
15193
- left: Math.min(start.x, current.x) - drawboardAabb.value.left,
15194
- top: Math.min(start.y, current.y) - drawboardAabb.value.top,
15195
- width: Math.abs(start.x - current.x),
15196
- height: Math.abs(start.y - current.y)
15197
- };
15204
+ selectedArea.value.x = Math.min(start.x, current.x) - drawboardAabb.value.left;
15205
+ selectedArea.value.y = Math.min(start.y, current.y) - drawboardAabb.value.top;
15206
+ selectedArea.value.width = Math.abs(start.x - current.x);
15207
+ selectedArea.value.height = Math.abs(start.y - current.y);
15198
15208
  selected = selectArea(selectedArea.value);
15199
15209
  }
15200
15210
  function onActivate() {
@@ -15315,10 +15325,10 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
15315
15325
  if (event.srcElement !== drawboardDom.value) {
15316
15326
  return;
15317
15327
  }
15318
- drawboardPointer.value = {
15319
- x: event.clientX - drawboardAabb.value.left,
15320
- y: event.clientY - drawboardAabb.value.top
15321
- };
15328
+ drawboardPointer.value = new Vector2$1(
15329
+ event.clientX - drawboardAabb.value.left,
15330
+ event.clientY - drawboardAabb.value.top
15331
+ );
15322
15332
  if (camera.value.grabbing || event.button === 1 || state.value && state.value !== "typing") {
15323
15333
  return;
15324
15334
  }
@@ -15560,22 +15570,17 @@ export {
15560
15570
  findChildrenWithProvide,
15561
15571
  getImageSizeFromUrl,
15562
15572
  getRandomValues,
15563
- iElementToYNodes,
15564
15573
  imageExtRe,
15565
15574
  imageExts,
15566
15575
  imageMimeTypeExtMap,
15567
15576
  isClickInsideElement,
15568
15577
  isInputEvent,
15569
15578
  isMac,
15570
- isOverlappingAabb,
15571
- isOverlappingObb,
15572
- isPointInsideAabb,
15573
15579
  isWindows,
15574
15580
  makeLayoutItemProps,
15575
15581
  makeLayoutProps,
15576
15582
  makeMceOverlayProps,
15577
15583
  makeMceStrategyProps,
15578
- minBoundingBox,
15579
15584
  mixins,
15580
15585
  plugins,
15581
15586
  propsFactory,