diff --git a/packages/stage/src/StageCore.ts b/packages/stage/src/StageCore.ts index e0a3590a..de62d80a 100644 --- a/packages/stage/src/StageCore.ts +++ b/packages/stage/src/StageCore.ts @@ -83,7 +83,10 @@ export default class StageCore extends EventEmitter { disabledRule: config.disabledRule, }); this.actionManager = new ActionManager(this.getActionManagerConfig(config)); - this.flashHighlight = new StageFlashHighlight({ container: this.mask.content }); + this.flashHighlight = new StageFlashHighlight({ + container: this.mask.content, + updateDragEl: config.updateDragEl, + }); this.initRenderEvent(); this.initActionEvent(); diff --git a/packages/stage/src/StageFlashHighlight.ts b/packages/stage/src/StageFlashHighlight.ts index e7f88b37..68b19320 100644 --- a/packages/stage/src/StageFlashHighlight.ts +++ b/packages/stage/src/StageFlashHighlight.ts @@ -18,8 +18,9 @@ import { getDocument, injectStyle } from '@tmagic/core'; -import { ZIndex } from './const'; -import { getOffset } from './util'; +import { FLASH_EL_ID_PREFIX, ZIndex } from './const'; +import TargetShadow from './TargetShadow'; +import type { StageFlashHighlightConfig } from './types'; /** 闪烁提示节点的 class name */ export const FLASH_TIP_CLASS_NAME = 'tmagic-stage-flash-tip'; @@ -34,14 +35,18 @@ const FLASH_DURATION = 1500; * 帮助用户快速定位组件在画布中的位置。 */ export default class StageFlashHighlight { - /** 闪烁节点挂载的容器(蒙层的content) */ - private container: HTMLElement; - private el?: HTMLElement; + /** 复用 TargetShadow 负责节点的定位校准(updateDragEl、fixed、滚动偏移等) */ + private targetShadow: TargetShadow; private timer?: NodeJS.Timeout; private styleEl?: HTMLStyleElement; - constructor(config: { container: HTMLElement }) { - this.container = config.container; + constructor(config: StageFlashHighlightConfig) { + this.targetShadow = new TargetShadow({ + container: config.container, + updateDragEl: config.updateDragEl, + zIndex: ZIndex.SELECTED_EL, + idPrefix: FLASH_EL_ID_PREFIX, + }); } /** @@ -52,27 +57,15 @@ export default class StageFlashHighlight { if (!el) return; this.injectStyle(); + // 先销毁旧节点再 update,确保每次都拿到全新节点,让闪烁动画重新播放 this.clear(); - const offset = getOffset(el); - const { transform } = getComputedStyle(el); - - const flashEl = globalThis.document.createElement('div'); - flashEl.className = FLASH_TIP_CLASS_NAME; - flashEl.style.cssText = ` - position: absolute; - box-sizing: border-box; - pointer-events: none; - transform: ${transform}; - left: ${offset.left}px; - top: ${offset.top}px; - width: ${el.clientWidth}px; - height: ${el.clientHeight}px; - z-index: ${ZIndex.SELECTED_EL}; - `; - - this.container.appendChild(flashEl); - this.el = flashEl; + const flashEl = this.targetShadow.update(el); + flashEl.classList.add(FLASH_TIP_CLASS_NAME); + flashEl.style.boxSizing = 'border-box'; + flashEl.style.pointerEvents = 'none'; + // getTargetElStyle 会写入 target 的内联 border,需清掉以让动画 class 的边框生效 + flashEl.style.border = ''; this.timer = globalThis.setTimeout(() => { this.clear(); @@ -87,8 +80,7 @@ export default class StageFlashHighlight { globalThis.clearTimeout(this.timer); this.timer = undefined; } - this.el?.remove(); - this.el = undefined; + this.targetShadow.destroyEl(); } /** @@ -96,6 +88,7 @@ export default class StageFlashHighlight { */ public destroy(): void { this.clear(); + this.targetShadow.destroy(); this.styleEl?.remove(); this.styleEl = undefined; } diff --git a/packages/stage/src/const.ts b/packages/stage/src/const.ts index 31f64e9f..91ca4eba 100644 --- a/packages/stage/src/const.ts +++ b/packages/stage/src/const.ts @@ -25,6 +25,9 @@ export const DRAG_EL_ID_PREFIX = 'drag_el_'; /** 高亮时需要在蒙层中创建一个占位节点,该节点的id前缀 */ export const HIGHLIGHT_EL_ID_PREFIX = 'highlight_el_'; +/** 闪烁提示时需要在蒙层中创建一个占位节点,该节点的id前缀 */ +export const FLASH_EL_ID_PREFIX = 'flash_el_'; + export const CONTAINER_HIGHLIGHT_CLASS_NAME = 'tmagic-stage-container-highlight'; export const PAGE_CLASS = 'magic-ui-page'; diff --git a/packages/stage/src/types.ts b/packages/stage/src/types.ts index 61c7b9da..5c0b50e8 100644 --- a/packages/stage/src/types.ts +++ b/packages/stage/src/types.ts @@ -269,6 +269,11 @@ export interface TargetShadowConfig { idPrefix?: string; } +export interface StageFlashHighlightConfig { + container: HTMLElement; + updateDragEl?: UpdateDragEl; +} + export interface RuleOptions { guidesOptions?: Partial; disabledRule?: boolean;