mce 0.15.29 → 0.15.31

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.css CHANGED
@@ -1173,7 +1173,7 @@
1173
1173
  }.mce-selector__slot {
1174
1174
  position: absolute;
1175
1175
  }
1176
- .mce-selector__parent-element {
1176
+ .mce-selector__parent-obb {
1177
1177
  position: absolute;
1178
1178
  pointer-events: none;
1179
1179
  border-width: 1px;
@@ -1192,7 +1192,7 @@
1192
1192
  position: absolute;
1193
1193
  color: rgba(var(--mce-theme-primary), 1);
1194
1194
  }
1195
- .mce-selector__element {
1195
+ .mce-selector__obb {
1196
1196
  position: absolute;
1197
1197
  border-width: 1px;
1198
1198
  border-style: solid;
package/dist/index.js CHANGED
@@ -3450,6 +3450,7 @@ const _4_1_text = defineMixin((editor) => {
3450
3450
  const _4_2_frame = defineMixin((editor) => {
3451
3451
  const {
3452
3452
  frames,
3453
+ isElement,
3453
3454
  isTopFrame,
3454
3455
  selection,
3455
3456
  getAncestorFrame
@@ -3458,7 +3459,7 @@ const _4_2_frame = defineMixin((editor) => {
3458
3459
  let current;
3459
3460
  const node = selection.value[0];
3460
3461
  if (node) {
3461
- current = isTopFrame(node) ? node : getAncestorFrame(node, true);
3462
+ current = isElement(node) && isTopFrame(node) ? node : getAncestorFrame(node, true);
3462
3463
  }
3463
3464
  const last = frames.value.length - 1;
3464
3465
  let index = frames.value.findIndex((node2) => node2.equal(current));
@@ -3550,8 +3551,8 @@ const _4_3_element = defineMixin((editor) => {
3550
3551
  const newHeight = aspectRatio > 1 ? halfWidth / aspectRatio : halfHeight;
3551
3552
  resizeElement(
3552
3553
  el,
3553
- newWidth / el.style.width,
3554
- newHeight / el.style.height,
3554
+ newWidth,
3555
+ newHeight,
3555
3556
  {
3556
3557
  deep: true,
3557
3558
  textFontSizeToFit: true
@@ -3663,28 +3664,30 @@ const _4_3_element = defineMixin((editor) => {
3663
3664
  }
3664
3665
  return isArray ? elements : elements[0];
3665
3666
  }
3666
- function resizeElement(element, scaleX, scaleY, options = {}) {
3667
- scaleX = Math.abs(scaleX);
3668
- scaleY = Math.abs(scaleY);
3669
- function handle(element2) {
3670
- const style = element2.style;
3671
- style.left = style.left * scaleX;
3672
- style.top = style.top * scaleY;
3673
- style.width = style.width * scaleX;
3674
- style.height = style.height * scaleY;
3675
- element2?.requestRender?.();
3676
- }
3677
- handle(element);
3667
+ function resizeElement(el, newWidth, newHeight, options = {}) {
3668
+ const scaleX = Math.abs(newWidth / el.style.width);
3669
+ const scaleY = Math.abs(newHeight / el.style.height);
3670
+ function handle(el2, isChild = false) {
3671
+ const style = el2.style;
3672
+ if (isChild) {
3673
+ style.left *= scaleX;
3674
+ style.top *= scaleY;
3675
+ }
3676
+ style.width *= scaleX;
3677
+ style.height *= scaleY;
3678
+ el2?.requestRender?.();
3679
+ }
3680
+ handle(el);
3678
3681
  if (options.deep) {
3679
- element.findOne((node) => {
3682
+ el.findOne((node) => {
3680
3683
  if (isElement(node)) {
3681
- handle(node);
3684
+ handle(node, true);
3682
3685
  }
3683
3686
  return false;
3684
3687
  });
3685
3688
  }
3686
- options.textToFit && textToFit(element);
3687
- options.textFontSizeToFit && textFontSizeToFit(element, scaleX);
3689
+ options.textToFit && textToFit(el);
3690
+ options.textFontSizeToFit && textFontSizeToFit(el, scaleX);
3688
3691
  }
3689
3692
  function selectArea(areaInDrawboard) {
3690
3693
  const area2 = new Obb2D(areaInDrawboard);
@@ -4267,59 +4270,10 @@ function definePlugin(cb) {
4267
4270
  const _arrange = definePlugin((editor) => {
4268
4271
  const {
4269
4272
  isElement,
4270
- rootAabb,
4271
4273
  elementSelection,
4272
4274
  selection,
4273
4275
  getAabb
4274
4276
  } = editor;
4275
- function align(direction) {
4276
- elementSelection.value.forEach((el) => {
4277
- if (el.parent && isElement(el.parent)) {
4278
- const parentAabb = getAabb(el.parent);
4279
- switch (direction) {
4280
- case "left":
4281
- el.style.left = 0;
4282
- break;
4283
- case "horizontal-center":
4284
- el.style.left = (parentAabb.width - el.style.width) / 2;
4285
- break;
4286
- case "right":
4287
- el.style.left = parentAabb.width - el.style.width;
4288
- break;
4289
- case "top":
4290
- el.style.top = 0;
4291
- break;
4292
- case "vertical-center":
4293
- el.style.top = (parentAabb.height - el.style.height) / 2;
4294
- break;
4295
- case "bottom":
4296
- el.style.top = parentAabb.height - el.style.height;
4297
- break;
4298
- }
4299
- } else {
4300
- switch (direction) {
4301
- case "left":
4302
- el.style.left = rootAabb.value.left;
4303
- break;
4304
- case "horizontal-center":
4305
- el.style.left = (rootAabb.value.left + rootAabb.value.width - el.style.width) / 2;
4306
- break;
4307
- case "right":
4308
- el.style.left = rootAabb.value.left + rootAabb.value.width - el.style.width;
4309
- break;
4310
- case "top":
4311
- el.style.top = rootAabb.value.top;
4312
- break;
4313
- case "vertical-center":
4314
- el.style.top = (rootAabb.value.top + rootAabb.value.height - el.style.height) / 2;
4315
- break;
4316
- case "bottom":
4317
- el.style.top = rootAabb.value.top + rootAabb.value.height - el.style.height;
4318
- break;
4319
- }
4320
- }
4321
- });
4322
- }
4323
4277
  function zOrder2(target, type) {
4324
4278
  const els = Array.isArray(target) ? target : [target];
4325
4279
  els.forEach((el) => {
@@ -4346,6 +4300,53 @@ const _arrange = definePlugin((editor) => {
4346
4300
  parent.moveChild(el, index);
4347
4301
  });
4348
4302
  }
4303
+ function align(direction) {
4304
+ const len = elementSelection.value.length;
4305
+ if (!len) {
4306
+ return;
4307
+ }
4308
+ let targetAabb;
4309
+ if (len === 1) {
4310
+ const parent = elementSelection.value[0]?.parent;
4311
+ if (parent && isElement(parent)) {
4312
+ targetAabb = parent.getGlobalAabb();
4313
+ }
4314
+ } else {
4315
+ targetAabb = getAabb(elementSelection.value);
4316
+ }
4317
+ if (!targetAabb) {
4318
+ return;
4319
+ }
4320
+ elementSelection.value.forEach((el) => {
4321
+ const parentAabb = el.getParent()?.getGlobalAabb?.() ?? new Aabb2D();
4322
+ const hw = el.size.x / 2;
4323
+ const hh = el.size.y / 2;
4324
+ const cos = Math.cos(el.rotation);
4325
+ const sin = Math.sin(el.rotation);
4326
+ const dx = Math.abs(hw * cos) + Math.abs(hh * sin);
4327
+ const dy = Math.abs(hw * sin) + Math.abs(hh * cos);
4328
+ switch (direction) {
4329
+ case "left":
4330
+ el.style.left = targetAabb.left - parentAabb.left + dx - hw;
4331
+ break;
4332
+ case "horizontal-center":
4333
+ el.style.left = targetAabb.left - parentAabb.left + targetAabb.width / 2 - hw;
4334
+ break;
4335
+ case "right":
4336
+ el.style.left = targetAabb.left - parentAabb.left + targetAabb.width - dx - hw;
4337
+ break;
4338
+ case "top":
4339
+ el.style.top = targetAabb.top - parentAabb.top + dy - hh;
4340
+ break;
4341
+ case "vertical-center":
4342
+ el.style.top = targetAabb.top - parentAabb.top + targetAabb.height / 2 - hh;
4343
+ break;
4344
+ case "bottom":
4345
+ el.style.top = targetAabb.top - parentAabb.top + targetAabb.height - dy - hh;
4346
+ break;
4347
+ }
4348
+ });
4349
+ }
4349
4350
  function bringToFront(target = selection.value) {
4350
4351
  target && zOrder2(target, "bringToFront");
4351
4352
  }
@@ -4395,17 +4396,16 @@ const _autoNest = definePlugin((editor) => {
4395
4396
  exec,
4396
4397
  root
4397
4398
  } = editor;
4398
- let startFrame;
4399
4399
  let startContext = {};
4400
- function nestIntoFrame(element, options) {
4400
+ function nestIntoFrame(el, options) {
4401
4401
  const pointer = options?.pointer;
4402
- const frame1 = element.findAncestor((node) => isTopFrame(node));
4403
- const aabb1 = element.getGlobalAabb();
4402
+ const frame1 = el.findAncestor((node) => isTopFrame(node));
4403
+ const aabb1 = el.getGlobalAabb();
4404
4404
  const area1 = aabb1.getArea();
4405
4405
  let flag = true;
4406
4406
  for (let i = 0, len = frames.value.length; i < len; i++) {
4407
4407
  const frame2 = frames.value[i];
4408
- if (frame2.equal(element)) {
4408
+ if (frame2.equal(el)) {
4409
4409
  continue;
4410
4410
  }
4411
4411
  const aabb2 = frame2.getGlobalAabb();
@@ -4415,10 +4415,10 @@ const _autoNest = definePlugin((editor) => {
4415
4415
  if (frame2.equal(options?.parent)) {
4416
4416
  index = options.index;
4417
4417
  }
4418
- frame2.moveChild(element, index);
4419
- element.style.left = aabb1.x - aabb2.x;
4420
- element.style.top = aabb1.y - aabb2.y;
4421
- element.updateGlobalTransform();
4418
+ frame2.moveChild(el, index);
4419
+ el.style.left = aabb1.x - aabb2.x;
4420
+ el.style.top = aabb1.y - aabb2.y;
4421
+ el.updateGlobalTransform();
4422
4422
  exec("layerScrollIntoView");
4423
4423
  }
4424
4424
  flag = false;
@@ -4430,10 +4430,10 @@ const _autoNest = definePlugin((editor) => {
4430
4430
  if (root.value.equal(options?.parent)) {
4431
4431
  index = options.index;
4432
4432
  }
4433
- root.value.moveChild(element, index);
4434
- element.style.left = aabb1.x;
4435
- element.style.top = aabb1.y;
4436
- element.updateGlobalTransform();
4433
+ root.value.moveChild(el, index);
4434
+ el.style.left = aabb1.x;
4435
+ el.style.top = aabb1.y;
4436
+ el.updateGlobalTransform();
4437
4437
  exec("layerScrollIntoView");
4438
4438
  }
4439
4439
  }
@@ -4443,20 +4443,10 @@ const _autoNest = definePlugin((editor) => {
4443
4443
  { command: "nestIntoFrame", handle: nestIntoFrame }
4444
4444
  ],
4445
4445
  events: {
4446
- selectionTransformStart: ({ elements }) => {
4447
- const pointer = getGlobalPointer();
4448
- startFrame = frames.value.find((frame) => frame.getGlobalAabb().contains(pointer));
4449
- const ctx = {};
4450
- elements.forEach((el) => {
4451
- ctx[el.instanceId] = {
4452
- parent: el.getParent(),
4453
- index: el.getIndex()
4454
- };
4455
- });
4456
- startContext = ctx;
4457
- },
4458
- selectionTransforming: ({ handle, startEvent, elements }) => {
4446
+ selectionTransformStart: ({ handle, startEvent, elements }) => {
4459
4447
  if (handle === "move" && !startEvent?.__FROM__) {
4448
+ const pointer = getGlobalPointer();
4449
+ const startFrame = frames.value.find((frame) => frame.getGlobalAabb().contains(pointer));
4460
4450
  const idSet = /* @__PURE__ */ new Set();
4461
4451
  elements.forEach((el) => {
4462
4452
  const frame = isTopFrame(el) ? el : el.findAncestor(isTopFrame);
@@ -4469,11 +4459,25 @@ const _autoNest = definePlugin((editor) => {
4469
4459
  }
4470
4460
  });
4471
4461
  if (idSet.size === 1) {
4472
- elements.forEach((element) => {
4462
+ const ctx = {};
4463
+ elements.forEach((el) => {
4464
+ ctx[el.instanceId] = {
4465
+ parent: el.getParent(),
4466
+ index: el.getIndex()
4467
+ };
4468
+ });
4469
+ startContext = ctx;
4470
+ }
4471
+ }
4472
+ },
4473
+ selectionTransforming: ({ handle, startEvent, elements }) => {
4474
+ if (handle === "move" && !startEvent?.__FROM__) {
4475
+ if (Object.keys(startContext).length > 0) {
4476
+ elements.forEach((el) => {
4473
4477
  nestIntoFrame(
4474
- element,
4478
+ el,
4475
4479
  {
4476
- ...startContext[element.instanceId],
4480
+ ...startContext[el.instanceId],
4477
4481
  pointer: getGlobalPointer()
4478
4482
  }
4479
4483
  );
@@ -4483,7 +4487,6 @@ const _autoNest = definePlugin((editor) => {
4483
4487
  },
4484
4488
  selectionTransformEnd: () => {
4485
4489
  startContext = {};
4486
- startFrame = void 0;
4487
4490
  }
4488
4491
  }
4489
4492
  };
@@ -5690,9 +5693,12 @@ const _group = definePlugin((editor) => {
5690
5693
  elementSelection,
5691
5694
  addElement,
5692
5695
  addElements,
5693
- doc
5696
+ doc,
5697
+ isElement,
5698
+ inEditorIs,
5699
+ obbToFit
5694
5700
  } = editor;
5695
- function group(inEditorIs) {
5701
+ function group(inEditorIs2) {
5696
5702
  const elements = elementSelection.value;
5697
5703
  if (!elements.length) {
5698
5704
  return;
@@ -5708,7 +5714,7 @@ const _group = definePlugin((editor) => {
5708
5714
  });
5709
5715
  doc.value.transact(() => {
5710
5716
  addElement({
5711
- name: inEditorIs === "Frame" ? "Frame" : "Group",
5717
+ name: inEditorIs2 === "Frame" ? "Frame" : "Group",
5712
5718
  style: {
5713
5719
  left: aabb.left,
5714
5720
  top: aabb.top,
@@ -5718,7 +5724,7 @@ const _group = definePlugin((editor) => {
5718
5724
  children,
5719
5725
  meta: {
5720
5726
  inPptIs: "GroupShape",
5721
- inEditorIs
5727
+ inEditorIs: inEditorIs2
5722
5728
  }
5723
5729
  }, {
5724
5730
  parent,
@@ -5762,7 +5768,19 @@ const _group = definePlugin((editor) => {
5762
5768
  { command: "groupSelection", key: "CmdOrCtrl+G" },
5763
5769
  { command: "frameSelection", key: "Alt+CmdOrCtrl+G" },
5764
5770
  { command: "ungroup", key: "CmdOrCtrl+Backspace" }
5765
- ]
5771
+ ],
5772
+ events: {
5773
+ selectionTransforming: ({ elements }) => {
5774
+ elements.forEach((el) => {
5775
+ el.findAncestor((ancestor) => {
5776
+ if (isElement(ancestor) && !inEditorIs(ancestor, "Frame")) {
5777
+ obbToFit(ancestor);
5778
+ }
5779
+ return false;
5780
+ });
5781
+ });
5782
+ }
5783
+ }
5766
5784
  };
5767
5785
  });
5768
5786
  const _history = definePlugin((editor) => {
@@ -12418,6 +12436,8 @@ const _shape = definePlugin((editor) => {
12418
12436
  position: start,
12419
12437
  active: true
12420
12438
  });
12439
+ el.style.width = 1;
12440
+ el.style.height = 1;
12421
12441
  return {
12422
12442
  move: (move) => {
12423
12443
  const minX = Math.min(move.x, start.x);
@@ -12426,8 +12446,8 @@ const _shape = definePlugin((editor) => {
12426
12446
  const maxY = Math.max(move.y, start.y);
12427
12447
  el.style.left = minX;
12428
12448
  el.style.top = minY;
12429
- el.style.width = maxX - minX;
12430
- el.style.height = maxY - minY;
12449
+ el.style.width = Math.max(1, maxX - minX);
12450
+ el.style.height = Math.max(1, maxY - minY);
12431
12451
  },
12432
12452
  end: () => {
12433
12453
  setActiveDrawingTool(void 0);
@@ -13597,29 +13617,13 @@ const _smartGuides = definePlugin((editor) => {
13597
13617
  state,
13598
13618
  getAabb,
13599
13619
  root,
13600
- camera
13620
+ camera,
13621
+ viewportAabb
13601
13622
  } = editor;
13602
13623
  const snapThreshold = computed(() => Math.max(1, 5 / camera.value.zoom.x));
13603
13624
  const excluded = computed(() => new Set(elementSelection.value.map((el) => el.id)));
13604
- const activeBox = computed(() => createBox(selectionAabb.value));
13605
13625
  const parnet = computed(() => elementSelection.value[0]?.parent ?? root.value);
13606
13626
  const parentBox = computed(() => createBox(parnet.value));
13607
- const boxes = computed(() => {
13608
- return parnet.value.children.filter((node) => !excluded.value.has(node.id)).map((node) => createBox(node)).filter(Boolean);
13609
- });
13610
- const store = computed(() => {
13611
- return boxes.value.reduce(
13612
- (store2, box) => {
13613
- [box.vt, box.vm, box.vb].forEach((val) => store2.vLines.add(val));
13614
- [box.hl, box.hm, box.hr].forEach((val) => store2.hLines.add(val));
13615
- return store2;
13616
- },
13617
- {
13618
- vLines: new BSTree((a, b) => a.pos - b.pos),
13619
- hLines: new BSTree((a, b) => a.pos - b.pos)
13620
- }
13621
- );
13622
- });
13623
13627
  function createBox(node) {
13624
13628
  if (!node)
13625
13629
  return void 0;
@@ -13733,12 +13737,22 @@ const _smartGuides = definePlugin((editor) => {
13733
13737
  const linePairs = ref([]);
13734
13738
  function updateSmartGuides() {
13735
13739
  const _linePairs = [];
13736
- const box = activeBox.value;
13740
+ const box = createBox(selectionAabb.value);
13737
13741
  if (box) {
13738
- const {
13739
- vLines,
13740
- hLines
13741
- } = store.value;
13742
+ const boxes = parnet.value.children.filter((node) => {
13743
+ return !excluded.value.has(node.id) && isElement(node) && viewportAabb.value.overlap(node.getGlobalAabb());
13744
+ }).map((node) => createBox(node)).filter(Boolean);
13745
+ const { vLines, hLines } = boxes.reduce(
13746
+ (store, box2) => {
13747
+ [box2.vt, box2.vm, box2.vb].forEach((val) => store.vLines.add(val));
13748
+ [box2.hl, box2.hm, box2.hr].forEach((val) => store.hLines.add(val));
13749
+ return store;
13750
+ },
13751
+ {
13752
+ vLines: new BSTree((a, b) => a.pos - b.pos),
13753
+ hLines: new BSTree((a, b) => a.pos - b.pos)
13754
+ }
13755
+ );
13742
13756
  const areaLine = {
13743
13757
  vt: [],
13744
13758
  vb: [],
@@ -13949,7 +13963,14 @@ const _smartGuides = definePlugin((editor) => {
13949
13963
  { type: "overlay", component: _sfc_main$k }
13950
13964
  ],
13951
13965
  events: {
13952
- selectionTransforming: updateSmartGuides
13966
+ selectionTransforming: ({ handle }) => {
13967
+ if (handle === "move") {
13968
+ updateSmartGuides();
13969
+ }
13970
+ },
13971
+ selectionTransformEnd: () => {
13972
+ linePairs.value = [];
13973
+ }
13953
13974
  }
13954
13975
  };
13955
13976
  });
@@ -14801,14 +14822,12 @@ const _ui = definePlugin((editor) => {
14801
14822
  const {
14802
14823
  drawboardDom,
14803
14824
  drawboardAabb,
14804
- drawboardPointer,
14805
- exec
14825
+ drawboardPointer
14806
14826
  } = editor;
14807
14827
  useResizeObserver$1(drawboardDom, (entries) => {
14808
14828
  const { left: _left, top: _top, width, height } = entries[0].contentRect;
14809
14829
  const { left = _left, top = _top } = drawboardDom.value?.getBoundingClientRect() ?? {};
14810
14830
  drawboardAabb.value = new Aabb2D(left, top, width, height);
14811
- exec("zoomToFit");
14812
14831
  });
14813
14832
  document.addEventListener("mousemove", (event) => {
14814
14833
  drawboardPointer.value = new Vector2$1(
@@ -15151,11 +15170,13 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
15151
15170
  const aabb = selectionAabbInDrawboard.value;
15152
15171
  if (location?.startsWith("top") || location?.startsWith("bottom")) {
15153
15172
  return {
15154
- minWidth: `${aabb.width}px`
15173
+ "--height": "auto",
15174
+ "--width": `${aabb.width}px`
15155
15175
  };
15156
15176
  } else if (location?.startsWith("left") || location?.startsWith("right")) {
15157
15177
  return {
15158
- minHeight: `${aabb.height}px`
15178
+ "--height": `${aabb.height}px`,
15179
+ "--width": "auto"
15159
15180
  };
15160
15181
  }
15161
15182
  return {};
@@ -15514,7 +15535,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
15514
15535
  rotatedCurrentPoint.y - centerPoint.y,
15515
15536
  rotatedCurrentPoint.x - centerPoint.x
15516
15537
  ) / (Math.PI / 180);
15517
- updated.rotate = (rotate + endAngle - startAngle + 360) % 360;
15538
+ updated.rotate = rotate + endAngle - startAngle;
15518
15539
  }
15519
15540
  } else if (isRound) {
15520
15541
  const offset2 = rotatePoint2(rotatedOffset, { x: 0, y: 0 }, -rotate);
@@ -16037,8 +16058,8 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16037
16058
  selectionObb,
16038
16059
  selectionObbInDrawboard,
16039
16060
  camera,
16040
- obbToFit,
16041
16061
  getObb,
16062
+ getAabb,
16042
16063
  registerCommand,
16043
16064
  unregisterCommand,
16044
16065
  inEditorIs,
@@ -16046,7 +16067,8 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16046
16067
  config,
16047
16068
  snapThreshold,
16048
16069
  getSnapPoints,
16049
- hoverElement
16070
+ hoverElement,
16071
+ selectionAabb
16050
16072
  } = useEditor();
16051
16073
  const transformable = useTemplateRef("transformableTpl");
16052
16074
  const startEvent = ref();
@@ -16087,18 +16109,6 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16087
16109
  };
16088
16110
  });
16089
16111
  });
16090
- const _transform2 = computed(() => {
16091
- const zoom = camera.value.zoom;
16092
- const { left, top, width, height, rotationDegrees } = selectionObbInDrawboard.value;
16093
- return {
16094
- left,
16095
- top,
16096
- width,
16097
- height,
16098
- rotate: rotationDegrees,
16099
- borderRadius: (elementSelection.value[0]?.style.borderRadius ?? 0) * zoom.x
16100
- };
16101
- });
16102
16112
  function snap(currentPos, type) {
16103
16113
  const points = getSnapPoints();
16104
16114
  const zoom = camera.value.zoom;
@@ -16135,6 +16145,45 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16135
16145
  elements: elementSelection.value
16136
16146
  };
16137
16147
  }
16148
+ const startContext = {
16149
+ rotate: 0,
16150
+ offsetMap: {}
16151
+ };
16152
+ function onStart() {
16153
+ startContext.rotate = 0;
16154
+ const aabb = selectionAabb.value;
16155
+ elementSelection.value.forEach((el) => {
16156
+ const elAabb = el.getGlobalAabb();
16157
+ startContext.offsetMap[el.instanceId] = {
16158
+ x: (elAabb.x - aabb.x) / aabb.width,
16159
+ y: (elAabb.y - aabb.y) / aabb.height
16160
+ };
16161
+ });
16162
+ emit("selectionTransformStart", createSelectionTransformContext());
16163
+ }
16164
+ function onMove() {
16165
+ if (!state.value) {
16166
+ state.value = "transforming";
16167
+ }
16168
+ }
16169
+ function onEnd() {
16170
+ if (state.value === "transforming") {
16171
+ state.value = void 0;
16172
+ }
16173
+ emit("selectionTransformEnd", createSelectionTransformContext());
16174
+ }
16175
+ const _transform2 = computed(() => {
16176
+ const zoom = camera.value.zoom;
16177
+ const { left, top, width, height, rotationDegrees } = selectionObbInDrawboard.value;
16178
+ return {
16179
+ left,
16180
+ top,
16181
+ width,
16182
+ height,
16183
+ rotate: rotationDegrees,
16184
+ borderRadius: (elementSelection.value[0]?.style.borderRadius ?? 0) * zoom.x
16185
+ };
16186
+ });
16138
16187
  const transform = computed({
16139
16188
  get: () => _transform2.value,
16140
16189
  set: (val) => {
@@ -16161,80 +16210,78 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16161
16210
  rotate: transform2.rotate - (oldTransform.rotate ?? 0),
16162
16211
  borderRadius: transform2.borderRadius - (oldTransform.borderRadius ?? 0) / zoom.y
16163
16212
  };
16164
- elementSelection.value.forEach((element) => {
16165
- const style = element.style;
16213
+ const els = elementSelection.value;
16214
+ if (els.length > 1) {
16215
+ if (handle.startsWith("rotate")) {
16216
+ offsetStyle.rotate = transform2.rotate - startContext.rotate;
16217
+ startContext.rotate += offsetStyle.rotate;
16218
+ }
16219
+ }
16220
+ els.forEach((el) => {
16221
+ const style = el.style;
16166
16222
  const newStyle = {
16167
16223
  left: style.left + offsetStyle.left,
16168
16224
  top: style.top + offsetStyle.top,
16169
16225
  width: style.width + offsetStyle.width,
16170
16226
  height: style.height + offsetStyle.height,
16171
- rotate: style.rotate + offsetStyle.rotate,
16227
+ rotate: (style.rotate + offsetStyle.rotate + 360) % 360,
16172
16228
  borderRadius: Math.round(style.borderRadius + offsetStyle.borderRadius)
16173
16229
  };
16174
16230
  if (handle.startsWith("rotate")) {
16175
16231
  newStyle.rotate = Math.round(newStyle.rotate * 100) / 100;
16176
16232
  } else if (handle.startsWith("resize")) {
16177
16233
  const scale = newStyle.rotate ? 100 : 1;
16178
- newStyle.width = Math.round(newStyle.width * scale) / scale;
16179
- newStyle.height = Math.round(newStyle.height * scale) / scale;
16180
- const shape = element.shape;
16234
+ const newWidth = Math.max(1, Math.round(newStyle.width * scale) / scale);
16235
+ const newHeight = Math.max(1, Math.round(newStyle.height * scale) / scale);
16236
+ const shape = el.shape;
16181
16237
  resizeElement(
16182
- element,
16183
- newStyle.width / element.style.width,
16184
- newStyle.height / element.style.height,
16185
- inEditorIs(element, "Frame") ? void 0 : shape.isValid() ? { deep: true } : handle.split("-")[1].length > 1 ? { deep: true, textFontSizeToFit: true } : { deep: true, textToFit: true }
16238
+ el,
16239
+ newWidth,
16240
+ newHeight,
16241
+ inEditorIs(el, "Frame") ? void 0 : shape.isValid() ? { deep: true } : handle.split("-")[1].length > 1 ? { deep: true, textFontSizeToFit: true } : { deep: true, textToFit: true }
16186
16242
  );
16187
- newStyle.width = element.style.width;
16188
- newStyle.height = element.style.height;
16243
+ newStyle.width = el.style.width;
16244
+ newStyle.height = el.style.height;
16189
16245
  }
16190
16246
  Object.assign(style, newStyle);
16191
- element.updateGlobalTransform();
16192
- element.findAncestor((ancestor) => {
16193
- if (isElement(ancestor) && !inEditorIs(ancestor, "Frame")) {
16194
- obbToFit(ancestor);
16195
- }
16196
- return false;
16197
- });
16247
+ el.updateGlobalTransform();
16198
16248
  });
16249
+ if (els.length > 1) {
16250
+ if (handle.startsWith("resize")) {
16251
+ const selectionAabb2 = getAabb(els);
16252
+ els.forEach((el) => {
16253
+ const parentAabb = el.getParent()?.getGlobalAabb?.() ?? new Aabb2D();
16254
+ const { x, y } = startContext.offsetMap[el.instanceId];
16255
+ el.style.left = selectionAabb2.left - parentAabb.left + selectionAabb2.width * x;
16256
+ el.style.top = selectionAabb2.top - parentAabb.left + selectionAabb2.height * y;
16257
+ });
16258
+ }
16259
+ }
16199
16260
  emit("selectionTransforming", createSelectionTransformContext());
16200
16261
  }
16201
16262
  });
16202
16263
  const movable = computed(() => {
16203
- return elementSelection.value.every((element) => {
16264
+ return state.value !== "typing" && elementSelection.value.every((element) => {
16204
16265
  return !isLock(element) && element.meta.movable !== false && element.meta.transformable !== false;
16205
16266
  });
16206
16267
  });
16207
16268
  const resizable = computed(() => {
16208
- return elementSelection.value.every((element) => {
16269
+ return state.value !== "typing" && elementSelection.value.every((element) => {
16209
16270
  return !isLock(element) && element.meta.resizable !== false && element.meta.transformable !== false;
16210
16271
  });
16211
16272
  });
16212
16273
  const rotatable = computed(() => {
16213
- return elementSelection.value.every((element) => {
16274
+ return state.value !== "typing" && elementSelection.value.every((element) => {
16214
16275
  return !isLock(element) && element.meta.rotatable !== false && element.meta.transformable !== false;
16215
16276
  });
16216
16277
  });
16217
16278
  const roundable = computed(() => {
16218
- if (elementSelection.value.length === 1) {
16279
+ if (state.value !== "typing" && elementSelection.value.length === 1) {
16219
16280
  const element = elementSelection.value[0];
16220
16281
  return hoverElement.value?.equal(element) && !isLock(element) && element.foreground.isValid();
16221
16282
  }
16222
16283
  return false;
16223
16284
  });
16224
- function onStart() {
16225
- emit("selectionTransformStart", createSelectionTransformContext());
16226
- }
16227
- function onMove() {
16228
- if (!state.value) {
16229
- state.value = "transforming";
16230
- }
16231
- }
16232
- function onEnd() {
16233
- if (state.value === "transforming") {
16234
- state.value = void 0;
16235
- }
16236
- emit("selectionTransformEnd", createSelectionTransformContext());
16237
- }
16238
16285
  function tipFormat() {
16239
16286
  const obb = elementSelection.value.length === 1 ? elementSelection.value[0].style : selectionObb.value;
16240
16287
  return `${Number(obb.width.toFixed(2))} × ${Number(obb.height.toFixed(2))}`;
@@ -16247,44 +16294,43 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16247
16294
  (openBlock(true), createElementBlock(Fragment, null, renderList(parentObbStyles.value, (style, index) => {
16248
16295
  return openBlock(), createElementBlock("div", {
16249
16296
  key: index,
16250
- class: "mce-selector__parent-element",
16297
+ class: "mce-selector__parent-obb",
16251
16298
  style: normalizeStyle$1({
16252
16299
  borderColor: "currentColor",
16253
16300
  ...style
16254
16301
  })
16255
16302
  }, null, 4);
16256
16303
  }), 128)),
16257
- unref(state) === "selecting" ? (openBlock(), createElementBlock("div", {
16258
- key: 0,
16259
- class: "mce-selector__selected-area",
16260
- style: normalizeStyle$1({
16261
- borderColor: "currentcolor",
16262
- ...props.selectedArea.toCssStyle()
16263
- })
16264
- }, null, 4)) : createCommentVNode("", true),
16265
- (openBlock(true), createElementBlock(Fragment, null, renderList(selectionObbStyles.value, (style, index) => {
16304
+ unref(state) !== "transforming" ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(selectionObbStyles.value, (style, index) => {
16266
16305
  return openBlock(), createElementBlock("div", {
16267
16306
  key: index,
16268
- class: "mce-selector__element",
16307
+ class: "mce-selector__obb",
16269
16308
  style: normalizeStyle$1({
16270
16309
  borderColor: "currentcolor",
16271
16310
  ...style
16272
16311
  })
16273
16312
  }, null, 4);
16274
- }), 128)),
16275
- transform.value.width && transform.value.height ? (openBlock(), createBlock(_sfc_main$a, mergeProps({
16313
+ }), 128)) : createCommentVNode("", true),
16314
+ unref(state) === "selecting" ? (openBlock(), createElementBlock("div", {
16276
16315
  key: 1,
16316
+ class: "mce-selector__selected-area",
16317
+ style: normalizeStyle$1({
16318
+ borderColor: "currentcolor",
16319
+ ...props.selectedArea.toCssStyle()
16320
+ })
16321
+ }, null, 4)) : createCommentVNode("", true),
16322
+ transform.value.width && transform.value.height ? (openBlock(), createBlock(_sfc_main$a, mergeProps({
16323
+ key: 2,
16277
16324
  ref: "transformableTpl"
16278
16325
  }, unref(config).transformControls, {
16279
16326
  modelValue: transform.value,
16280
16327
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => transform.value = $event),
16281
- movable: unref(state) !== "typing" && movable.value,
16282
- resizable: unref(state) !== "typing" && resizable.value,
16283
- rotatable: unref(state) !== "typing" && rotatable.value,
16284
- roundable: unref(state) !== "typing" && roundable.value,
16328
+ movable: movable.value,
16329
+ resizable: resizable.value,
16330
+ rotatable: rotatable.value,
16331
+ roundable: roundable.value,
16285
16332
  "resize-strategy": props.resizeStrategy,
16286
16333
  class: "mce-selector__transform",
16287
- "border-style": unref(elementSelection).length > 1 ? "dashed" : "solid",
16288
16334
  "tip-format": tipFormat,
16289
16335
  onStart,
16290
16336
  onMove,
@@ -16297,9 +16343,9 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
16297
16343
  ]),
16298
16344
  key: "0"
16299
16345
  } : void 0
16300
- ]), 1040, ["modelValue", "movable", "resizable", "rotatable", "roundable", "resize-strategy", "border-style"])) : createCommentVNode("", true),
16346
+ ]), 1040, ["modelValue", "movable", "resizable", "rotatable", "roundable", "resize-strategy"])) : createCommentVNode("", true),
16301
16347
  transform.value.width && transform.value.height && _ctx.$slots.default ? (openBlock(), createElementBlock("div", {
16302
- key: 2,
16348
+ key: 3,
16303
16349
  class: "mce-selector__slot",
16304
16350
  style: normalizeStyle$1(unref(boundingBoxToStyle)(transform.value))
16305
16351
  }, [
@@ -46,10 +46,10 @@ declare global {
46
46
  parseAnchor: (anchor: Anchor, isRtl?: boolean) => ParsedAnchor;
47
47
  isNode: (value: any) => value is Node;
48
48
  isRoot: (value: any) => value is Node;
49
- inEditorIs: (value: Node, inEditorIs?: EditorNodeType) => boolean;
49
+ inEditorIs: (node: Node, inEditorIs?: EditorNodeType) => boolean;
50
50
  isElement: (value: any) => value is Element2D;
51
- isFrame: (value: any) => value is Element2D;
52
- isTopFrame: (value: any) => value is Element2D;
51
+ isFrame: (node: Node) => boolean;
52
+ isTopFrame: (node: Node) => boolean;
53
53
  isVisible: (node: Node) => boolean;
54
54
  setVisible: (node: Node, visible: boolean) => void;
55
55
  isLock: (node: Node) => boolean;
@@ -19,7 +19,7 @@ declare global {
19
19
  interface Editor {
20
20
  addElement: (element: Element, options?: AddElementOptions) => Element2D;
21
21
  addElements: (element: Element[], options?: AddElementOptions) => Element2D[];
22
- resizeElement: (element: Element2D, width: number, height: number, options?: ResizeElementOptions) => void;
22
+ resizeElement: (element: Element2D, newWidth: number, newHeight: number, options?: ResizeElementOptions) => void;
23
23
  selectArea: (areaInDrawboard: Aabb2D) => Element2D[];
24
24
  }
25
25
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mce",
3
3
  "type": "module",
4
- "version": "0.15.29",
4
+ "version": "0.15.31",
5
5
  "description": "The headless canvas editor framework. only the ESM.",
6
6
  "author": "wxm",
7
7
  "license": "MIT",
@@ -63,7 +63,7 @@
63
63
  "lodash-es": "^4.17.22",
64
64
  "modern-canvas": "^0.14.39",
65
65
  "modern-font": "^0.4.4",
66
- "modern-idoc": "^0.10.9",
66
+ "modern-idoc": "^0.10.10",
67
67
  "modern-text": "^1.10.15",
68
68
  "yjs": "^13.6.29"
69
69
  },