feat(registry): 注册 ComponentDetailManager 到全局 Registry 和 BimEngine

This commit is contained in:
yuding
2026-01-28 12:00:55 +08:00
parent 33f1c72791
commit 89789e003b
87 changed files with 37063 additions and 24064 deletions

View File

@@ -786,6 +786,21 @@ export class BimButtonGroup implements IBimComponent {
public setBackgroundColor(color: string): void { this.setColors({ backgroundColor: color }); }
private isVisible(id: string): boolean { return this.options.visibility?.[id] !== false; }
public setType(type: 'default' | 'glass-pill'): void {
this.container.classList.remove('type-default', 'type-glass-pill');
this.options.type = type;
if (type && type !== 'default') {
this.container.classList.add(`type-${type}`);
}
this.render();
}
public getType(): 'default' | 'glass-pill' {
return this.options.type || 'default';
}
public destroy(): void {
if (this.unsubscribeLocale) {
this.unsubscribeLocale();

View File

@@ -12,7 +12,7 @@ export const createZoomBoxButton = (): ButtonConfig => {
icon: getIcon('框选放大'),
onClick: () => {
const registry = ManagerRegistry.getInstance();
registry.engine3d?.getEngine().rangeScale.active();
registry.engine3d?.activateZoomBox();
}
};
};

View File

@@ -274,20 +274,20 @@ export class BimDialog implements IBimComponent {
/**
* 边界夹紧:保持当前 left/top 不变的前提下,确保弹窗不超出容器
* 说明:用于 fitHeight / fitWidth 后的尺寸变化场景,避免弹窗被裁切。
* 说明:用于 fitHeight / fitWidth 后的"尺寸变化"场景,避免弹窗被裁切。
*/
private clampToContainer(): void {
const containerW = this.container.clientWidth;
const containerH = this.container.clientHeight;
const elW = this.element.offsetWidth;
const elH = this.element.offsetHeight;
const bottomOffset = this.options.bottomOffset ?? 70;
// 当前 left/top优先从 style 读取,避免 NaN
const currentLeft = this.element.offsetLeft;
const currentTop = this.element.offsetTop;
const maxLeft = Math.max(0, containerW - elW);
const maxTop = Math.max(0, containerH - elH);
const maxTop = Math.max(0, containerH - elH - bottomOffset);
const nextLeft = Math.max(0, Math.min(currentLeft, maxLeft));
const nextTop = Math.max(0, Math.min(currentTop, maxTop));
@@ -302,8 +302,8 @@ export class BimDialog implements IBimComponent {
private initPosition() {
const pos = this.options.position;
const elRect = this.element.getBoundingClientRect();
const bottomOffset = this.options.bottomOffset ?? 70;
// 计算相对父容器的定位
let left = 0;
let top = 0;
@@ -326,9 +326,9 @@ export class BimDialog implements IBimComponent {
case 'top-right': left = pW - elW; top = 0; break;
case 'left-center': left = 0; top = (pH - elH) / 2; break;
case 'right-center': left = pW - elW; top = (pH - elH) / 2; break;
case 'bottom-left': left = 0; top = pH - elH; break;
case 'bottom-center': left = (pW - elW) / 2; top = pH - elH; break;
case 'bottom-right': left = pW - elW; top = pH - elH; break;
case 'bottom-left': left = 0; top = pH - elH - bottomOffset; break;
case 'bottom-center': left = (pW - elW) / 2; top = pH - elH - bottomOffset; break;
case 'bottom-right': left = pW - elW; top = pH - elH - bottomOffset; break;
default:
left = (pW - elW) / 2;
top = (pH - elH) / 2;
@@ -336,7 +336,7 @@ export class BimDialog implements IBimComponent {
}
left = Math.max(0, Math.min(left, pW - elW));
top = Math.max(0, Math.min(top, pH - elH));
top = Math.max(0, Math.min(top, pH - elH - bottomOffset));
this.element.style.left = `${left}px`;
this.element.style.top = `${top}px`;
@@ -354,24 +354,23 @@ export class BimDialog implements IBimComponent {
let containerH = 0;
let elW = 0;
let elH = 0;
let bottomOffset = 0;
const onMouseDown = (e: MouseEvent) => {
e.preventDefault(); // 阻止默认行为(如选中文本),非常重要,防止卡顿
e.stopPropagation(); // 阻止传递给 Three.js
e.preventDefault();
e.stopPropagation();
startX = e.clientX;
startY = e.clientY;
startLeft = this.element.offsetLeft;
startTop = this.element.offsetTop;
// 缓存尺寸,减少 reflow
containerW = this.container.clientWidth;
containerH = this.container.clientHeight;
elW = this.element.offsetWidth;
elH = this.element.offsetHeight;
bottomOffset = this.options.bottomOffset ?? 70;
// 关键:使用 capture: true
// 确保即使 createDom 阻止了冒泡document 也能在捕获阶段收到事件
document.addEventListener('mousemove', onMouseMove, { capture: true });
document.addEventListener('mouseup', onMouseUp, { capture: true });
};
@@ -380,7 +379,6 @@ export class BimDialog implements IBimComponent {
e.preventDefault();
e.stopPropagation();
// 节流优化:使用 requestAnimationFrame
if (this.rafId) return;
this.rafId = requestAnimationFrame(() => {
@@ -391,7 +389,7 @@ export class BimDialog implements IBimComponent {
let newTop = startTop + dy;
const maxLeft = containerW - elW;
const maxTop = containerH - elH;
const maxTop = containerH - elH - bottomOffset;
newLeft = Math.max(0, Math.min(newLeft, maxLeft));
newTop = Math.max(0, Math.min(newTop, maxTop));

View File

@@ -50,6 +50,8 @@ export interface DialogOptions extends DialogColors {
minWidth?: number;
/** 最小高度限制 */
minHeight?: number;
/** 底部偏移量(用于避开底部工具栏),默认 70px */
bottomOffset?: number;
/** 关闭时的回调函数 */
onClose?: () => void;
/** 打开时的回调函数 */

View File

@@ -294,30 +294,7 @@
min-width: 0;
}
.bim-measure-clear-btn:hover,
.bim-measure-clear-btn:active,
.bim-measure-clear-btn:focus {
background: transparent;
border: none;
outline: none;
text-decoration: none;
}
.bim-measure-clear-btn {
background: transparent;
border: none;
color: var(--bim-measure-danger, white); /* 先用偏绿(接近截图),可由主题覆盖 */
cursor: pointer;
/* 缩小可点击区域:仅文字本身附近 */
padding: 0;
font-size: 13px;
/* 防止外部环境(如 demo给 button 设置 flex: 1 导致“各占一半” */
flex: 0 0 auto !important;
width: auto;
min-width: 0;
}
/* 你要求:删除按钮不需要 hover 效果 */
/* 删除按钮不需要 hover 效果 */
.bim-measure-clear-btn:hover,
.bim-measure-clear-btn:active,
.bim-measure-clear-btn:focus {