初始化
This commit is contained in:
60
src/components/section-plane-panel/index.css
Normal file
60
src/components/section-plane-panel/index.css
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 拾取面剖切面板样式
|
||||
*/
|
||||
|
||||
.section-plane-panel {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding: 12px 12px 16px 12px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.section-plane-btn {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
padding: 8px;
|
||||
border: 1px solid transparent;
|
||||
background: var(--bim-section-btn-bg, rgba(255, 255, 255, 0.06));
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
|
||||
min-width: 60px;
|
||||
outline: none;
|
||||
color: var(--bim-text-color, rgba(255, 255, 255, 0.90));
|
||||
}
|
||||
|
||||
.section-plane-btn:hover {
|
||||
background: var(--bim-section-btn-hover, rgba(255, 255, 255, 0.10));
|
||||
}
|
||||
|
||||
.section-plane-btn:active {
|
||||
background: var(--bim-section-btn-active, rgba(255, 255, 255, 0.14));
|
||||
border-color: var(--bim-text-active-color, #fff);
|
||||
color: var(--bim-text-active-color, #fff);
|
||||
}
|
||||
|
||||
.section-plane-btn-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--bim-icon-color, #ccc);
|
||||
}
|
||||
|
||||
.section-plane-btn-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.section-plane-btn-label {
|
||||
font-size: 12px;
|
||||
color: inherit;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
174
src/components/section-plane-panel/index.ts
Normal file
174
src/components/section-plane-panel/index.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
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',
|
||||
'<svg viewBox="0 0 24 24"><path fill="currentColor" d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/></svg>',
|
||||
() => {
|
||||
if (this.options.onHide) {
|
||||
this.options.onHide();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 反向按钮
|
||||
this.reverseBtn = this.createButton(
|
||||
'reverse',
|
||||
'<svg viewBox="0 0 24 24"><path fill="currentColor" d="M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z"/></svg>',
|
||||
() => {
|
||||
if (this.options.onReverse) {
|
||||
this.options.onReverse();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 重置按钮
|
||||
this.resetBtn = this.createButton(
|
||||
'reset',
|
||||
'<svg viewBox="0 0 24 24"><path fill="currentColor" d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>',
|
||||
() => {
|
||||
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;
|
||||
}
|
||||
}
|
||||
19
src/components/section-plane-panel/types.ts
Normal file
19
src/components/section-plane-panel/types.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 拾取面剖切面板配置选项
|
||||
*/
|
||||
export interface SectionPlanePanelOptions {
|
||||
/**
|
||||
* 隐藏按钮回调
|
||||
*/
|
||||
onHide?: () => void;
|
||||
|
||||
/**
|
||||
* 反向按钮回调
|
||||
*/
|
||||
onReverse?: () => void;
|
||||
|
||||
/**
|
||||
* 重置按钮回调
|
||||
*/
|
||||
onReset?: () => void;
|
||||
}
|
||||
Reference in New Issue
Block a user