唯杰地图 logo唯杰地图
VJMAP
EN

浮动工具栏(FloatingToolbar)

vjcad/references/ui/floating-toolbar.md 6.1 KB142 行
原文

文档:vjcad/doc/ui/index.md(floating-toolbar 段) 示例:vjcad/example/ui/15floatingtoolbar.js

1. 用途

FloatingToolbar 是悬浮在画布上的可拖动小工具栏。适合:

  • 不希望占用 Ribbon / 菜单的"自定义快捷键面板"
  • 测量 / 标注等"工作模式临时面板"
  • 移动端 / 触屏简化操作面板

由全局工厂 createFloatingToolbar(id, options) 创建,单例:相同 id 第二次调用会返回已有实例(并顺手 show() 它,新传的 options 被忽略)。新建的工具栏默认是隐藏的,必须调 show()。

2. 最小示例

const { createFloatingToolbar, IconRegistry, IconCategory, Engine } = vjcad;

const tb = createFloatingToolbar('draw-tools', {
    title: '绘图工具',
    columns: 4,
    iconSize: 30,
    position: { top: '80px', right: '20px' },
    items: [
        { id: 'line',   icon: IconRegistry.getIcon('line',   IconCategory.Commands),
          tooltip: '直线 (LINE)',   command: 'LINE' },
        { id: 'circle', icon: IconRegistry.getIcon('circle', IconCategory.Commands),
          tooltip: '圆 (CIRCLE)',   command: 'CIRCLE' },
        { id: 'arc',    icon: IconRegistry.getIcon('arc',    IconCategory.Commands),
          tooltip: '圆弧 (ARC)',    command: 'ARC' },
        { id: 'zoomext',
          icon: '<svg viewBox="0 0 24 24" stroke="#58a6ff"><polyline points="15 3 21 3 21 9"/></svg>',
          tooltip: '缩放全图',
          onClick: () => Engine.zoomExtents() }
    ]
});
tb.show();

要点:

  • command 字段直接走 Engine.editor.executerWithOp(command)
  • 没注册过命令的项用 onClick 回调
  • IconRegistry.getIcon(name, IconCategory.Commands) 返回内置 SVG 字符串,找不到时返回 undefined,自己 fallback

3. 配置项

interface FloatingToolbarOptions {
    title?: string;                     // 标题,留空 → 不显示标题栏
    showHeader?: boolean;               // 强制显示 / 隐藏标题栏
    position?: PanelPosition;           // { top?/right?/bottom?/left? } CSS 定位
    columns?: number;                   // 横向布局:每行多少列
    rows?: number;                      // 纵向布局:每列多少行
    iconSize?: number;                  // 图标按钮像素尺寸
    items?: FloatingToolbarItem[];
}

interface FloatingToolbarItem {
    id: string;                         // 唯一
    icon: string;                       // 只能是内联 SVG 字符串(以 '<svg' 开头)或图片 URL;不查 IconRegistry,
                                        // 写注册名会被当成 <img src="line"> 而裂图——要内置图标就 IconRegistry.getIcon(...) 取 SVG 串
    tooltip: string;                    // ⚠️ 必填(不是可选)
    command?: string;                   // 直接执行的 vjcad 命令
    onClick?: () => void;               // 自定义回调
    disabled?: boolean;
}

FloatingToolbarOptions 只有上面 7 个键——没有 draggable / closeOnEsc。

columns 与 rows 互斥:填了 columns 是横式(行数自适应),填了 rows 是竖式(列数自适应)。

4. 实例管理 API

const tb = createFloatingToolbar('my-tools', { /* ... */ });

tb.show();         // 显示(新建后默认隐藏,必须调)
tb.hide();
tb.close();        // 与 hide() 完全相同,不触发任何事件
tb.destroy();      // 彻底销毁、从 DOM 移除、删 cache

tb.addItem({ id: 'spline', icon: '...', tooltip: '样条', command: 'SPLINE' });
tb.addItems([{ id: 'a', icon: '...', tooltip: 'A' }, { id: 'b', icon: '...', tooltip: 'B' }]);
tb.removeItem('spline');
tb.updateItem('line', { tooltip: '改了一下', disabled: true });
tb.resetPosition();   // 清掉持久化位置并复位到 options.position(没有 setPosition/toggle 方法)
tb.isVisible;

5. 单例特性

const t1 = createFloatingToolbar('draw-tools', { title: 'A', columns: 4 });
const t2 = createFloatingToolbar('draw-tools', { title: 'B' });   // 不会重建
console.log(t1 === t2);   // true,title 仍是 'A'

需要"重新构建"时先 destroy 再 create:

tb.destroy();
const fresh = createFloatingToolbar('draw-tools', { title: '新建' });

6. 实战:根据当前命令切换工具栏

const drawTb = createFloatingToolbar('draw-tools', { /* 绘图项 */ });
const editTb = createFloatingToolbar('edit-tools', { /* 编辑项 */ });

const events = CadEventManager.getInstance();
events.on(CadEvents.SelectionChanged, () => {
    const sel = ssGetFirst() ?? [];
    if (sel.length > 0) { drawTb.hide(); editTb.show(); }
    else                { drawTb.show(); editTb.hide(); }
});

7. 可访问性 / 键盘

  • 拖拽标题栏(或顶部 16px 拖动条)即可移动;拖动结束后位置持久化到 localStorage(键 vjcad-ftb-pos-<id>),下次同 id 创建时优先用缓存位置、忽略 options.position
  • resetPosition() 删除该缓存并复位到 options.position
  • 支持 tooltip 鼠标悬停出现

红旗

  • id 全局唯一;与别的插件同 id 时后创建者直接拿到先创建者的实例(自己的 options/items 被忽略),不是互相覆盖——id 加插件前缀
  • 一次性创建过多浮动工具栏(>4 个)会让画布变挤;通常配合命令上下文动态显示
  • command 字段必须是已注册的命令名;命令未注册时点击没反应
  • tooltip 是 FloatingToolbarItem 的必填字段
  • position 在窗口缩放后不会自动重排,自适应 要自己监听 window.resize 后用 resetPosition() 或重建;改了 options.position 却不生效,多半是 localStorage 里有旧的拖动位置,先 resetPosition()
  • destroy() 会移除 DOM 但不会注销点击监听里的引用,自定义 onClick 中如有外部资源记得释放

参考(官方文档 MCP)

  • 文档:vjcad/doc/ui/index.md(floating-toolbar 段)
  • 示例:vjcad/example/ui/15floatingtoolbar.js