import './index.css'; import type { ThemeConfig } from '../../themes/types'; import { IBimComponent } from '../../types/component'; import { localeManager, t } from '../../services/locale'; import { themeManager } from '../../services/theme'; import type { SectionPlanePanelOptions } from './types'; /** * 拾取面剖切面板组件 * 包含三个操作按钮:隐藏、反向、重置 */ export class SectionPlanePanel implements IBimComponent { public element: HTMLElement; private options: SectionPlanePanelOptions; // DOM 引用 private hideBtn!: HTMLButtonElement; private reverseBtn!: HTMLButtonElement; private resetBtn!: HTMLButtonElement; private hideLabelEl!: HTMLElement; private reverseLabelEl!: HTMLElement; private resetLabelEl!: HTMLElement; // 订阅清理 private unsubscribeLocale: (() => void) | null = null; private unsubscribeTheme: (() => void) | null = null; constructor(options: SectionPlanePanelOptions = {}) { this.options = options; this.element = this.createDom(); } /** * 初始化组件 */ public init(): void { // 订阅语言变更 this.unsubscribeLocale = localeManager.subscribe(() => { this.setLocales(); }); // 订阅主题变更 this.unsubscribeTheme = themeManager.subscribe((theme) => { this.setTheme(theme); }); // 初始应用 this.setLocales(); this.setTheme(themeManager.getTheme()); } /** * 设置主题 */ public setTheme(theme: ThemeConfig): void { const style = this.element.style; style.setProperty('--bim-section-btn-bg', theme.componentBackground ?? 'rgba(255, 255, 255, 0.06)'); style.setProperty('--bim-section-btn-hover', theme.componentHover ?? 'rgba(255, 255, 255, 0.10)'); style.setProperty('--bim-section-btn-active', theme.componentActive ?? 'rgba(255, 255, 255, 0.14)'); style.setProperty('--bim-primary-color', theme.primary ?? '#1890ff'); style.setProperty('--bim-icon-color', theme.icon ?? '#ccc'); style.setProperty('--bim-text-color', theme.textSecondary ?? 'rgba(255, 255, 255, 0.90)'); style.setProperty('--bim-text-active-color', theme.textPrimary ?? '#fff'); } /** * 设置语言 */ public setLocales(): void { this.hideLabelEl.textContent = t('sectionPlane.actions.hide'); this.reverseLabelEl.textContent = t('sectionPlane.actions.reverse'); this.resetLabelEl.textContent = t('sectionPlane.actions.reset'); this.hideBtn.title = t('sectionPlane.actions.hide'); this.reverseBtn.title = t('sectionPlane.actions.reverse'); this.resetBtn.title = t('sectionPlane.actions.reset'); } /** * 销毁组件 */ public destroy(): void { if (this.unsubscribeLocale) { this.unsubscribeLocale(); this.unsubscribeLocale = null; } if (this.unsubscribeTheme) { this.unsubscribeTheme(); this.unsubscribeTheme = null; } this.element.remove(); } /** * 创建 DOM */ private createDom(): HTMLElement { const root = document.createElement('div'); root.className = 'section-plane-panel'; // 隐藏按钮 this.hideBtn = this.createButton( 'hide', '', () => { if (this.options.onHide) { this.options.onHide(); } } ); // 反向按钮 this.reverseBtn = this.createButton( 'reverse', '', () => { if (this.options.onReverse) { this.options.onReverse(); } } ); // 重置按钮 this.resetBtn = this.createButton( 'reset', '', () => { if (this.options.onReset) { this.options.onReset(); } } ); root.appendChild(this.hideBtn); root.appendChild(this.reverseBtn); root.appendChild(this.resetBtn); return root; } /** * 创建按钮 */ private createButton(type: 'hide' | 'reverse' | 'reset', iconSvg: string, onClick: () => void): HTMLButtonElement { const btn = document.createElement('button'); btn.type = 'button'; btn.className = 'section-plane-btn'; // 图标 const icon = document.createElement('div'); icon.className = 'section-plane-btn-icon'; icon.innerHTML = iconSvg; btn.appendChild(icon); // 标签 const label = document.createElement('div'); label.className = 'section-plane-btn-label'; btn.appendChild(label); // 保存 label 引用 if (type === 'hide') { this.hideLabelEl = label; } else if (type === 'reverse') { this.reverseLabelEl = label; } else { this.resetLabelEl = label; } // 点击事件 btn.addEventListener('click', onClick); return btn; } }