@tmagic/stage 1.7.9 → 1.7.11
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/es/ActionManager.js +20 -0
- package/dist/es/MoveableOptionsManager.js +3 -1
- package/dist/es/Rule.js +1 -1
- package/dist/es/StageCore.js +32 -1
- package/dist/es/StageRender.js +16 -0
- package/dist/tmagic-stage.umd.cjs +83 -13
- package/package.json +4 -3
- package/src/ActionManager.ts +24 -0
- package/src/Rule.ts +1 -1
- package/src/StageCore.ts +48 -1
- package/src/StageRender.ts +31 -0
- package/types/index.d.ts +20 -2
package/dist/es/ActionManager.js
CHANGED
|
@@ -151,6 +151,26 @@ var ActionManager = class extends EventEmitter$1 {
|
|
|
151
151
|
return null;
|
|
152
152
|
}
|
|
153
153
|
/**
|
|
154
|
+
* 获取鼠标下方第二个可选中元素(跳过最上层),用于双击穿透选中下方元素
|
|
155
|
+
* @param event 鼠标事件
|
|
156
|
+
* @returns 鼠标下方第二个可选中元素,不存在时返回 null
|
|
157
|
+
*/
|
|
158
|
+
async getNextElementFromPoint(event) {
|
|
159
|
+
const els = this.getElementsFromPoint(event);
|
|
160
|
+
let stopped = false;
|
|
161
|
+
const stop = () => stopped = true;
|
|
162
|
+
let skippedFirst = false;
|
|
163
|
+
for (const el of els) if (!getIdFromEl()(el)?.startsWith("ghost_el_") && await this.isElCanSelect(el, event, stop)) {
|
|
164
|
+
if (stopped) break;
|
|
165
|
+
if (!skippedFirst) {
|
|
166
|
+
skippedFirst = true;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
return el;
|
|
170
|
+
}
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
154
174
|
* 判断一个元素能否在当前场景被选中
|
|
155
175
|
* @param el 被判断的元素
|
|
156
176
|
* @param event 鼠标事件
|
|
@@ -70,7 +70,9 @@ var MoveableOptionsManager = class extends EventEmitter$1 {
|
|
|
70
70
|
* @returns moveable所需参数
|
|
71
71
|
*/
|
|
72
72
|
getOptions(isMultiSelect, runtimeOptions = {}) {
|
|
73
|
-
|
|
73
|
+
const defaultOptions = this.getDefaultOptions(isMultiSelect);
|
|
74
|
+
const customizedOptions = this.getCustomizeOptions() || {};
|
|
75
|
+
this.options = merge(defaultOptions, customizedOptions, runtimeOptions);
|
|
74
76
|
return this.options;
|
|
75
77
|
}
|
|
76
78
|
/**
|
package/dist/es/Rule.js
CHANGED
|
@@ -79,6 +79,7 @@ var Rule = class extends EventEmitter$1 {
|
|
|
79
79
|
this.hGuides?.off("changeGuides", this.hGuidesChangeGuidesHandler);
|
|
80
80
|
this.vGuides?.off("changeGuides", this.vGuidesChangeGuidesHandler);
|
|
81
81
|
this.containerResizeObserver?.disconnect();
|
|
82
|
+
this.container = void 0;
|
|
82
83
|
this.removeAllListeners();
|
|
83
84
|
}
|
|
84
85
|
destroyGuides() {
|
|
@@ -89,7 +90,6 @@ var Rule = class extends EventEmitter$1 {
|
|
|
89
90
|
});
|
|
90
91
|
this.hGuides = void 0;
|
|
91
92
|
this.vGuides = void 0;
|
|
92
|
-
this.container = void 0;
|
|
93
93
|
}
|
|
94
94
|
getGuidesStyle = (type) => ({
|
|
95
95
|
position: "fixed",
|
package/dist/es/StageCore.js
CHANGED
|
@@ -43,7 +43,31 @@ var StageCore = class extends EventEmitter {
|
|
|
43
43
|
* @param id 选中的id
|
|
44
44
|
*/
|
|
45
45
|
async select(id, event) {
|
|
46
|
-
|
|
46
|
+
if (!this.renderer) return;
|
|
47
|
+
let el = this.renderer.getTargetElement(id) || null;
|
|
48
|
+
if (!el) el = await new Promise((resolve) => {
|
|
49
|
+
const observer = new MutationObserver(() => {
|
|
50
|
+
const target = this.renderer?.getTargetElement(id);
|
|
51
|
+
if (target) {
|
|
52
|
+
observer.disconnect();
|
|
53
|
+
clearTimeout(timer);
|
|
54
|
+
resolve(target);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const body = this.renderer?.getDocument()?.body;
|
|
58
|
+
if (!body) {
|
|
59
|
+
resolve(null);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
observer.observe(body, {
|
|
63
|
+
childList: true,
|
|
64
|
+
subtree: true
|
|
65
|
+
});
|
|
66
|
+
const timer = setTimeout(() => {
|
|
67
|
+
observer.disconnect();
|
|
68
|
+
resolve(this.renderer?.getTargetElement(id) || null);
|
|
69
|
+
}, 1e3);
|
|
70
|
+
});
|
|
47
71
|
if (el === this.actionManager?.getSelectedEl()) return;
|
|
48
72
|
await this.renderer?.select([id]);
|
|
49
73
|
if (el) this.mask?.setLayout(el);
|
|
@@ -157,6 +181,13 @@ var StageCore = class extends EventEmitter {
|
|
|
157
181
|
this.renderer?.reloadIframe(url);
|
|
158
182
|
}
|
|
159
183
|
/**
|
|
184
|
+
* 将指定id的dom元素生成为图片
|
|
185
|
+
*/
|
|
186
|
+
async getElementImage(id, type = "png", options = {}) {
|
|
187
|
+
if (!this.renderer) throw new Error("Renderer is not initialized");
|
|
188
|
+
return this.renderer.getElementImage(id, type, options);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
160
191
|
* 销毁实例
|
|
161
192
|
*/
|
|
162
193
|
destroy() {
|
package/dist/es/StageRender.js
CHANGED
|
@@ -3,6 +3,7 @@ import { addSelectedClassName, removeSelectedClassName } from "./util.js";
|
|
|
3
3
|
import style_default from "./style.js";
|
|
4
4
|
import { EventEmitter } from "events";
|
|
5
5
|
import { getElById, getHost, guid, injectStyle, isSameDomain } from "@tmagic/core";
|
|
6
|
+
import { snapdom } from "@zumer/snapdom";
|
|
6
7
|
//#region packages/stage/src/StageRender.ts
|
|
7
8
|
var StageRender = class extends EventEmitter {
|
|
8
9
|
/** 组件的js、css执行的环境,直接渲染为当前window,iframe渲染则为iframe.contentWindow */
|
|
@@ -103,6 +104,21 @@ var StageRender = class extends EventEmitter {
|
|
|
103
104
|
getTargetElement(id) {
|
|
104
105
|
return getElById()(this.getDocument(), id);
|
|
105
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* 将指定id的dom元素生成为图片
|
|
109
|
+
* @param id 目标元素的id
|
|
110
|
+
* @param options 图片生成选项
|
|
111
|
+
* @returns data URL 格式的图片数据
|
|
112
|
+
*/
|
|
113
|
+
async getElementImage(id, type = "png", options = {}) {
|
|
114
|
+
const el = this.getTargetElement(id);
|
|
115
|
+
if (!el) throw new Error(`Element with id "${id}" not found`);
|
|
116
|
+
el.scrollIntoView();
|
|
117
|
+
const toFunc = `to${type.charAt(0).toUpperCase() + type.slice(1)}`;
|
|
118
|
+
const result = await snapdom(el, options);
|
|
119
|
+
if (toFunc in result) return result[toFunc]();
|
|
120
|
+
throw new Error(`Invalid type: ${type}`);
|
|
121
|
+
}
|
|
106
122
|
postTmagicRuntimeReady() {
|
|
107
123
|
this.contentWindow = this.iframe?.contentWindow;
|
|
108
124
|
this.contentWindow.magic = this.getMagicApi();
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("events"), require("@tmagic/core"), require("keycon"), require("moveable-helper"), require("moveable"), require("@scena/guides")) : typeof define === "function" && define.amd ? define([
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("events"), require("@tmagic/core"), require("keycon"), require("moveable-helper"), require("moveable"), require("@scena/guides"), require("@zumer/snapdom")) : typeof define === "function" && define.amd ? define([
|
|
3
3
|
"exports",
|
|
4
4
|
"events",
|
|
5
5
|
"@tmagic/core",
|
|
6
6
|
"keycon",
|
|
7
7
|
"moveable-helper",
|
|
8
8
|
"moveable",
|
|
9
|
-
"@scena/guides"
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
"@scena/guides",
|
|
10
|
+
"@zumer/snapdom"
|
|
11
|
+
], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.TMagicStage = {}, global.events, global._tmagic_core, global.keycon, global.moveable_helper, global.moveable, global._scena_guides, global._zumer_snapdom));
|
|
12
|
+
})(this, function(exports, events, _tmagic_core, keycon, moveable_helper, moveable, _scena_guides, _zumer_snapdom) {
|
|
12
13
|
Object.defineProperties(exports, {
|
|
13
14
|
__esModule: { value: true },
|
|
14
15
|
[Symbol.toStringTag]: { value: "Module" }
|
|
@@ -35,11 +36,11 @@
|
|
|
35
36
|
enumerable: true
|
|
36
37
|
}) : target, mod));
|
|
37
38
|
//#endregion
|
|
38
|
-
events = __toESM(events);
|
|
39
|
-
keycon = __toESM(keycon);
|
|
40
|
-
moveable_helper = __toESM(moveable_helper);
|
|
41
|
-
moveable = __toESM(moveable);
|
|
42
|
-
_scena_guides = __toESM(_scena_guides);
|
|
39
|
+
events = __toESM(events, 1);
|
|
40
|
+
keycon = __toESM(keycon, 1);
|
|
41
|
+
moveable_helper = __toESM(moveable_helper, 1);
|
|
42
|
+
moveable = __toESM(moveable, 1);
|
|
43
|
+
_scena_guides = __toESM(_scena_guides, 1);
|
|
43
44
|
//#region node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_freeGlobal.js
|
|
44
45
|
/** Detect free variable `global` from Node.js. */
|
|
45
46
|
var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
|
|
@@ -1650,7 +1651,8 @@
|
|
|
1650
1651
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
1651
1652
|
*/
|
|
1652
1653
|
function Stack(entries) {
|
|
1653
|
-
|
|
1654
|
+
var data = this.__data__ = new ListCache(entries);
|
|
1655
|
+
this.size = data.size;
|
|
1654
1656
|
}
|
|
1655
1657
|
Stack.prototype.clear = stackClear;
|
|
1656
1658
|
Stack.prototype["delete"] = stackDelete;
|
|
@@ -2914,7 +2916,9 @@
|
|
|
2914
2916
|
* @returns moveable所需参数
|
|
2915
2917
|
*/
|
|
2916
2918
|
getOptions(isMultiSelect, runtimeOptions = {}) {
|
|
2917
|
-
|
|
2919
|
+
const defaultOptions = this.getDefaultOptions(isMultiSelect);
|
|
2920
|
+
const customizedOptions = this.getCustomizeOptions() || {};
|
|
2921
|
+
this.options = merge(defaultOptions, customizedOptions, runtimeOptions);
|
|
2918
2922
|
return this.options;
|
|
2919
2923
|
}
|
|
2920
2924
|
/**
|
|
@@ -3619,6 +3623,26 @@
|
|
|
3619
3623
|
return null;
|
|
3620
3624
|
}
|
|
3621
3625
|
/**
|
|
3626
|
+
* 获取鼠标下方第二个可选中元素(跳过最上层),用于双击穿透选中下方元素
|
|
3627
|
+
* @param event 鼠标事件
|
|
3628
|
+
* @returns 鼠标下方第二个可选中元素,不存在时返回 null
|
|
3629
|
+
*/
|
|
3630
|
+
async getNextElementFromPoint(event) {
|
|
3631
|
+
const els = this.getElementsFromPoint(event);
|
|
3632
|
+
let stopped = false;
|
|
3633
|
+
const stop = () => stopped = true;
|
|
3634
|
+
let skippedFirst = false;
|
|
3635
|
+
for (const el of els) if (!(0, _tmagic_core.getIdFromEl)()(el)?.startsWith("ghost_el_") && await this.isElCanSelect(el, event, stop)) {
|
|
3636
|
+
if (stopped) break;
|
|
3637
|
+
if (!skippedFirst) {
|
|
3638
|
+
skippedFirst = true;
|
|
3639
|
+
continue;
|
|
3640
|
+
}
|
|
3641
|
+
return el;
|
|
3642
|
+
}
|
|
3643
|
+
return null;
|
|
3644
|
+
}
|
|
3645
|
+
/**
|
|
3622
3646
|
* 判断一个元素能否在当前场景被选中
|
|
3623
3647
|
* @param el 被判断的元素
|
|
3624
3648
|
* @param event 鼠标事件
|
|
@@ -4013,6 +4037,7 @@
|
|
|
4013
4037
|
this.hGuides?.off("changeGuides", this.hGuidesChangeGuidesHandler);
|
|
4014
4038
|
this.vGuides?.off("changeGuides", this.vGuidesChangeGuidesHandler);
|
|
4015
4039
|
this.containerResizeObserver?.disconnect();
|
|
4040
|
+
this.container = void 0;
|
|
4016
4041
|
this.removeAllListeners();
|
|
4017
4042
|
}
|
|
4018
4043
|
destroyGuides() {
|
|
@@ -4023,7 +4048,6 @@
|
|
|
4023
4048
|
});
|
|
4024
4049
|
this.hGuides = void 0;
|
|
4025
4050
|
this.vGuides = void 0;
|
|
4026
|
-
this.container = void 0;
|
|
4027
4051
|
}
|
|
4028
4052
|
getGuidesStyle = (type) => ({
|
|
4029
4053
|
position: "fixed",
|
|
@@ -4424,6 +4448,21 @@
|
|
|
4424
4448
|
getTargetElement(id) {
|
|
4425
4449
|
return (0, _tmagic_core.getElById)()(this.getDocument(), id);
|
|
4426
4450
|
}
|
|
4451
|
+
/**
|
|
4452
|
+
* 将指定id的dom元素生成为图片
|
|
4453
|
+
* @param id 目标元素的id
|
|
4454
|
+
* @param options 图片生成选项
|
|
4455
|
+
* @returns data URL 格式的图片数据
|
|
4456
|
+
*/
|
|
4457
|
+
async getElementImage(id, type = "png", options = {}) {
|
|
4458
|
+
const el = this.getTargetElement(id);
|
|
4459
|
+
if (!el) throw new Error(`Element with id "${id}" not found`);
|
|
4460
|
+
el.scrollIntoView();
|
|
4461
|
+
const toFunc = `to${type.charAt(0).toUpperCase() + type.slice(1)}`;
|
|
4462
|
+
const result = await (0, _zumer_snapdom.snapdom)(el, options);
|
|
4463
|
+
if (toFunc in result) return result[toFunc]();
|
|
4464
|
+
throw new Error(`Invalid type: ${type}`);
|
|
4465
|
+
}
|
|
4427
4466
|
postTmagicRuntimeReady() {
|
|
4428
4467
|
this.contentWindow = this.iframe?.contentWindow;
|
|
4429
4468
|
this.contentWindow.magic = this.getMagicApi();
|
|
@@ -4543,7 +4582,31 @@
|
|
|
4543
4582
|
* @param id 选中的id
|
|
4544
4583
|
*/
|
|
4545
4584
|
async select(id, event) {
|
|
4546
|
-
|
|
4585
|
+
if (!this.renderer) return;
|
|
4586
|
+
let el = this.renderer.getTargetElement(id) || null;
|
|
4587
|
+
if (!el) el = await new Promise((resolve) => {
|
|
4588
|
+
const observer = new MutationObserver(() => {
|
|
4589
|
+
const target = this.renderer?.getTargetElement(id);
|
|
4590
|
+
if (target) {
|
|
4591
|
+
observer.disconnect();
|
|
4592
|
+
clearTimeout(timer);
|
|
4593
|
+
resolve(target);
|
|
4594
|
+
}
|
|
4595
|
+
});
|
|
4596
|
+
const body = this.renderer?.getDocument()?.body;
|
|
4597
|
+
if (!body) {
|
|
4598
|
+
resolve(null);
|
|
4599
|
+
return;
|
|
4600
|
+
}
|
|
4601
|
+
observer.observe(body, {
|
|
4602
|
+
childList: true,
|
|
4603
|
+
subtree: true
|
|
4604
|
+
});
|
|
4605
|
+
const timer = setTimeout(() => {
|
|
4606
|
+
observer.disconnect();
|
|
4607
|
+
resolve(this.renderer?.getTargetElement(id) || null);
|
|
4608
|
+
}, 1e3);
|
|
4609
|
+
});
|
|
4547
4610
|
if (el === this.actionManager?.getSelectedEl()) return;
|
|
4548
4611
|
await this.renderer?.select([id]);
|
|
4549
4612
|
if (el) this.mask?.setLayout(el);
|
|
@@ -4657,6 +4720,13 @@
|
|
|
4657
4720
|
this.renderer?.reloadIframe(url);
|
|
4658
4721
|
}
|
|
4659
4722
|
/**
|
|
4723
|
+
* 将指定id的dom元素生成为图片
|
|
4724
|
+
*/
|
|
4725
|
+
async getElementImage(id, type = "png", options = {}) {
|
|
4726
|
+
if (!this.renderer) throw new Error("Renderer is not initialized");
|
|
4727
|
+
return this.renderer.getElementImage(id, type, options);
|
|
4728
|
+
}
|
|
4729
|
+
/**
|
|
4660
4730
|
* 销毁实例
|
|
4661
4731
|
*/
|
|
4662
4732
|
destroy() {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.7.
|
|
2
|
+
"version": "1.7.11",
|
|
3
3
|
"name": "@tmagic/stage",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@scena/guides": "^0.29.2",
|
|
33
33
|
"events": "^3.3.0",
|
|
34
|
+
"@zumer/snapdom": "^2.8.0",
|
|
34
35
|
"keycon": "^1.4.0",
|
|
35
36
|
"lodash-es": "^4.17.21",
|
|
36
37
|
"moveable": "^0.53.0",
|
|
@@ -42,8 +43,8 @@
|
|
|
42
43
|
"@types/lodash-es": "^4.17.4"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
|
-
"typescript": "^
|
|
46
|
-
"@tmagic/core": "1.7.
|
|
46
|
+
"typescript": "^6.0.3",
|
|
47
|
+
"@tmagic/core": "1.7.11"
|
|
47
48
|
},
|
|
48
49
|
"peerDependenciesMeta": {
|
|
49
50
|
"typescript": {
|
package/src/ActionManager.ts
CHANGED
|
@@ -236,6 +236,30 @@ export default class ActionManager extends EventEmitter {
|
|
|
236
236
|
return null;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
/**
|
|
240
|
+
* 获取鼠标下方第二个可选中元素(跳过最上层),用于双击穿透选中下方元素
|
|
241
|
+
* @param event 鼠标事件
|
|
242
|
+
* @returns 鼠标下方第二个可选中元素,不存在时返回 null
|
|
243
|
+
*/
|
|
244
|
+
public async getNextElementFromPoint(event: MouseEvent): Promise<HTMLElement | null> {
|
|
245
|
+
const els = this.getElementsFromPoint(event as Point);
|
|
246
|
+
|
|
247
|
+
let stopped = false;
|
|
248
|
+
const stop = () => (stopped = true);
|
|
249
|
+
let skippedFirst = false;
|
|
250
|
+
for (const el of els) {
|
|
251
|
+
if (!getIdFromEl()(el)?.startsWith(GHOST_EL_ID_PREFIX) && (await this.isElCanSelect(el, event, stop))) {
|
|
252
|
+
if (stopped) break;
|
|
253
|
+
if (!skippedFirst) {
|
|
254
|
+
skippedFirst = true;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
return el;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
|
|
239
263
|
/**
|
|
240
264
|
* 判断一个元素能否在当前场景被选中
|
|
241
265
|
* @param el 被判断的元素
|
package/src/Rule.ts
CHANGED
|
@@ -124,6 +124,7 @@ export default class Rule extends EventEmitter {
|
|
|
124
124
|
this.hGuides?.off('changeGuides', this.hGuidesChangeGuidesHandler);
|
|
125
125
|
this.vGuides?.off('changeGuides', this.vGuidesChangeGuidesHandler);
|
|
126
126
|
this.containerResizeObserver?.disconnect();
|
|
127
|
+
this.container = undefined;
|
|
127
128
|
this.removeAllListeners();
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -137,7 +138,6 @@ export default class Rule extends EventEmitter {
|
|
|
137
138
|
|
|
138
139
|
this.hGuides = undefined;
|
|
139
140
|
this.vGuides = undefined;
|
|
140
|
-
this.container = undefined;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
private getGuidesStyle = (type: GuidesType) => ({
|
package/src/StageCore.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { EventEmitter } from 'events';
|
|
20
20
|
|
|
21
|
+
import { SnapdomOptions } from '@zumer/snapdom';
|
|
21
22
|
import type { MoveableOptions, OnDragStart } from 'moveable';
|
|
22
23
|
|
|
23
24
|
import type { Id } from '@tmagic/core';
|
|
@@ -88,7 +89,38 @@ export default class StageCore extends EventEmitter {
|
|
|
88
89
|
* @param id 选中的id
|
|
89
90
|
*/
|
|
90
91
|
public async select(id: Id, event?: MouseEvent): Promise<void> {
|
|
91
|
-
|
|
92
|
+
if (!this.renderer) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let el = this.renderer.getTargetElement(id) || null;
|
|
97
|
+
|
|
98
|
+
if (!el) {
|
|
99
|
+
el = await new Promise<HTMLElement | null>((resolve) => {
|
|
100
|
+
const observer = new MutationObserver(() => {
|
|
101
|
+
const target = this.renderer?.getTargetElement(id);
|
|
102
|
+
if (target) {
|
|
103
|
+
observer.disconnect();
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
resolve(target);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const body = this.renderer?.getDocument()?.body;
|
|
110
|
+
if (!body) {
|
|
111
|
+
resolve(null);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
observer.observe(body, { childList: true, subtree: true });
|
|
116
|
+
|
|
117
|
+
const timer = setTimeout(() => {
|
|
118
|
+
observer.disconnect();
|
|
119
|
+
resolve(this.renderer?.getTargetElement(id) || null);
|
|
120
|
+
}, 1000);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
92
124
|
if (el === this.actionManager?.getSelectedEl()) return;
|
|
93
125
|
|
|
94
126
|
await this.renderer?.select([id]);
|
|
@@ -241,6 +273,21 @@ export default class StageCore extends EventEmitter {
|
|
|
241
273
|
this.renderer?.reloadIframe(url);
|
|
242
274
|
}
|
|
243
275
|
|
|
276
|
+
/**
|
|
277
|
+
* 将指定id的dom元素生成为图片
|
|
278
|
+
*/
|
|
279
|
+
public async getElementImage(
|
|
280
|
+
id: Id,
|
|
281
|
+
type: 'download' | 'raw' | 'svg' | 'canvas' | 'png' | 'jpeg' | 'webp' | 'blob' = 'png',
|
|
282
|
+
options: SnapdomOptions = {},
|
|
283
|
+
) {
|
|
284
|
+
if (!this.renderer) {
|
|
285
|
+
throw new Error('Renderer is not initialized');
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return this.renderer.getElementImage(id, type, options);
|
|
289
|
+
}
|
|
290
|
+
|
|
244
291
|
/**
|
|
245
292
|
* 销毁实例
|
|
246
293
|
*/
|
package/src/StageRender.ts
CHANGED
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
|
|
19
19
|
import { EventEmitter } from 'events';
|
|
20
20
|
|
|
21
|
+
import { snapdom, SnapdomOptions } from '@zumer/snapdom';
|
|
22
|
+
|
|
21
23
|
import type { Id } from '@tmagic/core';
|
|
22
24
|
import { getElById, getHost, guid, injectStyle, isSameDomain } from '@tmagic/core';
|
|
23
25
|
|
|
@@ -162,6 +164,35 @@ export default class StageRender extends EventEmitter {
|
|
|
162
164
|
return getElById()(this.getDocument(), id);
|
|
163
165
|
}
|
|
164
166
|
|
|
167
|
+
/**
|
|
168
|
+
* 将指定id的dom元素生成为图片
|
|
169
|
+
* @param id 目标元素的id
|
|
170
|
+
* @param options 图片生成选项
|
|
171
|
+
* @returns data URL 格式的图片数据
|
|
172
|
+
*/
|
|
173
|
+
public async getElementImage(
|
|
174
|
+
id: Id,
|
|
175
|
+
type: 'download' | 'raw' | 'svg' | 'canvas' | 'png' | 'jpeg' | 'webp' | 'blob' = 'png',
|
|
176
|
+
options: SnapdomOptions = {},
|
|
177
|
+
) {
|
|
178
|
+
const el = this.getTargetElement(id);
|
|
179
|
+
if (!el) {
|
|
180
|
+
throw new Error(`Element with id "${id}" not found`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
el.scrollIntoView();
|
|
184
|
+
|
|
185
|
+
const toFunc = `to${type.charAt(0).toUpperCase() + type.slice(1)}`;
|
|
186
|
+
|
|
187
|
+
const result = await snapdom(el, options);
|
|
188
|
+
|
|
189
|
+
if (toFunc in result) {
|
|
190
|
+
return result[toFunc]();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
throw new Error(`Invalid type: ${type}`);
|
|
194
|
+
}
|
|
195
|
+
|
|
165
196
|
public postTmagicRuntimeReady() {
|
|
166
197
|
this.contentWindow = this.iframe?.contentWindow as RuntimeWindow;
|
|
167
198
|
|
package/types/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import * as _tmagic_editor0 from "@tmagic/editor";
|
|
1
|
+
import * as _$_tmagic_editor0 from "@tmagic/editor";
|
|
2
2
|
import EventEmitter$1, { EventEmitter } from "events";
|
|
3
|
+
import { SnapdomOptions } from "@zumer/snapdom";
|
|
3
4
|
import { MoveableManagerInterface, MoveableOptions, OnDrag, OnDragGroup, OnDragGroupStart, OnDragStart, OnResize, OnResizeGroup, OnResizeGroupStart, OnResizeStart, OnRotate, OnRotateStart, OnScale, OnScaleStart, Renderer } from "moveable";
|
|
4
5
|
import Core, { Id, MApp, MContainer, MNode } from "@tmagic/core";
|
|
5
6
|
import Guides, { GuidesOptions, GuidesOptions as GuidesOptions$1 } from "@scena/guides";
|
|
@@ -468,6 +469,12 @@ declare class ActionManager extends EventEmitter$1 {
|
|
|
468
469
|
* @returns 鼠标下方第一个可选中元素
|
|
469
470
|
*/
|
|
470
471
|
getElementFromPoint(event: MouseEvent): Promise<HTMLElement | null>;
|
|
472
|
+
/**
|
|
473
|
+
* 获取鼠标下方第二个可选中元素(跳过最上层),用于双击穿透选中下方元素
|
|
474
|
+
* @param event 鼠标事件
|
|
475
|
+
* @returns 鼠标下方第二个可选中元素,不存在时返回 null
|
|
476
|
+
*/
|
|
477
|
+
getNextElementFromPoint(event: MouseEvent): Promise<HTMLElement | null>;
|
|
471
478
|
/**
|
|
472
479
|
* 判断一个元素能否在当前场景被选中
|
|
473
480
|
* @param el 被判断的元素
|
|
@@ -711,6 +718,13 @@ declare class StageRender extends EventEmitter {
|
|
|
711
718
|
*/
|
|
712
719
|
getElementsFromPoint(point: Point): HTMLElement[];
|
|
713
720
|
getTargetElement(id: Id): HTMLElement | null;
|
|
721
|
+
/**
|
|
722
|
+
* 将指定id的dom元素生成为图片
|
|
723
|
+
* @param id 目标元素的id
|
|
724
|
+
* @param options 图片生成选项
|
|
725
|
+
* @returns data URL 格式的图片数据
|
|
726
|
+
*/
|
|
727
|
+
getElementImage(id: Id, type?: 'download' | 'raw' | 'svg' | 'canvas' | 'png' | 'jpeg' | 'webp' | 'blob', options?: SnapdomOptions): Promise<any>;
|
|
714
728
|
postTmagicRuntimeReady(): void;
|
|
715
729
|
reloadIframe(url: string): void;
|
|
716
730
|
destroyIframe(): void;
|
|
@@ -797,10 +811,14 @@ declare class StageCore extends EventEmitter {
|
|
|
797
811
|
*/
|
|
798
812
|
delayedMarkContainer(event: MouseEvent, excludeElList?: Element[]): NodeJS.Timeout | undefined;
|
|
799
813
|
getMoveableOption<K extends keyof MoveableOptions>(key: K): MoveableOptions[K] | undefined;
|
|
800
|
-
getDragStatus(): _tmagic_editor0.StageDragStatus | undefined;
|
|
814
|
+
getDragStatus(): _$_tmagic_editor0.StageDragStatus | undefined;
|
|
801
815
|
disableMultiSelect(): void;
|
|
802
816
|
enableMultiSelect(): void;
|
|
803
817
|
reloadIframe(url: string): void;
|
|
818
|
+
/**
|
|
819
|
+
* 将指定id的dom元素生成为图片
|
|
820
|
+
*/
|
|
821
|
+
getElementImage(id: Id, type?: 'download' | 'raw' | 'svg' | 'canvas' | 'png' | 'jpeg' | 'webp' | 'blob', options?: SnapdomOptions): Promise<any>;
|
|
804
822
|
/**
|
|
805
823
|
* 销毁实例
|
|
806
824
|
*/
|