@tmagic/stage 1.0.0-rc.2 → 1.0.0-rc.5

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.
@@ -23,6 +23,8 @@
23
23
  var ZIndex = /* @__PURE__ */ ((ZIndex2) => {
24
24
  ZIndex2["MASK"] = "99999";
25
25
  ZIndex2["SELECTED_EL"] = "666";
26
+ ZIndex2["GHOST_EL"] = "700";
27
+ ZIndex2["DRAG_EL"] = "9";
26
28
  return ZIndex2;
27
29
  })(ZIndex || {});
28
30
  var MouseButton = /* @__PURE__ */ ((MouseButton2) => {
@@ -38,6 +40,8 @@
38
40
  return Mode2;
39
41
  })(Mode || {});
40
42
  const SELECTED_CLASS = "tmagic-stage-selected-area";
43
+ const H_GUIDE_LINE_STORAGE_KEY = "$MagicStageHorizontalGuidelinesData";
44
+ const V_GUIDE_LINE_STORAGE_KEY = "$MagicStageVerticalGuidelinesData";
41
45
 
42
46
  const getParents = (el, relative) => {
43
47
  let cur = el.parentElement;
@@ -184,12 +188,29 @@
184
188
  item.classList.add(`${SELECTED_CLASS}-parents`);
185
189
  });
186
190
  };
191
+ const getGuideLineFromCache = (type) => {
192
+ const key = {
193
+ [GuidesType.HORIZONTAL]: H_GUIDE_LINE_STORAGE_KEY,
194
+ [GuidesType.VERTICAL]: V_GUIDE_LINE_STORAGE_KEY
195
+ }[type];
196
+ if (!key)
197
+ return [];
198
+ const guideLineCacheData = globalThis.localStorage.getItem(key);
199
+ if (guideLineCacheData) {
200
+ try {
201
+ return JSON.parse(guideLineCacheData) || [];
202
+ } catch (e) {
203
+ console.error(e);
204
+ }
205
+ }
206
+ return [];
207
+ };
187
208
 
188
209
  class StageDragResize extends EventEmitter.EventEmitter {
189
210
  constructor(config) {
190
211
  super();
191
- this.horizontalGuidelines = [];
192
- this.verticalGuidelines = [];
212
+ this.horizontalGuidelines = getGuideLineFromCache(GuidesType.HORIZONTAL);
213
+ this.verticalGuidelines = getGuideLineFromCache(GuidesType.VERTICAL);
193
214
  this.elementGuidelines = [];
194
215
  this.mode = Mode.ABSOLUTE;
195
216
  this.moveableOptions = {};
@@ -264,6 +285,26 @@
264
285
  target: this.dragEl
265
286
  });
266
287
  }
288
+ setElementGuidelines(nodes) {
289
+ this.elementGuidelines.forEach((node) => {
290
+ node.remove();
291
+ });
292
+ this.elementGuidelines = [];
293
+ if (this.mode === Mode.ABSOLUTE) {
294
+ const frame = document.createDocumentFragment();
295
+ for (const node of nodes) {
296
+ const { width, height } = node.getBoundingClientRect();
297
+ if (node === this.target)
298
+ continue;
299
+ const { left, top } = getOffset(node);
300
+ const elementGuideline = document.createElement("div");
301
+ elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
302
+ this.elementGuidelines.push(elementGuideline);
303
+ frame.append(elementGuideline);
304
+ }
305
+ this.container.append(frame);
306
+ }
307
+ }
267
308
  initMoveable() {
268
309
  this.moveable?.destroy();
269
310
  this.moveable = new Moveable__default["default"](this.container, {
@@ -348,14 +389,6 @@
348
389
  this.destroyGhostEl();
349
390
  });
350
391
  }
