@tmagic/stage 1.8.0-beta.2 → 1.8.0-beta.3

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.
@@ -1,5 +1,6 @@
1
1
  import "./const.js";
2
2
  import ActionManager from "./ActionManager.js";
3
+ import StageFlashHighlight from "./StageFlashHighlight.js";
3
4
  import StageMask from "./StageMask.js";
4
5
  import StageRender from "./StageRender.js";
5
6
  import { EventEmitter } from "events";
@@ -13,13 +14,17 @@ var StageCore = class extends EventEmitter {
13
14
  renderer = null;
14
15
  mask = null;
15
16
  actionManager = null;
17
+ flashHighlight = null;
16
18
  pageResizeObserver = null;
17
19
  autoScrollIntoView;
18
20
  customizedRender;
21
+ /** 非点击画布选中组件时,是否对选中区域做高亮闪烁提示,默认开启 */
22
+ disabledFlashTip;
19
23
  constructor(config) {
20
24
  super();
21
25
  this.autoScrollIntoView = config.autoScrollIntoView;
22
26
  this.customizedRender = config.render;
27
+ this.disabledFlashTip = config.disabledFlashTip ?? false;
23
28
  this.renderer = new StageRender({
24
29
  runtimeUrl: config.runtimeUrl,
25
30
  zoom: config.zoom,
@@ -34,6 +39,7 @@ var StageCore = class extends EventEmitter {
34
39
  disabledRule: config.disabledRule
35
40
  });
36
41
  this.actionManager = new ActionManager(this.getActionManagerConfig(config));
42
+ this.flashHighlight = new StageFlashHighlight({ container: this.mask.content });
37
43
  this.initRenderEvent();
38
44
  this.initActionEvent();
39
45
  this.initMaskEvent();
@@ -42,7 +48,7 @@ var StageCore = class extends EventEmitter {
42
48
  * 单选选中元素
43
49
  * @param id 选中的id
44
50
  */
45
- async select(id, event) {
51
+ async select(id, event, options = {}) {
46
52
  if (!this.renderer) return;
47
53
  let el = this.renderer.getTargetElement(id) || null;
48
54
  if (!el) el = await new Promise((resolve) => {
@@ -73,6 +79,8 @@ var StageCore = class extends EventEmitter {
73
79
  if (el) this.mask?.setLayout(el);
74
80
  this.actionManager?.select(el, event);
75
81
  if (el && (this.autoScrollIntoView || el.dataset.autoScrollIntoView)) this.mask?.observerIntersection(el);
82
+ const isPage = el === this.mask?.page || el?.className.includes("magic-ui-page");
83
+ if (el && !event && options.flash !== false && !this.disabledFlashTip && !isPage) this.flashHighlight?.flash(el);
76
84
  }
77
85
  /**
78
86
  * 多选选中多个元素
@@ -198,16 +206,18 @@ var StageCore = class extends EventEmitter {
198
206
  * 销毁实例
199
207
  */
200
208
  destroy() {
201
- const { mask, renderer, actionManager, pageResizeObserver } = this;
209
+ const { mask, renderer, actionManager, flashHighlight, pageResizeObserver } = this;
202
210
  renderer?.destroy();
203
211
  mask?.destroy();
204
212
  actionManager?.destroy();
213
+ flashHighlight?.destroy();
205
214
  pageResizeObserver?.disconnect();
206
215
  this.removeAllListeners();
207
216
  this.container = void 0;
208
217
  this.renderer = null;
209
218
  this.mask = null;
210
219
  this.actionManager = null;
220
+ this.flashHighlight = null;
211
221
  this.pageResizeObserver = null;
212
222
  }
213
223
  on(eventName, listener) {
@@ -0,0 +1,110 @@
1
+ import { ZIndex } from "./const.js";
2
+ import { getOffset } from "./util.js";
3
+ import { getDocument, injectStyle } from "@tmagic/core";
4
+ //#region packages/stage/src/StageFlashHighlight.ts
5
+ /** 闪烁提示节点的 class name */
6
+ var FLASH_TIP_CLASS_NAME = "tmagic-stage-flash-tip";
7
+ /** 闪烁动画名称 */
8
+ var FLASH_ANIMATION_NAME = "tmagic-stage-flash";
9
+ /** 闪烁动画时长(ms) */
10
+ var FLASH_DURATION = 1500;
11
+ /**
12
+ * 选中区域闪烁提示
13
+ * @description 当组件不是通过点击画布选中(如从图层树、面包屑等外部选中)时,在画布上对选中区域做一次高亮闪烁,
14
+ * 帮助用户快速定位组件在画布中的位置。
15
+ */
16
+ var StageFlashHighlight = class {
17
+ /** 闪烁节点挂载的容器(蒙层的content) */
18
+ container;
19
+ el;
20
+ timer;
21
+ styleEl;
22
+ constructor(config) {
23
+ this.container = config.container;
24
+ }
25
+ /**
26
+ * 在目标元素所在区域做一次高亮闪烁
27
+ * @param el 选中组件的Dom节点元素
28
+ */
29
+ flash(el) {
30
+ if (!el) return;
31
+ this.injectStyle();
32
+ this.clear();
33
+ const offset = getOffset(el);
34
+ const { transform } = getComputedStyle(el);
35
+ const flashEl = globalThis.document.createElement("div");
36
+ flashEl.className = FLASH_TIP_CLASS_NAME;
37
+ flashEl.style.cssText = `
38
+ position: absolute;
39
+ box-sizing: border-box;
40
+ pointer-events: none;
41
+ transform: ${transform};
42
+ left: ${offset.left}px;
43
+ top: ${offset.top}px;
44
+ width: ${el.clientWidth}px;
45
+ height: ${el.clientHeight}px;
46
+ z-index: ${ZIndex.SELECTED_EL};
47
+ `;
48
+ this.container.appendChild(flashEl);
49
+ this.el = flashEl;
50
+ this.timer = globalThis.setTimeout(() => {
51
+ this.clear();
52
+ }, FLASH_DURATION);
53
+ }
54
+ /**
55
+ * 清除闪烁节点
56
+ */
57
+ clear() {
58
+ if (this.timer) {
59
+ globalThis.clearTimeout(this.timer);
60
+ this.timer = void 0;
61
+ }
62
+ this.el?.remove();
63
+ this.el = void 0;
64
+ }
65
+ /**
66
+ * 销毁实例
67
+ */
68
+ destroy() {
69
+ this.clear();
70
+ this.styleEl?.remove();
71
+ this.styleEl = void 0;
72
+ }
73
+ /**
74
+ * 注入闪烁动画样式(仅注入一次)
75
+ */
76
+ injectStyle() {
77
+ if (this.styleEl) return;
78
+ this.styleEl = injectStyle(getDocument(), `
79
+ @keyframes ${FLASH_ANIMATION_NAME} {
80
+ 0% {
81
+ opacity: 0;
82
+ background-color: rgba(146, 84, 222, 0);
83
+ }
84
+ 20% {
85
+ opacity: 1;
86
+ background-color: rgba(146, 84, 222, 0.7);
87
+ }
88
+ 45% {
89
+ opacity: 0.6;
90
+ background-color: rgba(146, 84, 222, 0.4);
91
+ }
92
+ 70% {
93
+ opacity: 1;
94
+ background-color: rgba(146, 84, 222, 0.7);
95
+ }
96
+ 100% {
97
+ opacity: 0;
98
+ background-color: rgba(146, 84, 222, 0);
99
+ }
100
+ }
101
+ .${FLASH_TIP_CLASS_NAME} {
102
+ border: 2px solid #9254de;
103
+ border-radius: 2px;
104
+ animation: ${FLASH_ANIMATION_NAME} ${FLASH_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1) both;
105
+ }
106
+ `);
107
+ }
108
+ };
109
+ //#endregion
110
+ export { StageFlashHighlight as default };
@@ -3993,6 +3993,112 @@
3993
3993
  };
3994
3994
  };
3995
3995
  //#endregion
3996
+ //#region packages/stage/src/StageFlashHighlight.ts
3997
+ /** 闪烁提示节点的 class name */
3998
+ var FLASH_TIP_CLASS_NAME = "tmagic-stage-flash-tip";
3999
+ /** 闪烁动画名称 */
4000
+ var FLASH_ANIMATION_NAME = "tmagic-stage-flash";
4001
+ /** 闪烁动画时长(ms) */
4002
+ var FLASH_DURATION = 1500;
4003
+ /**
4004
+ * 选中区域闪烁提示
4005
+ * @description 当组件不是通过点击画布选中(如从图层树、面包屑等外部选中)时,在画布上对选中区域做一次高亮闪烁,
4006
+ * 帮助用户快速定位组件在画布中的位置。
4007
+ */
4008
+ var StageFlashHighlight = class {
4009
+ /** 闪烁节点挂载的容器(蒙层的content) */
4010
+ container;
4011
+ el;
4012
+ timer;
4013
+ styleEl;
4014
+ constructor(config) {
4015
+ this.container = config.container;
4016
+ }
4017
+ /**
4018
+ * 在目标元素所在区域做一次高亮闪烁
4019
+ * @param el 选中组件的Dom节点元素
4020
+ */
4021
+ flash(el) {
4022
+ if (!el) return;
4023
+ this.injectStyle();
4024
+ this.clear();
4025
+ const offset = getOffset(el);
4026
+ const { transform } = getComputedStyle(el);
4027
+ const flashEl = globalThis.document.createElement("div");
4028
+ flashEl.className = FLASH_TIP_CLASS_NAME;
4029
+ flashEl.style.cssText = `
4030
+ position: absolute;
4031
+ box-sizing: border-box;
4032
+ pointer-events: none;
4033
+ transform: ${transform};
4034
+ left: ${offset.left}px;
4035
+ top: ${offset.top}px;
4036
+ width: ${el.clientWidth}px;
4037
+ height: ${el.clientHeight}px;
4038
+ z-index: ${ZIndex.SELECTED_EL};
4039
+ `;
4040
+ this.container.appendChild(flashEl);
4041
+ this.el = flashEl;
4042
+ this.timer = globalThis.setTimeout(() => {
4043
+ this.clear();
4044
+ }, FLASH_DURATION);
4045
+ }
4046
+ /**
4047
+ * 清除闪烁节点
4048
+ */
4049
+ clear() {
4050
+ if (this.timer) {
4051
+ globalThis.clearTimeout(this.timer);
4052
+ this.timer = void 0;
4053
+ }
4054
+ this.el?.remove();
4055
+ this.el = void 0;
4056
+ }
4057
+ /**
4058
+ * 销毁实例
4059
+ */
4060
+ destroy() {
4061
+ this.clear();
4062
+ this.styleEl?.remove();
4063
+ this.styleEl = void 0;
4064
+ }
4065
+ /**
4066
+ * 注入闪烁动画样式(仅注入一次)
4067
+ */
4068
+ injectStyle() {
4069
+ if (this.styleEl) return;
4070
+ this.styleEl = (0, _tmagic_core.injectStyle)((0, _tmagic_core.getDocument)(), `
4071
+ @keyframes ${FLASH_ANIMATION_NAME} {
4072
+ 0% {
4073
+ opacity: 0;
4074
+ background-color: rgba(146, 84, 222, 0);
4075
+ }
4076
+ 20% {
4077
+ opacity: 1;
4078
+ background-color: rgba(146, 84, 222, 0.7);
4079
+ }
4080
+ 45% {
4081
+ opacity: 0.6;
4082
+ background-color: rgba(146, 84, 222, 0.4);
4083
+ }
4084
+ 70% {
4085
+ opacity: 1;
4086
+ background-color: rgba(146, 84, 222, 0.7);
4087
+ }
4088
+ 100% {
4089
+ opacity: 0;
4090
+ background-color: rgba(146, 84, 222, 0);
4091
+ }
4092
+ }
4093
+ .${FLASH_TIP_CLASS_NAME} {
4094
+ border: 2px solid #9254de;
4095
+ border-radius: 2px;
4096
+ animation: ${FLASH_ANIMATION_NAME} ${FLASH_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1) both;
4097
+ }
4098
+ `);
4099
+ }
4100
+ };
4101
+ //#endregion
3996
4102
  //#region packages/stage/src/Rule.ts
3997
4103
  var guidesClass = "tmagic-stage-guides";
3998
4104
  var Rule = class extends events.default {
@@ -4586,13 +4692,17 @@
4586
4692
  renderer = null;
4587
4693
  mask = null;
4588
4694
  actionManager = null;
4695
+ flashHighlight = null;
4589
4696
  pageResizeObserver = null;
4590
4697
  autoScrollIntoView;
4591
4698
  customizedRender;
4699
+ /** 非点击画布选中组件时,是否对选中区域做高亮闪烁提示,默认开启 */
4700
+ disabledFlashTip;
4592
4701
  constructor(config) {
4593
4702
  super();
4594
4703
  this.autoScrollIntoView = config.autoScrollIntoView;
4595
4704
  this.customizedRender = config.render;
4705
+ this.disabledFlashTip = config.disabledFlashTip ?? false;
4596
4706
  this.renderer = new StageRender({
4597
4707
  runtimeUrl: config.runtimeUrl,
4598
4708
  zoom: config.zoom,
@@ -4607,6 +4717,7 @@
4607
4717
  disabledRule: config.disabledRule
4608
4718
  });
4609
4719
  this.actionManager = new ActionManager(this.getActionManagerConfig(config));
4720
+ this.flashHighlight = new StageFlashHighlight({ container: this.mask.content });
4610
4721
  this.initRenderEvent();
4611
4722
  this.initActionEvent();
4612
4723
  this.initMaskEvent();
@@ -4615,7 +4726,7 @@
4615
4726
  * 单选选中元素
4616
4727
  * @param id 选中的id
4617
4728
  */
4618
- async select(id, event) {
4729
+ async select(id, event, options = {}) {
4619
4730
  if (!this.renderer) return;
4620
4731
  let el = this.renderer.getTargetElement(id) || null;
4621
4732
  if (!el) el = await new Promise((resolve) => {
@@ -4646,6 +4757,8 @@
4646
4757
  if (el) this.mask?.setLayout(el);
4647
4758
  this.actionManager?.select(el, event);
4648
4759
  if (el && (this.autoScrollIntoView || el.dataset.autoScrollIntoView)) this.mask?.observerIntersection(el);
4760
+ const isPage = el === this.mask?.page || el?.className.includes("magic-ui-page");
4761
+ if (el && !event && options.flash !== false && !this.disabledFlashTip && !isPage) this.flashHighlight?.flash(el);
4649
4762
  }
4650
4763
  /**
4651
4764
  * 多选选中多个元素
@@ -4771,16 +4884,18 @@
4771
4884
  * 销毁实例
4772
4885
  */
4773
4886
  destroy() {
4774
- const { mask, renderer, actionManager, pageResizeObserver } = this;
4887
+ const { mask, renderer, actionManager, flashHighlight, pageResizeObserver } = this;
4775
4888
  renderer?.destroy();
4776
4889
  mask?.destroy();
4777
4890
  actionManager?.destroy();
4891
+ flashHighlight?.destroy();
4778
4892
  pageResizeObserver?.disconnect();
4779
4893
  this.removeAllListeners();
4780
4894
  this.container = void 0;
4781
4895
  this.renderer = null;
4782
4896
  this.mask = null;
4783
4897
  this.actionManager = null;
4898
+ this.flashHighlight = null;
4784
4899
  this.pageResizeObserver = null;
4785
4900
  }
4786
4901
  on(eventName, listener) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.8.0-beta.2",
2
+ "version": "1.8.0-beta.3",
3
3
  "name": "@tmagic/stage",
4
4
  "type": "module",
5
5
  "sideEffects": false,
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "peerDependencies": {
46
46
  "typescript": "^6.0.3",
47
- "@tmagic/core": "1.8.0-beta.2"
47
+ "@tmagic/core": "1.8.0-beta.3"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "typescript": {
package/src/StageCore.ts CHANGED
@@ -25,7 +25,8 @@ import type { Id } from '@tmagic/core';
25
25
  import { getIdFromEl } from '@tmagic/core';
26
26
 
27
27
  import ActionManager from './ActionManager';
28
- import { DEFAULT_ZOOM } from './const';
28
+ import { DEFAULT_ZOOM, PAGE_CLASS } from './const';
29
+ import StageFlashHighlight from './StageFlashHighlight';
29
30
  import StageMask from './StageMask';
30
31
  import StageRender from './StageRender';
31
32
  import type {
@@ -51,16 +52,20 @@ export default class StageCore extends EventEmitter {
51
52
  public renderer: StageRender | null = null;
52
53
  public mask: StageMask | null = null;
53
54
  public actionManager: ActionManager | null = null;
55
+ public flashHighlight: StageFlashHighlight | null = null;
54
56
 
55
57
  private pageResizeObserver: ResizeObserver | null = null;
56
58
  private autoScrollIntoView: boolean | undefined;
57
59
  private customizedRender?: CustomizeRender;
60
+ /** 非点击画布选中组件时,是否对选中区域做高亮闪烁提示,默认开启 */
61
+ private disabledFlashTip: boolean;
58
62
 
59
63
  constructor(config: StageCoreConfig) {
60
64
  super();
61
65
 
62
66
  this.autoScrollIntoView = config.autoScrollIntoView;
63
67
  this.customizedRender = config.render;
68
+ this.disabledFlashTip = config.disabledFlashTip ?? false;
64
69
 
65
70
  this.renderer = new StageRender({
66
71
  runtimeUrl: config.runtimeUrl,
@@ -78,6 +83,7 @@ export default class StageCore extends EventEmitter {
78
83
  disabledRule: config.disabledRule,
79
84
  });
80
85
  this.actionManager = new ActionManager(this.getActionManagerConfig(config));
86
+ this.flashHighlight = new StageFlashHighlight({ container: this.mask.content });
81
87
 
82
88
  this.initRenderEvent();
83
89
  this.initActionEvent();
@@ -88,7 +94,7 @@ export default class StageCore extends EventEmitter {
88
94
  * 单选选中元素
89
95
  * @param id 选中的id
90
96
  */
91
- public async select(id: Id, event?: MouseEvent): Promise<void> {
97
+ public async select(id: Id, event?: MouseEvent, options: { flash?: boolean } = {}): Promise<void> {
92
98
  if (!this.renderer) {
93
99
  return;
94
100
  }
@@ -133,6 +139,13 @@ export default class StageCore extends EventEmitter {
133
139
  if (el && (this.autoScrollIntoView || el.dataset.autoScrollIntoView)) {
134
140
  this.mask?.observerIntersection(el);
135
141
  }
142
+
143
+ // 非点击画布选中(如从图层树、面包屑等外部选中,此时没有鼠标事件)时,对选中区域做一次高亮闪烁,帮助用户定位组件
144
+ // 选中页面(mask.page 或带有 magic-ui-page class 的节点)时不做闪烁提示
145
+ const isPage = el === this.mask?.page || el?.className.includes(PAGE_CLASS);
146
+ if (el && !event && options.flash !== false && !this.disabledFlashTip && !isPage) {
147
+ this.flashHighlight?.flash(el);
148
+ }
136
149
  }
137
150
 
138
151
  /**
@@ -300,11 +313,12 @@ export default class StageCore extends EventEmitter {
300
313
  * 销毁实例
301
314
  */
302
315
  public destroy(): void {
303
- const { mask, renderer, actionManager, pageResizeObserver } = this;
316
+ const { mask, renderer, actionManager, flashHighlight, pageResizeObserver } = this;
304
317
 
305
318
  renderer?.destroy();
306
319
  mask?.destroy();
307
320
  actionManager?.destroy();
321
+ flashHighlight?.destroy();
308
322
  pageResizeObserver?.disconnect();
309
323
 
310
324
  this.removeAllListeners();
@@ -313,6 +327,7 @@ export default class StageCore extends EventEmitter {
313
327
  this.renderer = null;
314
328
  this.mask = null;
315
329
  this.actionManager = null;
330
+ this.flashHighlight = null;
316
331
  this.pageResizeObserver = null;
317
332
  }
318
333
 
@@ -0,0 +1,142 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making TMagicEditor available.
3
+ *
4
+ * Copyright (C) 2025 Tencent. All rights reserved.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import { getDocument, injectStyle } from '@tmagic/core';
20
+
21
+ import { ZIndex } from './const';
22
+ import { getOffset } from './util';
23
+
24
+ /** 闪烁提示节点的 class name */
25
+ export const FLASH_TIP_CLASS_NAME = 'tmagic-stage-flash-tip';
26
+ /** 闪烁动画名称 */
27
+ const FLASH_ANIMATION_NAME = 'tmagic-stage-flash';
28
+ /** 闪烁动画时长(ms) */
29
+ const FLASH_DURATION = 1500;
30
+
31
+ /**
32
+ * 选中区域闪烁提示
33
+ * @description 当组件不是通过点击画布选中(如从图层树、面包屑等外部选中)时,在画布上对选中区域做一次高亮闪烁,
34
+ * 帮助用户快速定位组件在画布中的位置。
35
+ */
36
+ export default class StageFlashHighlight {
37
+ /** 闪烁节点挂载的容器(蒙层的content) */
38
+ private container: HTMLElement;
39
+ private el?: HTMLElement;
40
+ private timer?: NodeJS.Timeout;
41
+ private styleEl?: HTMLStyleElement;
42
+
43
+ constructor(config: { container: HTMLElement }) {
44
+ this.container = config.container;
45
+ }
46
+
47
+ /**
48
+ * 在目标元素所在区域做一次高亮闪烁
49
+ * @param el 选中组件的Dom节点元素
50
+ */
51
+ public flash(el: HTMLElement): void {
52
+ if (!el) return;
53
+
54
+ this.injectStyle();
55
+ this.clear();
56
+
57
+ const offset = getOffset(el);
58
+ const { transform } = getComputedStyle(el);
59
+
60
+ const flashEl = globalThis.document.createElement('div');
61
+ flashEl.className = FLASH_TIP_CLASS_NAME;
62
+ flashEl.style.cssText = `
63
+ position: absolute;
64
+ box-sizing: border-box;
65
+ pointer-events: none;
66
+ transform: ${transform};
67
+ left: ${offset.left}px;
68
+ top: ${offset.top}px;
69
+ width: ${el.clientWidth}px;
70
+ height: ${el.clientHeight}px;
71
+ z-index: ${ZIndex.SELECTED_EL};
72
+ `;
73
+
74
+ this.container.appendChild(flashEl);
75
+ this.el = flashEl;
76
+
77
+ this.timer = globalThis.setTimeout(() => {
78
+ this.clear();
79
+ }, FLASH_DURATION);
80
+ }
81
+
82
+ /**
83
+ * 清除闪烁节点
84
+ */
85
+ public clear(): void {
86
+ if (this.timer) {
87
+ globalThis.clearTimeout(this.timer);
88
+ this.timer = undefined;
89
+ }
90
+ this.el?.remove();
91
+ this.el = undefined;
92
+ }
93
+
94
+ /**
95
+ * 销毁实例
96
+ */
97
+ public destroy(): void {
98
+ this.clear();
99
+ this.styleEl?.remove();
100
+ this.styleEl = undefined;
101
+ }
102
+
103
+ /**
104
+ * 注入闪烁动画样式(仅注入一次)
105
+ */
106
+ private injectStyle(): void {
107
+ if (this.styleEl) return;
108
+
109
+ this.styleEl = injectStyle(
110
+ getDocument(),
111
+ `
112
+ @keyframes ${FLASH_ANIMATION_NAME} {
113
+ 0% {
114
+ opacity: 0;
115
+ background-color: rgba(146, 84, 222, 0);
116
+ }
117
+ 20% {
118
+ opacity: 1;
119
+ background-color: rgba(146, 84, 222, 0.7);
120
+ }
121
+ 45% {
122
+ opacity: 0.6;
123
+ background-color: rgba(146, 84, 222, 0.4);
124
+ }
125
+ 70% {
126
+ opacity: 1;
127
+ background-color: rgba(146, 84, 222, 0.7);
128
+ }
129
+ 100% {
130
+ opacity: 0;
131
+ background-color: rgba(146, 84, 222, 0);
132
+ }
133
+ }
134
+ .${FLASH_TIP_CLASS_NAME} {
135
+ border: 2px solid #9254de;
136
+ border-radius: 2px;
137
+ animation: ${FLASH_ANIMATION_NAME} ${FLASH_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1) both;
138
+ }
139
+ `,
140
+ );
141
+ }
142
+ }
package/src/types.ts CHANGED
@@ -90,6 +90,11 @@ export interface StageCoreConfig {
90
90
  */
91
91
  alwaysMultiSelect?: boolean;
92
92
  disabledRule?: boolean;
93
+ /**
94
+ * 是否禁用「非点击画布选中组件时,对选中区域做高亮闪烁提示」,默认 false(即默认开启闪烁提示)。
95
+ * 用于从图层树、面包屑等外部选中组件时,帮助用户快速定位组件在画布中的位置。
96
+ */
97
+ disabledFlashTip?: boolean;
93
98
  }
94
99
 
95
100
  export interface ActionManagerConfig {
package/types/index.d.ts CHANGED
@@ -215,6 +215,11 @@ interface StageCoreConfig {
215
215
  */
216
216
  alwaysMultiSelect?: boolean;
217
217
  disabledRule?: boolean;
218
+ /**
219
+ * 是否禁用「非点击画布选中组件时,对选中区域做高亮闪烁提示」,默认 false(即默认开启闪烁提示)。
220
+ * 用于从图层树、面包屑等外部选中组件时,帮助用户快速定位组件在画布中的位置。
221
+ */
222
+ disabledFlashTip?: boolean;
218
223
  }
219
224
  interface ActionManagerConfig {
220
225
  container: HTMLElement;
@@ -591,6 +596,40 @@ declare class ActionManager extends EventEmitter$1 {
591
596
  private dblclickHandler;
592
597
  }
593
598
  //#endregion
599
+ //#region temp/packages/stage/src/StageFlashHighlight.d.ts
600
+ /**
601
+ * 选中区域闪烁提示
602
+ * @description 当组件不是通过点击画布选中(如从图层树、面包屑等外部选中)时,在画布上对选中区域做一次高亮闪烁,
603
+ * 帮助用户快速定位组件在画布中的位置。
604
+ */
605
+ declare class StageFlashHighlight {
606
+ /** 闪烁节点挂载的容器(蒙层的content) */
607
+ private container;
608
+ private el?;
609
+ private timer?;
610
+ private styleEl?;
611
+ constructor(config: {
612
+ container: HTMLElement;
613
+ });
614
+ /**
615
+ * 在目标元素所在区域做一次高亮闪烁
616
+ * @param el 选中组件的Dom节点元素
617
+ */
618
+ flash(el: HTMLElement): void;
619
+ /**
620
+ * 清除闪烁节点
621
+ */
622
+ clear(): void;
623
+ /**
624
+ * 销毁实例
625
+ */
626
+ destroy(): void;
627
+ /**
628
+ * 注入闪烁动画样式(仅注入一次)
629
+ */
630
+ private injectStyle;
631
+ }
632
+ //#endregion
594
633
  //#region temp/packages/stage/src/Rule.d.ts
595
634
  declare class Rule extends EventEmitter$1 {
596
635
  hGuides?: Guides;
@@ -790,15 +829,20 @@ declare class StageCore extends EventEmitter {
790
829
  renderer: StageRender | null;
791
830
  mask: StageMask | null;
792
831
  actionManager: ActionManager | null;
832
+ flashHighlight: StageFlashHighlight | null;
793
833
  private pageResizeObserver;
794
834
  private autoScrollIntoView;
795
835
  private customizedRender?;
836
+ /** 非点击画布选中组件时,是否对选中区域做高亮闪烁提示,默认开启 */
837
+ private disabledFlashTip;
796
838
  constructor(config: StageCoreConfig);
797
839
  /**
798
840
  * 单选选中元素
799
841
  * @param id 选中的id
800
842
  */
801
- select(id: Id, event?: MouseEvent): Promise<void>;
843
+ select(id: Id, event?: MouseEvent, options?: {
844
+ flash?: boolean;
845
+ }): Promise<void>;
802
846
  /**
803
847
  * 多选选中多个元素
804
848
  * @param ids 选中元素的id列表