初始化
This commit is contained in:
@@ -56,7 +56,7 @@
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
|
||||
color: var(--bim-btn-text-color, #ccc);
|
||||
background-color: var(--bim-btn-bg, transparent);
|
||||
padding: 6px;
|
||||
@@ -64,6 +64,8 @@
|
||||
position: relative;
|
||||
/* 为绝对定位提供锚点 */
|
||||
justify-content: center;
|
||||
border: 1px solid transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.opt-btn:hover {
|
||||
@@ -73,11 +75,10 @@
|
||||
.opt-btn.active {
|
||||
background-color: var(--bim-btn-active-bg, rgba(255, 255, 255, 0.15));
|
||||
color: var(--bim-btn-text-active-color, #fff);
|
||||
/* 开关按钮激活时不显示边框,只改变背景 */
|
||||
}
|
||||
|
||||
.opt-btn.active .opt-btn-icon {
|
||||
color: var(--bim-icon-active-color, #fff);
|
||||
}
|
||||
/* 开关按钮激活时图标颜色保持不变,继承默认颜色 */
|
||||
|
||||
.opt-btn.disabled {
|
||||
opacity: 0.5;
|
||||
@@ -246,15 +247,30 @@
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
color: var(--bim-btn-text-color, #ccc);
|
||||
transition: background 0.2s;
|
||||
transition: background 0.2s, border-color 0.2s, color 0.2s;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* 二级菜单项的图标默认颜色 */
|
||||
.opt-btn-dropdown-item .opt-btn-icon {
|
||||
color: var(--bim-icon-color, #ccc);
|
||||
}
|
||||
|
||||
.opt-btn-dropdown-item:hover {
|
||||
background-color: var(--bim-btn-hover-bg, #444);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 二级菜单项激活态(支持 keepActive 的可视化) */
|
||||
.opt-btn-dropdown-item.active {
|
||||
background-color: var(--bim-btn-active-bg, rgba(255, 255, 255, 0.15));
|
||||
color: var(--bim-btn-text-active-color, #fff);
|
||||
/* 开关按钮激活时不显示边框,只改变背景 */
|
||||
}
|
||||
|
||||
/* 开关按钮激活时图标颜色保持不变,继承默认颜色 */
|
||||
|
||||
/* 下拉菜单项 - 横向布局(图标在左,默认) */
|
||||
.opt-btn-dropdown-item.align-horizontal {
|
||||
flex-direction: row;
|
||||
|
||||
@@ -183,6 +183,32 @@ export class BimButtonGroup implements IBimComponent {
|
||||
if (this.options.iconActiveColor) style.setProperty('--bim-icon-active-color', this.options.iconActiveColor);
|
||||
if (this.options.textColor) style.setProperty('--bim-btn-text-color', this.options.textColor);
|
||||
if (this.options.textActiveColor) style.setProperty('--bim-btn-text-active-color', this.options.textActiveColor);
|
||||
|
||||
// 同步更新所有已存在的dropdown元素的CSS变量(dropdown被添加到body,无法继承容器的CSS变量)
|
||||
const dropdowns = document.querySelectorAll('.opt-btn-dropdown');
|
||||
dropdowns.forEach(dropdown => {
|
||||
const dropdownStyle = (dropdown as HTMLElement).style;
|
||||
if (this.options.iconColor) dropdownStyle.setProperty('--bim-icon-color', this.options.iconColor);
|
||||
if (this.options.iconActiveColor) dropdownStyle.setProperty('--bim-icon-active-color', this.options.iconActiveColor);
|
||||
if (this.options.textColor) dropdownStyle.setProperty('--bim-btn-text-color', this.options.textColor);
|
||||
if (this.options.textActiveColor) dropdownStyle.setProperty('--bim-btn-text-active-color', this.options.textActiveColor);
|
||||
if (this.options.btnBackgroundColor) dropdownStyle.setProperty('--bim-btn-bg', this.options.btnBackgroundColor);
|
||||
if (this.options.btnHoverColor) dropdownStyle.setProperty('--bim-btn-hover-bg', this.options.btnHoverColor);
|
||||
if (this.options.btnActiveColor) dropdownStyle.setProperty('--bim-btn-active-bg', this.options.btnActiveColor);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置主题的primary颜色(用于边框等)
|
||||
*/
|
||||
private setPrimaryColor(color: string): void {
|
||||
this.container.style.setProperty('--bim-primary-color', color);
|
||||
|
||||
// 同步更新所有dropdown(dropdown被添加到body,无法继承容器的CSS变量)
|
||||
const dropdowns = document.querySelectorAll('.opt-btn-dropdown');
|
||||
dropdowns.forEach(dropdown => {
|
||||
(dropdown as HTMLElement).style.setProperty('--bim-primary-color', color);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,6 +236,7 @@ export class BimButtonGroup implements IBimComponent {
|
||||
});
|
||||
|
||||
this.applyStyles();
|
||||
this.setPrimaryColor(theme.primary);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,6 +366,10 @@ export class BimButtonGroup implements IBimComponent {
|
||||
const hasLabel = this.options.showLabel && button.label;
|
||||
if (!hasLabel) {
|
||||
btnEl.classList.add('no-label');
|
||||
// 当不显示 label 时,添加 title 属性作为 tooltip
|
||||
if (button.label) {
|
||||
btnEl.title = t(button.label);
|
||||
}
|
||||
}
|
||||
|
||||
// 应用按钮的自定义样式
|
||||
@@ -412,13 +443,64 @@ export class BimButtonGroup implements IBimComponent {
|
||||
if (button.disabled) return;
|
||||
if (!button.children || button.children.length === 0) {
|
||||
if (button.keepActive) {
|
||||
this.setBtnActive(button.id);
|
||||
// 1) 先切换自身激活状态(onClick 里通常会根据 isActive 决定“打开/关闭”逻辑)
|
||||
const wasActive = this.activeBtnIds.has(button.id);
|
||||
const newState = !wasActive;
|
||||
this.setBtnActive(button.id, newState);
|
||||
|
||||
// 2) 互斥逻辑:仅在“本次切换为激活”时触发
|
||||
// - 一级按钮:同 groupId 下其它一级按钮互斥
|
||||
// - 二级按钮:同 groupId + 同 parentId 下其它二级按钮互斥
|
||||
// - 被关闭的按钮需要触发 onClick(用于执行关闭逻辑)
|
||||
if (newState && button.exclusive && button.groupId) {
|
||||
this.deactivateExclusiveSiblings(button);
|
||||
}
|
||||
}
|
||||
this.closeDropdown();
|
||||
if (button.onClick) button.onClick(button);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 互斥关闭同范围内的其它已激活按钮,并触发它们的 onClick
|
||||
* @param button 当前被激活的按钮
|
||||
*/
|
||||
private deactivateExclusiveSiblings(button: OptButton): void {
|
||||
const group = this.groups.find(g => g.id === button.groupId);
|
||||
if (!group) return;
|
||||
|
||||
// 二级按钮:同 groupId + 同 parentId
|
||||
if (button.parentId) {
|
||||
const parent = this.findButton(group.buttons, button.parentId);
|
||||
const siblings = parent?.children || [];
|
||||
for (const sib of siblings) {
|
||||
if (!sib) continue;
|
||||
if (sib.id === button.id) continue;
|
||||
if (sib.parentId !== button.parentId) continue;
|
||||
if (sib.groupId !== button.groupId) continue;
|
||||
|
||||
if (this.activeBtnIds.has(sib.id)) {
|
||||
this.setBtnActive(sib.id, false);
|
||||
// 触发被关闭按钮的 onClick(此时 sib.isActive 已经同步为 false)
|
||||
if (sib.onClick) sib.onClick(sib);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 一级按钮:同 groupId 下其它一级按钮(不包含二级)
|
||||
for (const sib of group.buttons) {
|
||||
if (sib.id === button.id) continue;
|
||||
if (sib.groupId !== button.groupId) continue;
|
||||
if (sib.parentId) continue; // 只处理一级按钮
|
||||
|
||||
if (this.activeBtnIds.has(sib.id)) {
|
||||
this.setBtnActive(sib.id, false);
|
||||
if (sib.onClick) sib.onClick(sib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleMouseEnter(button: OptButton, btnEl: HTMLElement): void {
|
||||
if (this.hoverTimeout) clearTimeout(this.hoverTimeout);
|
||||
if (button.children && button.children.length > 0) {
|
||||
@@ -440,6 +522,16 @@ export class BimButtonGroup implements IBimComponent {
|
||||
dropdown.className = 'opt-btn-dropdown';
|
||||
if (this.options.backgroundColor) dropdown.style.setProperty('--bim-toolbar-bg', this.options.backgroundColor);
|
||||
|
||||
// 将主题CSS变量复制到dropdown元素上(因为dropdown被添加到body,无法继承容器的CSS变量)
|
||||
const dropdownStyle = dropdown.style;
|
||||
if (this.options.iconColor) dropdownStyle.setProperty('--bim-icon-color', this.options.iconColor);
|
||||
if (this.options.iconActiveColor) dropdownStyle.setProperty('--bim-icon-active-color', this.options.iconActiveColor);
|
||||
if (this.options.textColor) dropdownStyle.setProperty('--bim-btn-text-color', this.options.textColor);
|
||||
if (this.options.textActiveColor) dropdownStyle.setProperty('--bim-btn-text-active-color', this.options.textActiveColor);
|
||||
if (this.options.btnBackgroundColor) dropdownStyle.setProperty('--bim-btn-bg', this.options.btnBackgroundColor);
|
||||
if (this.options.btnHoverColor) dropdownStyle.setProperty('--bim-btn-hover-bg', this.options.btnHoverColor);
|
||||
if (this.options.btnActiveColor) dropdownStyle.setProperty('--bim-btn-active-bg', this.options.btnActiveColor);
|
||||
|
||||
// 获取按钮的位置信息
|
||||
const btnRect = btnEl.getBoundingClientRect();
|
||||
const expand = this.options.expand || 'down';
|
||||
@@ -503,6 +595,14 @@ export class BimButtonGroup implements IBimComponent {
|
||||
item.classList.add('align-vertical');
|
||||
}
|
||||
|
||||
// 二级菜单项的 active 状态渲染(修复 keepActive 在二级按钮“看起来不生效”的问题)
|
||||
// 说明:
|
||||
// - keepActive 的状态会记录在 activeBtnIds / button.isActive 上
|
||||
// - 下拉菜单每次打开都会重新渲染,因此必须在这里同步一次 active 样式
|
||||
if (this.activeBtnIds.has(button.id) || button.isActive) {
|
||||
item.classList.add('active');
|
||||
}
|
||||
|
||||
// 应用按钮的自定义样式
|
||||
const iconSize = button.iconSize || 32; // 二级菜单默认图标更小
|
||||
const minWidth = button.minWidth; // 不设置默认值,让下拉菜单项保持紧凑
|
||||
@@ -523,6 +623,9 @@ export class BimButtonGroup implements IBimComponent {
|
||||
label.className = 'opt-btn-dropdown-label';
|
||||
label.textContent = t(button.label);
|
||||
item.appendChild(label);
|
||||
} else if (button.label) {
|
||||
// 当不显示 label 时,添加 title 属性作为 tooltip
|
||||
item.title = t(button.label);
|
||||
}
|
||||
|
||||
item.addEventListener('click', (e) => { e.stopPropagation(); this.handleClick(button); });
|
||||
@@ -572,11 +675,17 @@ export class BimButtonGroup implements IBimComponent {
|
||||
|
||||
const hasLabel = this.options.showLabel && button.label;
|
||||
|
||||
// 只需要更新 no-label 类,CSS 会处理显示/隐藏
|
||||
// 更新 no-label 类和 title 属性
|
||||
if (hasLabel) {
|
||||
btnEl.classList.remove('no-label');
|
||||
// 显示标签时,移除 title(避免重复显示)
|
||||
btnEl.removeAttribute('title');
|
||||
} else {
|
||||
btnEl.classList.add('no-label');
|
||||
// 隐藏标签时,添加 title 作为 tooltip
|
||||
if (button.label) {
|
||||
btnEl.title = t(button.label);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,6 +7,18 @@ export interface ButtonConfig {
|
||||
label: string;
|
||||
icon?: string;
|
||||
keepActive?: boolean;
|
||||
/**
|
||||
* 是否互斥(开关互斥)
|
||||
*
|
||||
* 行为说明:
|
||||
* - 当按钮从“未激活”切换到“激活”时,如果该按钮开启了 exclusive,
|
||||
* 会自动关闭同互斥范围内的其它已激活按钮,并触发它们的 onClick(用于执行关闭逻辑)。
|
||||
* - 一级按钮:互斥范围 = 同 groupId 下的一级按钮
|
||||
* - 二级按钮:互斥范围 = 同 groupId 且同 parentId 下的二级按钮
|
||||
*
|
||||
* 注意:该能力通常与 keepActive 搭配使用。
|
||||
*/
|
||||
exclusive?: boolean;
|
||||
isActive?:boolean;
|
||||
disabled?: boolean;
|
||||
onClick?: (button: OptButton) => void;
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
import { ButtonConfig } from '../../../index.type';
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
import { infoIcon } from './icon';
|
||||
|
||||
export const infoButton: ButtonConfig = {
|
||||
id: 'toolbar-info',
|
||||
type: 'button',
|
||||
label: 'toolbar.info',
|
||||
icon: infoIcon,
|
||||
onClick: () => {
|
||||
// WORKAROUND: Dispatch a standard custom event on document
|
||||
document.dispatchEvent(new CustomEvent('bim-demo:open-property-panel'));
|
||||
}
|
||||
/**
|
||||
* 信息按钮配置
|
||||
* 说明:当前仍保留 demo 的事件触发方式;engine 已注入,便于未来替换为 SDK 内部逻辑。
|
||||
*/
|
||||
export const createInfoButton = (_engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'toolbar-info',
|
||||
groupId: 'group-2',
|
||||
type: 'button',
|
||||
label: 'toolbar.info',
|
||||
icon: infoIcon,
|
||||
onClick: () => {
|
||||
// WORKAROUND: Dispatch a standard custom event on document
|
||||
document.dispatchEvent(new CustomEvent('bim-demo:open-property-panel'));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 定位按钮配置
|
||||
*/
|
||||
export const locationButton: ButtonConfig = {
|
||||
id: 'location',
|
||||
groupId: 'group-1',
|
||||
type: 'button',
|
||||
label: 'toolbar.location',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9 13h2v-2.75h2V13h2V8.25l-3-2l-3 2zm3 9q-4.025-3.425-6.012-6.362T4 10.2q0-3.75 2.413-5.975T12 2t5.588 2.225T20 10.2q0 2.5-1.987 5.438T12 22"/></svg>',
|
||||
keepActive: false,
|
||||
onClick: (button) => {
|
||||
console.log('定位按钮被点击:', button.id);
|
||||
}
|
||||
export const createLocationButton = (_engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'location',
|
||||
groupId: 'group-1',
|
||||
type: 'button',
|
||||
label: 'toolbar.location',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9 13h2v-2.75h2V13h2V8.25l-3-2l-3 2zm3 9q-4.025-3.425-6.012-6.362T4 10.2q0-3.75 2.413-5.975T12 2t5.588 2.225T20 10.2q0 2.5-1.987 5.438T12 22"/></svg>',
|
||||
keepActive: false,
|
||||
onClick: (button) => {
|
||||
// 预留:未来接入定位逻辑(此处已注入 engine)
|
||||
console.log('定位按钮被点击:', button.id);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 轴向剖切按钮配置
|
||||
*/
|
||||
export const createSectionAxisButton = (engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'section-axis',
|
||||
groupId: 'group-1',
|
||||
parentId: 'section',
|
||||
type: 'button',
|
||||
keepActive: true,
|
||||
exclusive: true,
|
||||
align: 'vertical',
|
||||
label: 'toolbar.sectionAxis',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><circle cx="12" cy="12" r="6" fill="currentColor"/></svg>',
|
||||
onClick: (button) => {
|
||||
if (button.isActive) {
|
||||
engine.sectionAxis?.show();
|
||||
} else {
|
||||
engine.sectionAxis?.destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 剖切盒按钮配置
|
||||
*/
|
||||
export const createSectionBoxButton = (engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'section-box',
|
||||
groupId: 'group-1',
|
||||
parentId: 'section',
|
||||
type: 'button',
|
||||
keepActive: true,
|
||||
exclusive: true,
|
||||
align: 'vertical',
|
||||
label: 'toolbar.sectionBox',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><circle cx="12" cy="12" r="6" fill="currentColor"/></svg>',
|
||||
onClick: (button) => {
|
||||
console.log('剖切盒被点击:', button.id, '激活状态:', button.isActive);
|
||||
if (button.isActive) {
|
||||
// 激活时显示弹窗
|
||||
engine.sectionBox?.show();
|
||||
} else {
|
||||
// 关闭时隐藏弹窗
|
||||
engine.sectionBox?.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 剖切菜单按钮配置
|
||||
*/
|
||||
export const createSectionMenuButton = (_engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'section',
|
||||
groupId: 'group-1',
|
||||
type: 'menu',
|
||||
label: 'toolbar.section',
|
||||
align: 'vertical',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8" fill="currentColor"/></svg>',
|
||||
keepActive: true,
|
||||
onClick: (button) => {
|
||||
console.log('剖切按钮被点击:', button.id);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 拾取面剖切按钮配置
|
||||
*/
|
||||
export const createSectionPlaneButton = (engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'section-plane',
|
||||
groupId: 'group-1',
|
||||
parentId: 'section',
|
||||
type: 'button',
|
||||
keepActive: true,
|
||||
exclusive: true,
|
||||
align: 'vertical',
|
||||
label: 'toolbar.sectionPlane',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><circle cx="12" cy="12" r="6" fill="currentColor"/></svg>',
|
||||
onClick: (button) => {
|
||||
console.log('拾取面剖切被点击:', button.id, '激活状态:', button.isActive);
|
||||
if (button.isActive) {
|
||||
// 激活时显示弹窗
|
||||
engine.sectionPlane?.show();
|
||||
} else {
|
||||
// 关闭时隐藏弹窗
|
||||
engine.sectionPlane?.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1,16 +1,20 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 定位按钮配置
|
||||
* 设置按钮配置
|
||||
*/
|
||||
export const settingButton: ButtonConfig = {
|
||||
id: 'setting',
|
||||
groupId: 'group-2',
|
||||
type: 'button',
|
||||
label: 'toolbar.setting',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="m9.25 22l-.4-3.2q-.325-.125-.612-.3t-.563-.375L4.7 19.375l-2.75-4.75l2.575-1.95Q4.5 12.5 4.5 12.338v-.675q0-.163.025-.338L1.95 9.375l2.75-4.75l2.975 1.25q.275-.2.575-.375t.6-.3l.4-3.2h5.5l.4 3.2q.325.125.613.3t.562.375l2.975-1.25l2.75 4.75l-2.575 1.95q.025.175.025.338v.674q0 .163-.05.338l2.575 1.95l-2.75 4.75l-2.95-1.25q-.275.2-.575.375t-.6.3l-.4 3.2zM11 20h1.975l.35-2.65q.775-.2 1.438-.587t1.212-.938l2.475 1.025l.975-1.7l-2.15-1.625q.125-.35.175-.737T17.5 12t-.05-.787t-.175-.738l2.15-1.625l-.975-1.7l-2.475 1.05q-.55-.575-1.212-.962t-1.438-.588L13 4h-1.975l-.35 2.65q-.775.2-1.437.588t-1.213.937L5.55 7.15l-.975 1.7l2.15 1.6q-.125.375-.175.75t-.05.8q0 .4.05.775t.175.75l-2.15 1.625l.975 1.7l2.475-1.05q.55.575 1.213.963t1.437.587zm1.05-4.5q1.45 0 2.475-1.025T15.55 12t-1.025-2.475T12.05 8.5q-1.475 0-2.488 1.025T8.55 12t1.013 2.475T12.05 15.5M12 12"/></svg>',
|
||||
keepActive: false,
|
||||
onClick: (button) => {
|
||||
console.log('设置按钮被点击:', button.id);
|
||||
}
|
||||
export const createSettingButton = (_engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'setting',
|
||||
groupId: 'group-2',
|
||||
type: 'button',
|
||||
label: 'toolbar.setting',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="m9.25 22l-.4-3.2q-.325-.125-.612-.3t-.563-.375L4.7 19.375l-2.75-4.75l2.575-1.95Q4.5 12.5 4.5 12.338v-.675q0-.163.025-.338L1.95 9.375l2.75-4.75l2.975 1.25q.275-.2.575-.375t.6-.3l.4-3.2h5.5l.4 3.2q.325.125.613.3t.562.375l2.975-1.25l2.75 4.75l-2.575 1.95q.025.175.025.338v.674q0 .163-.05.338l2.575 1.95l-2.75 4.75l-2.95-1.25q-.275.2-.575.375t-.6.3l-.4 3.2zM11 20h1.975l.35-2.65q.775-.2 1.438-.587t1.212-.938l2.475 1.025l.975-1.7l-2.15-1.625q.125-.35.175-.737T17.5 12t-.05-.787t-.175-.738l2.15-1.625l-.975-1.7l-2.475 1.05q-.55-.575-1.212-.962t-1.438-.588L13 4h-1.975l-.35 2.65q-.775.2-1.437.588t-1.213.937L5.55 7.15l-.975 1.7l2.15 1.6q-.125.375-.175.75t-.05.8q0 .4.05.775t.175.75l-2.15 1.625l.975 1.7l2.475-1.05q.55.575 1.213.963t1.437.587zm1.05-4.5q1.45 0 2.475-1.025T15.55 12t-1.025-2.475T12.05 8.5q-1.475 0-2.488 1.025T8.55 12t1.013 2.475T12.05 15.5M12 12"/></svg>',
|
||||
keepActive: false,
|
||||
onClick: (button) => {
|
||||
// 预留:未来接入设置逻辑(此处已注入 engine)
|
||||
console.log('设置按钮被点击:', button.id);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
|
||||
export const walkBirdButton: ButtonConfig = {
|
||||
id: 'walk-bird',
|
||||
groupId: 'group-1',
|
||||
parentId: 'walk',
|
||||
align: 'vertical',
|
||||
type: 'button',
|
||||
label: 'toolbar.walkBird',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9 22V8.775q-2.275-.6-3.637-2.512T4 2h2q0 2.075 1.338 3.538T10.75 7h2.5q.75 0 1.4.275t1.175.8L20.35 12.6l-1.4 1.4L15 10.05V22h-2v-6h-2v6zm3-16q-.825 0-1.412-.587T10 4t.588-1.412T12 2t1.413.588T14 4t-.587 1.413T12 6"/></svg>',
|
||||
onClick: (button) => {
|
||||
console.log('鸟瞰漫游被点击:', button.id);
|
||||
}
|
||||
/**
|
||||
* 第三人称(鸟瞰)漫游按钮配置
|
||||
*/
|
||||
export const createWalkBirdButton = (_engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'walk-bird',
|
||||
groupId: 'group-1',
|
||||
parentId: 'walk',
|
||||
align: 'vertical',
|
||||
keepActive: true,
|
||||
exclusive: true,
|
||||
type: 'button',
|
||||
label: 'toolbar.walkBird',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9 22V8.775q-2.275-.6-3.637-2.512T4 2h2q0 2.075 1.338 3.538T10.75 7h2.5q.75 0 1.4.275t1.175.8L20.35 12.6l-1.4 1.4L15 10.05V22h-2v-6h-2v6zm3-16q-.825 0-1.412-.587T10 4t.588-1.412T12 2t1.413.588T14 4t-.587 1.413T12 6"/></svg>',
|
||||
onClick: (button) => {
|
||||
console.log('鸟瞰漫游被点击:', button.id);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 漫游菜单按钮配置
|
||||
*/
|
||||
export const walkMenuButton: ButtonConfig = {
|
||||
id: 'walk',
|
||||
groupId: 'group-1',
|
||||
type: 'menu',
|
||||
label: 'toolbar.walk',
|
||||
align: 'vertical',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9 22V8.775q-2.275-.6-3.637-2.512T4 2h2q0 2.075 1.338 3.538T10.75 7h2.5q.75 0 1.4.275t1.175.8L20.35 12.6l-1.4 1.4L15 10.05V22h-2v-6h-2v6zm3-16q-.825 0-1.412-.587T10 4t.588-1.412T12 2t1.413.588T14 4t-.587 1.413T12 6"/></svg>',
|
||||
keepActive: true,
|
||||
onClick: (button) => {
|
||||
console.log('漫游按钮被点击:', button.id);
|
||||
}
|
||||
export const createWalkMenuButton = (_engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'walk',
|
||||
groupId: 'group-1',
|
||||
type: 'menu',
|
||||
label: 'toolbar.walk',
|
||||
align: 'vertical',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9 22V8.775q-2.275-.6-3.637-2.512T4 2h2q0 2.075 1.338 3.538T10.75 7h2.5q.75 0 1.4.275t1.175.8L20.35 12.6l-1.4 1.4L15 10.05V22h-2v-6h-2v6zm3-16q-.825 0-1.412-.587T10 4t.588-1.412T12 2t1.413.588T14 4t-.587 1.413T12 6"/></svg>',
|
||||
keepActive: true,
|
||||
onClick: (button) => {
|
||||
console.log('漫游按钮被点击:', button.id);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
|
||||
export const walkPersonButton: ButtonConfig = {
|
||||
id: 'walk-person',
|
||||
groupId: 'group-1',
|
||||
parentId: 'walk',
|
||||
type: 'button',
|
||||
align: 'vertical',
|
||||
label: 'toolbar.walkPerson',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9 22V8.775q-2.275-.6-3.637-2.512T4 2h2q0 2.075 1.338 3.538T10.75 7h2.5q.75 0 1.4.275t1.175.8L20.35 12.6l-1.4 1.4L15 10.05V22h-2v-6h-2v6zm3-16q-.825 0-1.412-.587T10 4t.588-1.412T12 2t1.413.588T14 4t-.587 1.413T12 6"/></svg>',
|
||||
onClick: (button) => {
|
||||
console.log('人视漫游被点击:', button.id);
|
||||
}
|
||||
/**
|
||||
* 第一人称漫游按钮配置
|
||||
*/
|
||||
export const createWalkPersonButton = (_engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'walk-person',
|
||||
groupId: 'group-1',
|
||||
parentId: 'walk',
|
||||
type: 'button',
|
||||
keepActive: true,
|
||||
exclusive: true,
|
||||
align: 'vertical',
|
||||
label: 'toolbar.walkPerson',
|
||||
icon: '<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9 22V8.775q-2.275-.6-3.637-2.512T4 2h2q0 2.075 1.338 3.538T10.75 7h2.5q.75 0 1.4.275t1.175.8L20.35 12.6l-1.4 1.4L15 10.05V22h-2v-6h-2v6zm3-16q-.825 0-1.412-.587T10 4t.588-1.412T12 2t1.413.588T14 4t-.587 1.413T12 6"/></svg>',
|
||||
onClick: (button) => {
|
||||
console.log('人视漫游被点击:', button.id);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 选框放大按钮配置
|
||||
*
|
||||
* 说明:
|
||||
* - 当前仅添加 UI 按钮,点击事件先留空(后续接入引擎能力再实现)
|
||||
* - 使用工厂函数模式注入 engine,便于未来调用 engine API
|
||||
*/
|
||||
export const createZoomBoxButton = (_engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'zoom-box',
|
||||
groupId: 'group-1',
|
||||
keepActive: true,
|
||||
type: 'button',
|
||||
label: 'toolbar.zoomBox',
|
||||
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M16.5 20q-1.875 0-3.187-1.312T12 15.5t1.313-3.187T16.5 11t3.188 1.313T21 15.5q0 .65-.187 1.25T20.3 17.9l2 2q.275.275.275.7t-.275.7t-.7.275t-.7-.275l-2-2q-.55.325-1.15.513T16.5 20m0-2q1.05 0 1.775-.725T19 15.5t-.725-1.775T16.5 13t-1.775.725T14 15.5t.725 1.775T16.5 18M4 18V9v1v-4zm0 2q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4h16q.825 0 1.413.588T22 6v3q0 .425-.288.713T21 10h-8V6H4v12h5q.425 0 .713.288T10 19t-.288.713T9 20z"/></svg>',
|
||||
onClick: () => {
|
||||
// 事件先留空:后续实现“框选放大/框选缩放”能力时再接入
|
||||
// 这里不做任何动作,避免误触影响用户操作
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -13,32 +13,42 @@ export class Toolbar extends BimButtonGroup {
|
||||
|
||||
// 动态加载默认按钮配置
|
||||
const { createHomeButton } = await import('./buttons/home');
|
||||
const { locationButton } = await import('./buttons/location');
|
||||
const { walkMenuButton } = await import('./buttons/walk/walk-menu');
|
||||
const { walkPersonButton } = await import('./buttons/walk/walk-person');
|
||||
const { walkBirdButton } = await import('./buttons/walk/walk-bird');
|
||||
const { settingButton } = await import('./buttons/setting');
|
||||
const { infoButton } = await import('./buttons/info');
|
||||
const { createZoomBoxButton } = await import('./buttons/zoom-box');
|
||||
const { createLocationButton } = await import('./buttons/location');
|
||||
const { createWalkMenuButton } = await import('./buttons/walk/walk-menu');
|
||||
const { createWalkPersonButton } = await import('./buttons/walk/walk-person');
|
||||
const { createWalkBirdButton } = await import('./buttons/walk/walk-bird');
|
||||
const { createSettingButton } = await import('./buttons/setting');
|
||||
const { createInfoButton } = await import('./buttons/info');
|
||||
const { createMeasureButton } = await import('./buttons/measure');
|
||||
const { createSectionMenuButton } = await import('./buttons/section/section-menu');
|
||||
const { createSectionPlaneButton } = await import('./buttons/section/section-plane');
|
||||
const { createSectionAxisButton } = await import('./buttons/section/section-axis');
|
||||
const { createSectionBoxButton } = await import('./buttons/section/section-box');
|
||||
|
||||
this.addGroup('group-1');
|
||||
|
||||
// 使用工厂函数创建按钮,并注入 engine
|
||||
if (this.engine) {
|
||||
this.addButton(createHomeButton(this.engine));
|
||||
// 你要求:在"首页"后面添加"选框放大"
|
||||
this.addButton(createZoomBoxButton(this.engine));
|
||||
this.addButton(createMeasureButton(this.engine));
|
||||
this.addButton(createSectionMenuButton(this.engine));
|
||||
this.addButton(createSectionPlaneButton(this.engine));
|
||||
this.addButton(createSectionAxisButton(this.engine));
|
||||
this.addButton(createSectionBoxButton(this.engine));
|
||||
this.addButton(createWalkMenuButton(this.engine));
|
||||
this.addButton(createWalkPersonButton(this.engine));
|
||||
this.addButton(createWalkBirdButton(this.engine));
|
||||
this.addButton(createLocationButton(this.engine));
|
||||
this.addGroup('group-2');
|
||||
this.addButton(createSettingButton(this.engine));
|
||||
this.addButton(createInfoButton(this.engine));
|
||||
} else {
|
||||
console.warn('[Toolbar] Engine not available when creating buttons.');
|
||||
}
|
||||
|
||||
this.addButton(walkMenuButton);
|
||||
this.addButton(walkPersonButton);
|
||||
this.addButton(walkBirdButton);
|
||||
this.addButton(locationButton);
|
||||
this.addGroup('group-2');
|
||||
this.addButton(settingButton);
|
||||
this.addButton(infoButton);
|
||||
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user