351
- getSnapElements(runtime, el) {
352
- const { renderer, mask } = this.core;
353
- const getSnapElements = runtime?.getSnapElements || (() => {
354
- const doc = renderer.contentWindow?.document;
355
- return doc ? Array.from(doc.querySelectorAll("[id]")) : [];
356
- });
357
- return getSnapElements(el).filter((element) => element !== this.target && !this.target?.contains(element) && element !== mask.page);
358
- }
359
392
  sort() {
360
393
  if (!this.target || !this.ghostEl)
361
394
  throw new Error("\u672A\u77E5\u9519\u8BEF");
@@ -394,7 +427,7 @@
394
427
  const ghostEl = el.cloneNode(true);
395
428
  const { top, left } = getAbsolutePosition(el, getOffset(el));
396
429
  ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
397
- ghostEl.style.zIndex = "5";
430
+ ghostEl.style.zIndex = ZIndex.GHOST_EL;
398
431
  ghostEl.style.opacity = ".5";
399
432
  ghostEl.style.position = "absolute";
400
433
  ghostEl.style.left = `${left}px`;
@@ -415,7 +448,7 @@
415
448
  top: ${offset.top}px;
416
449
  width: ${width}px;
417
450
  height: ${height}px;
418
- z-index: 9;
451
+ z-index: ${ZIndex.DRAG_EL};
419
452
  `;
420
453
  this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
421
454
  }
@@ -431,6 +464,11 @@
431
464
  if (typeof moveableOptions === "function") {
432
465
  moveableOptions = moveableOptions(this.core);
433
466
  }
467
+ const elementGuidelines = moveableOptions.elementGuidelines || this.target.parentElement?.children || [];
468
+ this.setElementGuidelines(elementGuidelines);
469
+ if (moveableOptions.elementGuidelines) {
470
+ delete moveableOptions.elementGuidelines;
471
+ }
434
472
  return {
435
473
  origin: false,
436
474
  rootContainer: this.core.container,
@@ -650,8 +688,8 @@
650
688
  class Rule extends EventEmitter__default["default"] {
651
689
  constructor(container) {
652
690
  super();
653
- this.horizontalGuidelines = [];
654
- this.verticalGuidelines = [];
691
+ this.horizontalGuidelines = getGuideLineFromCache(GuidesType.HORIZONTAL);
692
+ this.verticalGuidelines = getGuideLineFromCache(GuidesType.VERTICAL);
655
693
  this.getGuidesStyle = (type) => ({
656
694
  position: "fixed",
657
695
  zIndex: 1,
@@ -675,6 +713,7 @@
675
713
  type: GuidesType.HORIZONTAL,
676
714
  guides: this.horizontalGuidelines
677
715
  });
716
+ globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
678
717
  };
679
718
  this.vGuidesChangeGuidesHandler = (e) => {
680
719
  this.verticalGuidelines = e.guides;
@@ -682,10 +721,11 @@
682
721
  type: GuidesType.VERTICAL,
683
722
  guides: this.verticalGuidelines
684
723
  });
724
+ globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
685
725
  };
686
726
  this.container = container;
687
- this.hGuides = this.createGuides(GuidesType.HORIZONTAL);
688
- this.vGuides = this.createGuides(GuidesType.VERTICAL);
727
+ this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
728
+ this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
689
729
  this.hGuides.on("changeGuides", this.hGuidesChangeGuidesHandler);
690
730
  this.vGuides.on("changeGuides", this.vGuidesChangeGuidesHandler);
691
731
  this.containerResizeObserver = new ResizeObserver(() => {
@@ -719,6 +759,8 @@
719
759
  type: GuidesType.HORIZONTAL,
720
760
  guides: []
721
761
  });
762
+ globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, "[]");
763
+ globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, "[]");
722
764
  }
723
765
  showRule(show = true) {
724
766
  if (show) {
@@ -802,6 +844,7 @@
802
844
  this.wrapperWidth = 0;
803
845
  this.maxScrollTop = 0;
804
846
  this.maxScrollLeft = 0;
847
+ this.intersectionObserver = null;
805
848
  this.mode = Mode.ABSOLUTE;
806
849
  this.pageResizeObserver = null;
807
850
  this.wrapperResizeObserver = null;
@@ -841,7 +884,6 @@
841
884
  if (this.maxScrollLeft > 0) {
842
885
  this.scrollLeft = this.scrollLeft + deltaX;
843
886
  }
844
- this.fixScrollValue();
845
887
  this.scroll();
846
888
  this.emit("scroll", event);
847
889
  };
@@ -873,15 +915,33 @@
873
915
  this.page = page;
874
916
  this.pageScrollParent = getScrollParent(page) || this.core.renderer.contentWindow?.document.documentElement || null;
875
917
  this.pageResizeObserver?.disconnect();
918
+ this.wrapperResizeObserver?.disconnect();
919
+ this.intersectionObserver?.disconnect();
920
+ if (typeof IntersectionObserver !== "undefined") {
921
+ this.intersectionObserver = new IntersectionObserver((entries) => {
922
+ entries.forEach((entry) => {
923
+ const { target, intersectionRatio } = entry;
924
+ if (intersectionRatio <= 0) {
925
+ this.scrollIntoView(target);
926
+ }
927
+ this.intersectionObserver?.unobserve(target);
928
+ });
929
+ }, {
930
+ root: this.pageScrollParent,
931
+ rootMargin: "0px",
932
+ threshold: 1
933
+ });
934
+ }
876
935
  if (typeof ResizeObserver !== "undefined") {
877
936
  this.pageResizeObserver = new ResizeObserver((entries) => {
878
937
  const [entry] = entries;
879
938
  const { clientHeight, clientWidth } = entry.target;
880
939
  this.setHeight(clientHeight);
881
940
  this.setWidth(clientWidth);
882
- this.fixScrollValue();
883
941
  this.scroll();
884
- this.core.dr.updateMoveable();
942
+ if (this.core.dr.moveable) {
943
+ this.core.dr.updateMoveable();
944
+ }
885
945
  });
886
946
  this.pageResizeObserver.observe(page);
887
947
  this.wrapperResizeObserver = new ResizeObserver((entries) => {
@@ -904,8 +964,6 @@
904
964
  this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
905
965
  }
906
966
  scrollIntoView(el) {
907
- if (this.mode === Mode.FIXED)
908
- return;
909
967
  el.scrollIntoView();
910
968
  if (!this.pageScrollParent)
911
969
  return;
@@ -923,6 +981,7 @@
923
981
  super.destroy();
924
982
  }
925
983
  scroll() {
984
+ this.fixScrollValue();
926
985
  let { scrollLeft, scrollTop } = this;
927
986
  if (this.pageScrollParent) {
928
987
  this.pageScrollParent.scrollTo({
@@ -951,10 +1010,10 @@
951
1010
  this.content.style.width = `${width}px`;
952
1011
  }
953
1012
  setMaxScrollLeft() {
954
- this.maxScrollLeft = this.width - this.wrapperWidth;
1013
+ this.maxScrollLeft = Math.max(this.width - this.wrapperWidth, 0);
955
1014
  }
956
1015
  setMaxScrollTop() {
957
- this.maxScrollTop = this.height - this.wrapperHeight;
1016
+ this.maxScrollTop = Math.max(this.height - this.wrapperHeight, 0);
958
1017
  }
959
1018
  fixScrollValue() {
960
1019
  if (this.scrollTop < 0)
@@ -1128,7 +1187,9 @@
1128
1187
  }
1129
1188
  this.mask.setLayout(el);
1130
1189
  this.dr.select(el, event);
1131
- this.mask.scrollIntoView(el);
1190
+ if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
1191
+ this.mask.intersectionObserver?.observe(el);
1192
+ }
1132
1193
  this.selectedDom = el;
1133
1194
  if (this.renderer.contentWindow) {
1134
1195
  removeSelectedClassName(this.renderer.contentWindow.document);