@tmagic/stage 1.0.0-beta.12 → 1.0.0-beta.15

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.
@@ -6,6 +6,7 @@ import Guides from '@scena/guides';
6
6
 
7
7
  const GHOST_EL_ID_PREFIX = "ghost_el_";
8
8
  const DRAG_EL_ID_PREFIX = "drag_el_";
9
+ const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
9
10
  const DEFAULT_ZOOM = 1;
10
11
  var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
11
12
  GuidesType2["HORIZONTAL"] = "horizontal";
@@ -163,21 +164,14 @@ const addSelectedClassName = (el) => {
163
164
  };
164
165
 
165
166
  class StageDragResize extends EventEmitter {
166
- core;
167
- container;
168
- target;
169
- dragEl;
170
- moveable;
171
- horizontalGuidelines = [];
172
- verticalGuidelines = [];
173
- elementGuidelines = [];
174
- moveableOptions = {};
175
- dragStatus = "end" /* END */;
176
- ghostEl;
177
- mode = Mode.ABSOLUTE;
178
- moveableHelper;
179
167
  constructor(config) {
180
168
  super();
169
+ this.horizontalGuidelines = [];
170
+ this.verticalGuidelines = [];
171
+ this.elementGuidelines = [];
172
+ this.mode = Mode.ABSOLUTE;
173
+ this.moveableOptions = {};
174
+ this.dragStatus = "end" /* END */;
181
175
  this.core = config.core;
182
176
  this.container = config.container;
183
177
  this.dragEl = globalThis.document.createElement("div");
@@ -399,6 +393,7 @@ class StageDragResize extends EventEmitter {
399
393
  top: ${offset.top}px;
400
394
  width: ${width}px;
401
395
  height: ${height}px;
396
+ z-index: 9;
402
397
  `;
403
398
  this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
404
399
  }
@@ -513,15 +508,97 @@ const up = (deltaTop, target) => {
513
508
  };
514
509
  };
515
510
 
511
+ class TargetCalibrate extends EventEmitter {
512
+ constructor(config) {
513
+ super();
514
+ this.parent = config.parent;
515
+ this.mask = config.mask;
516
+ this.dr = config.dr;
517
+ this.operationEl = globalThis.document.createElement("div");
518
+ this.parent.append(this.operationEl);
519
+ }
520
+ update(el, prefix) {
521
+ const { width, height } = el.getBoundingClientRect();
522
+ const { left, top } = this.getOffset(el);
523
+ this.operationEl.style.cssText = `
524
+ position: absolute;
525
+ left: ${left}px;
526
+ top: ${top}px;
527
+ width: ${width}px;
528
+ height: ${height}px;
529
+ `;
530
+ this.operationEl.id = `${prefix}${el.id}`;
531
+ return this.operationEl;
532
+ }
533
+ destroy() {
534
+ this.operationEl?.remove();
535
+ }
536
+ getOffset(el) {
537
+ const { transform } = getComputedStyle(el);
538
+ const { offsetParent } = el;
539
+ let left = el.offsetLeft;
540
+ let top = el.offsetTop;
541
+ if (transform.indexOf("matrix") > -1) {
542
+ let a = 1;
543
+ let b = 1;
544
+ let c = 1;
545
+ let d = 1;
546
+ let e = 0;
547
+ let f = 0;
548
+ transform.replace(/matrix\((.+), (.+), (.+), (.+), (.+), (.+)\)/, ($0, $1, $2, $3, $4, $5, $6) => {
549
+ a = +$1;
550
+ b = +$2;
551
+ c = +$3;
552
+ d = +$4;
553
+ e = +$5;
554
+ f = +$6;
555
+ return transform;
556
+ });
557
+ left = a * left + c * top + e;
558
+ top = b * left + d * top + f;
559
+ }
560
+ if (offsetParent) {
561
+ const parentOffset = this.getOffset(offsetParent);
562
+ return {
563
+ left: left + parentOffset.left,
564
+ top: top + parentOffset.top
565
+ };
566
+ }
567
+ if (this.dr.mode === Mode.FIXED) {
568
+ if (getMode(el) === Mode.FIXED) {
569
+ return {
570
+ left,
571
+ top
572
+ };
573
+ }
574
+ return {
575
+ left: left - this.mask.scrollLeft,
576
+ top: top - this.mask.scrollTop
577
+ };
578
+ }
579
+ if (getMode(el) === Mode.FIXED) {
580
+ return {
581
+ left: left + this.mask.scrollLeft,
582
+ top: top + this.mask.scrollTop
583
+ };
584
+ }
585
+ return {
586
+ left,
587
+ top
588
+ };
589
+ }
590
+ }
591
+
516
592
  class StageHighlight extends EventEmitter {
517
- core;
518
- container;
519
- target;
520
- moveable;
521
593
  constructor(config) {
522
594
  super();
523
595
  this.core = config.core;
524
596
  this.container = config.container;
597
+ this.calibrationTarget = new TargetCalibrate({
598
+ parent: this.core.mask.content,
599
+ mask: this.core.mask,
600
+ dr: this.core.dr
601
+ });
525
602
  }
526
603
  highlight(el) {
527
604
  if (!el || el === this.target)
@@ -529,9 +606,10 @@ class StageHighlight extends EventEmitter {
529
606
  this.target = el;
530
607
  this.moveable?.destroy();
531
608
  this.moveable = new Moveable(this.container, {
532
- target: this.target,
533
- scrollable: true,
534
- origin: false
609
+ target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
610
+ origin: false,
611
+ rootContainer: this.core.container,
612
+ zoom: 1
535
613
  });
536
614
  }
537
615
  clearHighlight() {
@@ -543,18 +621,46 @@ class StageHighlight extends EventEmitter {
543
621
  }
544
622
  destroy() {
545
623
  this.moveable?.destroy();
624
+ this.calibrationTarget.destroy();
546
625
  }
547
626
  }
548
627
 
549
628
  class Rule extends EventEmitter$1 {
550
- hGuides;
551
- vGuides;
552
- horizontalGuidelines = [];
553
- verticalGuidelines = [];
554
- container;
555
- containerResizeObserver;
556
629
  constructor(container) {
557
630
  super();
631
+ this.horizontalGuidelines = [];
632
+ this.verticalGuidelines = [];
633
+ this.getGuidesStyle = (type) => ({
634
+ position: "fixed",
635
+ zIndex: 1,
636
+ left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
637
+ top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
638
+ width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
639
+ height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
640
+ });
641
+ this.createGuides = (type, defaultGuides = []) => new Guides(this.container, {
642
+ type,
643
+ defaultGuides,
644
+ displayDragPos: true,
645
+ backgroundColor: "#fff",
646
+ lineColor: "#000",
647
+ textColor: "#000",
648
+ style: this.getGuidesStyle(type)
649
+ });
650
+ this.hGuidesChangeGuidesHandler = (e) => {
651
+ this.horizontalGuidelines = e.guides;
652
+ this.emit("changeGuides", {
653
+ type: GuidesType.HORIZONTAL,
654
+ guides: this.horizontalGuidelines
655
+ });
656
+ };
657
+ this.vGuidesChangeGuidesHandler = (e) => {
658
+ this.verticalGuidelines = e.guides;
659
+ this.emit("changeGuides", {
660
+ type: GuidesType.VERTICAL,
661
+ guides: this.verticalGuidelines
662
+ });
663
+ };
558
664
  this.container = container;
559
665
  this.hGuides = this.createGuides(GuidesType.HORIZONTAL);
560
666
  this.vGuides = this.createGuides(GuidesType.VERTICAL);
@@ -623,37 +729,6 @@ class Rule extends EventEmitter$1 {
623
729
  this.containerResizeObserver.disconnect();
624
730
  this.removeAllListeners();
625
731
  }
626
- getGuidesStyle = (type) => ({
627
- position: "fixed",
628
- zIndex: 1,
629
- left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
630
- top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
631
- width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
632
- height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
633
- });
634
- createGuides = (type, defaultGuides = []) => new Guides(this.container, {
635
- type,
636
- defaultGuides,
637
- displayDragPos: true,
638
- backgroundColor: "#fff",
639
- lineColor: "#000",
640
- textColor: "#000",
641
- style: this.getGuidesStyle(type)
642
- });
643
- hGuidesChangeGuidesHandler = (e) => {
644
- this.horizontalGuidelines = e.guides;
645
- this.emit("changeGuides", {
646
- type: GuidesType.HORIZONTAL,
647
- guides: this.horizontalGuidelines
648
- });
649
- };
650
- vGuidesChangeGuidesHandler = (e) => {
651
- this.verticalGuidelines = e.guides;
652
- this.emit("changeGuides", {
653
- type: GuidesType.VERTICAL,
654
- guides: this.verticalGuidelines
655
- });
656
- };
657
732
  }
658
733
 
659
734
  const wrapperClassName = "editor-mask-wrapper";
@@ -691,28 +766,66 @@ const createWrapper = () => {
691
766
  return el;
692
767
  };
693
768
  class StageMask extends Rule {
694
- content = createContent();
695
- wrapper;
696
- core;
697
- page = null;
698
- pageScrollParent = null;
699
- scrollTop = 0;
700
- scrollLeft = 0;
701
- width = 0;
702
- height = 0;
703
- wrapperHeight = 0;
704
- wrapperWidth = 0;
705
- maxScrollTop = 0;
706
- maxScrollLeft = 0;
707
- mode = Mode.ABSOLUTE;
708
- pageResizeObserver = null;
709
- wrapperResizeObserver = null;
710
- highlightHandler = throttle((event) => {
711
- this.emit("highlight", event);
712
- }, throttleTime);
713
769
  constructor(config) {
714
770
  const wrapper = createWrapper();
715
771
  super(wrapper);
772
+ this.content = createContent();
773
+ this.page = null;
774
+ this.pageScrollParent = null;
775
+ this.scrollTop = 0;
776
+ this.scrollLeft = 0;
777
+ this.width = 0;
778
+ this.height = 0;
779
+ this.wrapperHeight = 0;
780
+ this.wrapperWidth = 0;
781
+ this.maxScrollTop = 0;
782
+ this.maxScrollLeft = 0;
783
+ this.mode = Mode.ABSOLUTE;
784
+ this.pageResizeObserver = null;
785
+ this.wrapperResizeObserver = null;
786
+ this.highlightHandler = throttle((event) => {
787
+ this.emit("highlight", event);
788
+ }, throttleTime);
789
+ this.mouseDownHandler = (event) => {
790
+ this.emit("clearHighlight");
791
+ event.stopImmediatePropagation();
792
+ event.stopPropagation();
793
+ if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
794
+ return;
795
+ if (event.target.className.indexOf("moveable-control") !== -1) {
796
+ return;
797
+ }
798
+ this.content.removeEventListener("mousemove", this.highlightHandler);
799
+ this.emit("beforeSelect", event);
800
+ globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
801
+ };
802
+ this.mouseUpHandler = () => {
803
+ globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
804
+ this.content.addEventListener("mousemove", this.highlightHandler);
805
+ this.emit("select");
806
+ };
807
+ this.mouseWheelHandler = (event) => {
808
+ this.emit("clearHighlight");
809
+ if (!this.page)
810
+ throw new Error("page \u672A\u521D\u59CB\u5316");
811
+ const { deltaY, deltaX } = event;
812
+ if (this.page.clientHeight < this.wrapperHeight && deltaY)
813
+ return;
814
+ if (this.page.clientWidth < this.wrapperWidth && deltaX)
815
+ return;
816
+ if (this.maxScrollTop > 0) {
817
+ this.scrollTop = this.scrollTop + deltaY;
818
+ }
819
+ if (this.maxScrollLeft > 0) {
820
+ this.scrollLeft = this.scrollLeft + deltaX;
821
+ }
822
+ this.fixScrollValue();
823
+ this.scroll();
824
+ this.emit("scroll", event);
825
+ };
826
+ this.mouseLeaveHandler = () => {
827
+ setTimeout(() => this.emit("clearHighlight"), throttleTime);
828
+ };
716
829
  this.wrapper = wrapper;
717
830
  this.core = config.core;
718
831
  this.content.addEventListener("mousedown", this.mouseDownHandler);
@@ -821,53 +934,51 @@ class StageMask extends Rule {
821
934
  if (this.maxScrollLeft < this.scrollLeft)
822
935
  this.scrollLeft = this.maxScrollLeft;
823
936
  }
824
- mouseDownHandler = (event) => {
825
- this.emit("clearHighlight");
826
- event.stopImmediatePropagation();
827
- event.stopPropagation();
828
- if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
829
- return;
830
- if (event.target.className.indexOf("moveable-control") !== -1) {
831
- return;
832
- }
833
- this.content.removeEventListener("mousemove", this.highlightHandler);
834
- this.emit("beforeSelect", event);
835
- globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
836
- };
837
- mouseUpHandler = () => {
838
- globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
839
- this.content.addEventListener("mousemove", this.highlightHandler);
840
- this.emit("select");
841
- };
842
- mouseWheelHandler = (event) => {
843
- this.emit("clearHighlight");
844
- if (!this.page)
845
- throw new Error("page \u672A\u521D\u59CB\u5316");
846
- const { deltaY, deltaX } = event;
847
- if (this.maxScrollTop > 0) {
848
- this.scrollTop = this.scrollTop + deltaY;
849
- }
850
- if (this.maxScrollLeft > 0) {
851
- this.scrollLeft = this.scrollLeft + deltaX;
852
- }
853
- this.fixScrollValue();
854
- this.scroll();
855
- this.emit("scroll", event);
856
- };
857
- mouseLeaveHandler = () => {
858
- setTimeout(() => this.emit("clearHighlight"), throttleTime);
859
- };
860
937
  }
861
938
 
862
939
  class StageRender extends EventEmitter {
863
- contentWindow = null;
864
- runtime = null;
865
- iframe;
866
- runtimeUrl;
867
- core;
868
- render;
869
940
  constructor({ core }) {
870
941
  super();
942
+ this.contentWindow = null;
943
+ this.runtime = null;
944
+ this.getMagicApi = () => ({
945
+ onPageElUpdate: (el) => this.emit("page-el-update", el),
946
+ onRuntimeReady: (runtime) => {
947
+ this.runtime = runtime;
948
+ globalThis.runtime = runtime;
949
+ this.emit("runtime-ready", runtime);
950
+ }
951
+ });
952
+ this.getRuntime = () => {
953
+ if (this.runtime)
954
+ return Promise.resolve(this.runtime);
955
+ return new Promise((resolve) => {
956
+ const listener = (runtime) => {
957
+ this.off("runtime-ready", listener);
958
+ resolve(runtime);
959
+ };
960
+ this.on("runtime-ready", listener);
961
+ });
962
+ };
963
+ this.loadHandler = async () => {
964
+ this.emit("onload");
965
+ if (this.render) {
966
+ const el = await this.render(this.core);
967
+ if (el) {
968
+ this.iframe?.contentDocument?.body?.appendChild(el);
969
+ }
970
+ }
971
+ if (this.contentWindow) {
972
+ const style = this.contentWindow.document.createElement("style");
973
+ style.id = "tmagic-stage-render";
974
+ style.innerHTML = `
975
+ .${SELECTED_CLASS}, .${SELECTED_CLASS}-parent {
976
+ z-index: ${ZIndex.SELECTED_EL};
977
+ }
978
+ `;
979
+ this.contentWindow.document.head.appendChild(style);
980
+ }
981
+ };
871
982
  this.core = core;
872
983
  this.runtimeUrl = core.config.runtimeUrl || "";
873
984
  this.render = core.config.render;
@@ -880,14 +991,6 @@ class StageRender extends EventEmitter {
880
991
  `;
881
992
  this.iframe.addEventListener("load", this.loadHandler);
882
993
  }
883
- getMagicApi = () => ({
884
- onPageElUpdate: (el) => this.emit("page-el-update", el),
885
- onRuntimeReady: (runtime) => {
886
- this.runtime = runtime;
887
- globalThis.runtime = runtime;
888
- this.emit("runtime-ready", runtime);
889
- }
890
- });
891
994
  async mount(el) {
892
995
  if (this.iframe) {
893
996
  if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
@@ -904,17 +1007,6 @@ class StageRender extends EventEmitter {
904
1007
  throw Error("mount \u5931\u8D25");
905
1008
  }
906
1009
  }
907
- getRuntime = () => {
908
- if (this.runtime)
909
- return Promise.resolve(this.runtime);
910
- return new Promise((resolve) => {
911
- const listener = (runtime) => {
912
- this.off("runtime-ready", listener);
913
- resolve(runtime);
914
- };
915
- this.on("runtime-ready", listener);
916
- });
917
- };
918
1010
  destroy() {
919
1011
  this.iframe?.removeEventListener("load", this.loadHandler);
920
1012
  this.contentWindow = null;
@@ -922,40 +1014,12 @@ class StageRender extends EventEmitter {
922
1014
  this.iframe = void 0;
923
1015
  this.removeAllListeners();
924
1016
  }
925
- loadHandler = async () => {
926
- this.emit("onload");
927
- if (this.render) {
928
- const el = await this.render(this.core);
929
- if (el) {
930
- this.iframe?.contentDocument?.body?.appendChild(el);
931
- }
932
- }
933
- if (this.contentWindow) {
934
- const style = this.contentWindow.document.createElement("style");
935
- style.id = "tmagic-stage-render";
936
- style.innerHTML = `
937
- .${SELECTED_CLASS}, .${SELECTED_CLASS}-parent {
938
- z-index: ${ZIndex.SELECTED_EL};
939
- }
940
- `;
941
- this.contentWindow.document.head.appendChild(style);
942
- }
943
- };
944
1017
  }
945
1018
 
946
1019
  class StageCore extends EventEmitter {
947
- selectedDom;
948
- highlightedDom;
949
- renderer;
950
- mask;
951
- dr;
952
- highlightLayer;
953
- config;
954
- zoom = DEFAULT_ZOOM;
955
- container;
956
- canSelect;
957
1020
  constructor(config) {
958
1021
  super();
1022
+ this.zoom = DEFAULT_ZOOM;
959
1023
  this.config = config;
960
1024
  this.setZoom(config.zoom);
961
1025
  this.canSelect = config.canSelect || ((el) => !!el.id);