@tmagic/stage 1.0.3 → 1.1.0-beta.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/tmagic-stage.es.js +92 -56
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +112 -64
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageCore.d.ts +6 -2
- package/dist/types/src/StageDragResize.d.ts +1 -1
- package/dist/types/src/const.d.ts +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/types.d.ts +5 -0
- package/dist/types/src/util.d.ts +1 -6
- package/dist/types/src/vite-env.d.ts +1 -0
- package/package.json +4 -4
- package/src/StageCore.ts +16 -4
- package/src/StageDragResize.ts +87 -36
- package/src/StageHighlight.ts +0 -1
- package/src/StageMask.ts +4 -6
- package/src/StageRender.ts +5 -1
- package/src/TargetCalibrate.ts +0 -1
- package/src/const.ts +2 -0
- package/src/index.ts +1 -0
- package/src/style.css +10 -0
- package/src/types.ts +5 -0
- package/src/util.ts +15 -20
- package/src/vite-env.d.ts +1 -0
package/dist/tmagic-stage.es.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import EventEmitter$1, { EventEmitter } from 'events';
|
|
2
2
|
import Moveable from 'moveable';
|
|
3
3
|
import MoveableHelper from 'moveable-helper';
|
|
4
|
+
import { removeClassName, addClassName, removeClassNameByClassName, createDiv, injectStyle, isSameDomain, getHost } from '@tmagic/utils';
|
|
4
5
|
import { throttle } from 'lodash-es';
|
|
5
6
|
import Guides from '@scena/guides';
|
|
6
7
|
|
|
7
8
|
const GHOST_EL_ID_PREFIX = "ghost_el_";
|
|
8
9
|
const DRAG_EL_ID_PREFIX = "drag_el_";
|
|
9
10
|
const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
|
|
11
|
+
const CONTAINER_HIGHLIGHT_CLASS = "tmagic-stage-container-highlight";
|
|
10
12
|
const DEFAULT_ZOOM = 1;
|
|
11
13
|
var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
|
|
12
14
|
GuidesType2["HORIZONTAL"] = "horizontal";
|
|
@@ -70,13 +72,6 @@ const getAbsolutePosition = (el, { top, left }) => {
|
|
|
70
72
|
}
|
|
71
73
|
return { left, top };
|
|
72
74
|
};
|
|
73
|
-
const getHost = (targetUrl) => targetUrl.match(/\/\/([^/]+)/)?.[1];
|
|
74
|
-
const isSameDomain = (targetUrl = "", source = globalThis.location.host) => {
|
|
75
|
-
const isHttpUrl = /^(http[s]?:)?\/\//.test(targetUrl);
|
|
76
|
-
if (!isHttpUrl)
|
|
77
|
-
return true;
|
|
78
|
-
return getHost(targetUrl) === source;
|
|
79
|
-
};
|
|
80
75
|
const isAbsolute = (style) => style.position === "absolute";
|
|
81
76
|
const isRelative = (style) => style.position === "relative";
|
|
82
77
|
const isStatic = (style) => style.position === "static";
|
|
@@ -120,19 +115,14 @@ const getScrollParent = (element, includeHidden = false) => {
|
|
|
120
115
|
}
|
|
121
116
|
return null;
|
|
122
117
|
};
|
|
123
|
-
const createDiv = ({ className, cssText }) => {
|
|
124
|
-
const el = globalThis.document.createElement("div");
|
|
125
|
-
el.className = className;
|
|
126
|
-
el.style.cssText = cssText;
|
|
127
|
-
return el;
|
|
128
|
-
};
|
|
129
118
|
const removeSelectedClassName = (doc) => {
|
|
130
119
|
const oldEl = doc.querySelector(`.${SELECTED_CLASS}`);
|
|
131
120
|
if (oldEl) {
|
|
132
|
-
oldEl
|
|
133
|
-
oldEl.parentNode
|
|
121
|
+
removeClassName(oldEl, SELECTED_CLASS);
|
|
122
|
+
if (oldEl.parentNode)
|
|
123
|
+
removeClassName(oldEl.parentNode, `${SELECTED_CLASS}-parent`);
|
|
134
124
|
doc.querySelectorAll(`.${SELECTED_CLASS}-parents`).forEach((item) => {
|
|
135
|
-
item
|
|
125
|
+
removeClassName(item, `${SELECTED_CLASS}-parents`);
|
|
136
126
|
});
|
|
137
127
|
}
|
|
138
128
|
};
|
|
@@ -143,6 +133,14 @@ const addSelectedClassName = (el, doc) => {
|
|
|
143
133
|
item.classList.add(`${SELECTED_CLASS}-parents`);
|
|
144
134
|
});
|
|
145
135
|
};
|
|
136
|
+
const calcValueByFontsize = (doc, value) => {
|
|
137
|
+
const { fontSize } = doc.documentElement.style;
|
|
138
|
+
if (fontSize) {
|
|
139
|
+
const times = globalThis.parseFloat(fontSize) / 100;
|
|
140
|
+
return Number((value / times).toFixed(2));
|
|
141
|
+
}
|
|
142
|
+
return value;
|
|
143
|
+
};
|
|
146
144
|
|
|
147
145
|
class StageDragResize extends EventEmitter {
|
|
148
146
|
constructor(config) {
|
|
@@ -231,19 +229,22 @@ class StageDragResize extends EventEmitter {
|
|
|
231
229
|
});
|
|
232
230
|
this.elementGuidelines = [];
|
|
233
231
|
if (this.mode === Mode.ABSOLUTE) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
232
|
+
this.container.append(this.createGuidelineElements(nodes));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
createGuidelineElements(nodes) {
|
|
236
|
+
const frame = globalThis.document.createDocumentFragment();
|
|
237
|
+
for (const node of nodes) {
|
|
238
|
+
const { width, height } = node.getBoundingClientRect();
|
|
239
|
+
if (node === this.target)
|
|
240
|
+
continue;
|
|
241
|
+
const { left, top } = getOffset(node);
|
|
242
|
+
const elementGuideline = globalThis.document.createElement("div");
|
|
243
|
+
elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
|
|
244
|
+
this.elementGuidelines.push(elementGuideline);
|
|
245
|
+
frame.append(elementGuideline);
|
|
246
246
|
}
|
|
247
|
+
return frame;
|
|
247
248
|
}
|
|
248
249
|
initMoveable() {
|
|
249
250
|
this.moveable?.destroy();
|
|
@@ -296,6 +297,9 @@ class StageDragResize extends EventEmitter {
|
|
|
296
297
|
left: 0,
|
|
297
298
|
top: 0
|
|
298
299
|
};
|
|
300
|
+
let timeout;
|
|
301
|
+
const { contentWindow } = this.core.renderer;
|
|
302
|
+
const doc = contentWindow?.document;
|
|
299
303
|
this.moveable.on("dragStart", (e) => {
|
|
300
304
|
if (!this.target)
|
|
301
305
|
throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
|
|
@@ -309,6 +313,19 @@ class StageDragResize extends EventEmitter {
|
|
|
309
313
|
}).on("drag", (e) => {
|
|
310
314
|
if (!this.target || !this.dragEl)
|
|
311
315
|
return;
|
|
316
|
+
if (timeout) {
|
|
317
|
+
globalThis.clearTimeout(timeout);
|
|
318
|
+
timeout = void 0;
|
|
319
|
+
}
|
|
320
|
+
timeout = globalThis.setTimeout(async () => {
|
|
321
|
+
const els = this.core.getElementsFromPoint(e.inputEvent);
|
|
322
|
+
for (const el of els) {
|
|
323
|
+
if (doc && !el.id.startsWith(GHOST_EL_ID_PREFIX) && el !== this.target && await this.core.isContainer(el)) {
|
|
324
|
+
addClassName(el, doc, this.core.containerHighlightClassName);
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}, this.core.containerHighlightDuration);
|
|
312
329
|
this.dragStatus = "ing" /* ING */;
|
|
313
330
|
if (this.ghostEl) {
|
|
314
331
|
this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
@@ -318,13 +335,25 @@ class StageDragResize extends EventEmitter {
|
|
|
318
335
|
this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
|
|
319
336
|
this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
320
337
|
}).on("dragEnd", () => {
|
|
338
|
+
if (timeout) {
|
|
339
|
+
globalThis.clearTimeout(timeout);
|
|
340
|
+
timeout = void 0;
|
|
341
|
+
}
|
|
342
|
+
let parentEl = null;
|
|
343
|
+
if (doc) {
|
|
344
|
+
parentEl = removeClassNameByClassName(doc, this.core.containerHighlightClassName);
|
|
345
|
+
}
|
|
321
346
|
if (this.dragStatus === "ing" /* ING */) {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
347
|
+
if (parentEl) {
|
|
348
|
+
this.update(false, parentEl);
|
|
349
|
+
} else {
|
|
350
|
+
switch (this.mode) {
|
|
351
|
+
case Mode.SORTABLE:
|
|
352
|
+
this.sort();
|
|
353
|
+
break;
|
|
354
|
+
default:
|
|
355
|
+
this.update();
|
|
356
|
+
}
|
|
328
357
|
}
|
|
329
358
|
}
|
|
330
359
|
this.dragStatus = "end" /* END */;
|
|
@@ -398,16 +427,27 @@ class StageDragResize extends EventEmitter {
|
|
|
398
427
|
});
|
|
399
428
|
}
|
|
400
429
|
}
|
|
401
|
-
update(isResize = false) {
|
|
430
|
+
update(isResize = false, parentEl = null) {
|
|
402
431
|
if (!this.target)
|
|
403
432
|
return;
|
|
433
|
+
const { contentWindow } = this.core.renderer;
|
|
434
|
+
const doc = contentWindow?.document;
|
|
435
|
+
if (!doc)
|
|
436
|
+
return;
|
|
404
437
|
const offset = this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: this.target.offsetLeft, top: this.target.offsetTop };
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const width =
|
|
408
|
-
const height =
|
|
438
|
+
let left = calcValueByFontsize(doc, offset.left);
|
|
439
|
+
let top = calcValueByFontsize(doc, offset.top);
|
|
440
|
+
const width = calcValueByFontsize(doc, this.target.clientWidth);
|
|
441
|
+
const height = calcValueByFontsize(doc, this.target.clientHeight);
|
|
442
|
+
if (parentEl && this.mode === Mode.ABSOLUTE && this.dragEl) {
|
|
443
|
+
const [translateX, translateY] = this.moveableHelper?.getFrame(this.dragEl).properties.transform.translate.value;
|
|
444
|
+
const { left: parentLeft, top: parentTop } = getOffset(parentEl);
|
|
445
|
+
left = calcValueByFontsize(doc, this.dragEl.offsetLeft) + parseFloat(translateX) - calcValueByFontsize(doc, parentLeft);
|
|
446
|
+
top = calcValueByFontsize(doc, this.dragEl.offsetTop) + parseFloat(translateY) - calcValueByFontsize(doc, parentTop);
|
|
447
|
+
}
|
|
409
448
|
this.emit("update", {
|
|
410
449
|
el: this.target,
|
|
450
|
+
parentEl,
|
|
411
451
|
style: isResize ? { left, top, width, height } : { left, top }
|
|
412
452
|
});
|
|
413
453
|
}
|
|
@@ -508,15 +548,6 @@ class StageDragResize extends EventEmitter {
|
|
|
508
548
|
...moveableOptions
|
|
509
549
|
};
|
|
510
550
|
}
|
|
511
|
-
calcValueByFontsize(value) {
|
|
512
|
-
const { contentWindow } = this.core.renderer;
|
|
513
|
-
const fontSize = contentWindow?.document.documentElement.style.fontSize;
|
|
514
|
-
if (fontSize) {
|
|
515
|
-
const times = globalThis.parseFloat(fontSize) / 100;
|
|
516
|
-
return (value / times).toFixed(2);
|
|
517
|
-
}
|
|
518
|
-
return value;
|
|
519
|
-
}
|
|
520
551
|
}
|
|
521
552
|
const down = (deltaTop, target) => {
|
|
522
553
|
let swapIndex = 0;
|
|
@@ -780,11 +811,7 @@ class Rule extends EventEmitter$1 {
|
|
|
780
811
|
const wrapperClassName = "editor-mask-wrapper";
|
|
781
812
|
const throttleTime = 100;
|
|
782
813
|
const hideScrollbar = () => {
|
|
783
|
-
|
|
784
|
-
style.innerHTML = `
|
|
785
|
-
.${wrapperClassName}::-webkit-scrollbar { width: 0 !important; display: none }
|
|
786
|
-
`;
|
|
787
|
-
globalThis.document.head.appendChild(style);
|
|
814
|
+
injectStyle(globalThis.document, `.${wrapperClassName}::-webkit-scrollbar { width: 0 !important; display: none }`);
|
|
788
815
|
};
|
|
789
816
|
const createContent = () => createDiv({
|
|
790
817
|
className: "editor-mask",
|
|
@@ -1009,6 +1036,8 @@ class StageMask extends Rule {
|
|
|
1009
1036
|
}
|
|
1010
1037
|
}
|
|
1011
1038
|
|
|
1039
|
+
var style = ".tmagic-stage-container-highlight::after {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background-color: #000;\n opacity: .1;\n}\n";
|
|
1040
|
+
|
|
1012
1041
|
class StageRender extends EventEmitter {
|
|
1013
1042
|
constructor({ core }) {
|
|
1014
1043
|
super();
|
|
@@ -1046,6 +1075,7 @@ class StageRender extends EventEmitter {
|
|
|
1046
1075
|
this.contentWindow.postMessage({
|
|
1047
1076
|
tmagicRuntimeReady: true
|
|
1048
1077
|
}, "*");
|
|
1078
|
+
injectStyle(this.contentWindow.document, style);
|
|
1049
1079
|
};
|
|
1050
1080
|
this.core = core;
|
|
1051
1081
|
this.runtimeUrl = core.config.runtimeUrl || "";
|
|
@@ -1089,6 +1119,9 @@ class StageCore extends EventEmitter {
|
|
|
1089
1119
|
this.config = config;
|
|
1090
1120
|
this.setZoom(config.zoom);
|
|
1091
1121
|
this.canSelect = config.canSelect || ((el) => !!el.id);
|
|
1122
|
+
this.isContainer = config.isContainer;
|
|
1123
|
+
this.containerHighlightClassName = config.containerHighlightClassName;
|
|
1124
|
+
this.containerHighlightDuration = config.containerHighlightDuration;
|
|
1092
1125
|
this.renderer = new StageRender({ core: this });
|
|
1093
1126
|
this.mask = new StageMask({ core: this });
|
|
1094
1127
|
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
|
@@ -1123,7 +1156,7 @@ class StageCore extends EventEmitter {
|
|
|
1123
1156
|
setTimeout(() => this.emit("sort", data));
|
|
1124
1157
|
});
|
|
1125
1158
|
}
|
|
1126
|
-
|
|
1159
|
+
getElementsFromPoint(event) {
|
|
1127
1160
|
const { renderer, zoom } = this;
|
|
1128
1161
|
const doc = renderer.contentWindow?.document;
|
|
1129
1162
|
let x = event.clientX;
|
|
@@ -1135,7 +1168,10 @@ class StageCore extends EventEmitter {
|
|
|
1135
1168
|
y = y - rect.top;
|
|
1136
1169
|
}
|
|
1137
1170
|
}
|
|
1138
|
-
|
|
1171
|
+
return doc?.elementsFromPoint(x / zoom, y / zoom);
|
|
1172
|
+
}
|
|
1173
|
+
async setElementFromPoint(event) {
|
|
1174
|
+
const els = this.getElementsFromPoint(event);
|
|
1139
1175
|
let stopped = false;
|
|
1140
1176
|
const stop = () => stopped = true;
|
|
1141
1177
|
for (const el of els) {
|
|
@@ -1243,5 +1279,5 @@ class StageCore extends EventEmitter {
|
|
|
1243
1279
|
}
|
|
1244
1280
|
}
|
|
1245
1281
|
|
|
1246
|
-
export { DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, HIGHLIGHT_EL_ID_PREFIX, Mode, MouseButton, SELECTED_CLASS, StageDragResize, StageMask, StageRender, ZIndex, StageCore as default };
|
|
1282
|
+
export { CONTAINER_HIGHLIGHT_CLASS, DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, HIGHLIGHT_EL_ID_PREFIX, Mode, MouseButton, SELECTED_CLASS, StageDragResize, StageMask, StageRender, ZIndex, addSelectedClassName, calcValueByFontsize, StageCore as default, getAbsolutePosition, getMode, getOffset, getScrollParent, isAbsolute, isFixed, isFixedParent, isRelative, isStatic, removeSelectedClassName };
|
|
1247
1283
|
//# sourceMappingURL=tmagic-stage.es.js.map
|