主题与状态栏
文档:
vjcad/doc/ui/index.md(theme + statusbar 段) 示例:
vjcad/example/ui/07theme.js— 主题切换vjcad/example/ui/08statusbar.js— 状态栏功能按钮
1. 主题切换
vjcad 的"主题"其实是两套互不相干的东西:
Engine.THEME_MODE—— 画布主题(0 深 / 1 浅)。setter 只做三件事:写 localStorage、同步状态栏主题按钮、自动setBgc(0|255)。不改菜单 / 对话框 / 侧边栏等 UI 配色- UI 外壳配色 ——
MainView配置themeColors: {...},或运行时cadView.setThemeColors(partial)/Engine.setThemeColors(partial)(resetThemeColors()复原、getThemeColors()读取),写的是--theme-color-*CSS 变量
Engine.setBgc(gray) 是画布背景的底层开关,THEME_MODE 已经替你调用了。
// 画布切浅色(自动 setBgc(255) 并重绘)
Engine.THEME_MODE = 1;
// 画布切回深色(自动 setBgc(0) → #212830)
Engine.THEME_MODE = 0;
// UI 外壳换色(与 THEME_MODE 无关)
Engine.setThemeColors({ shellBg: '#f3f4f6', font: '#111827', border: '#d1d5db', accent: '#2563eb' });
| 值 | 含义 |
|---|---|
THEME_MODE = 0 |
画布深色(默认) |
THEME_MODE = 1 |
画布浅色 |
setBgc(0) |
默认深色底 Engine.DARK_BG_COLOR(#212830,不是纯黑) |
setBgc(255) |
白色 Engine.LIGHT_BG_COLOR(#FFFFFF) |
setBgc(1~254) |
按灰度 rgb(g,g,g)(如 33 → #212121,与默认 #212830 不同) |
2. 主题相关辅助函数
Engine.isDarkTheme(); // boolean
Engine.getThemeBackground(); // CSS 颜色字符串
// ⚠️ 无 Engine.themeColor()——实体的"主题自动反色"用 ACI 颜色 7(见下节);
// 主题色板读写用 Engine.getThemeColors() / Engine.setThemeColors(partial)
3. 颜色 7 的特殊性
ACI 颜色 7 在 vjcad 里是"主题色"——
- 深色主题:白色 (
0xffffff) - 浅色主题:黑色 (
0x000000)
写实体时直接 entity.color = 7 即可,不用 自己根据主题改颜色。
const text = new TextEnt([0, 0], '随主题变化', 10); // (insertionPoint, textString, height)
text.setDefaults();
text.color = 7;
Engine.addEntities(text);
4. 状态栏(FuncButtons)
底部状态栏由两块组成:
- 左侧:CoordsBar —— 实时坐标
- 右侧:FuncButtons —— 模式开关按钮
const coordsBar = Engine.view.coordsBar;
const funcButtons = coordsBar.funcButtons;
funcButtons.osnapButton.isOn; // 对象捕捉是否开
funcButtons.gridmodeButton.isOn; // 栅格
funcButtons.orthomodeButton.isOn; // 正交
funcButtons.polarmodeButton.isOn; // 极轴追踪(字段名是 polarmodeButton,不是 polarButton)
按钮状态由对应 Engine 全局变量驱动:
| 变量 | 含义 | 快捷键 |
|---|---|---|
Engine.OSMODE |
对象捕捉位掩码(1~512 各模式位;16384 位 = 捕捉总开关关闭,F3 就是切这一位;默认 255) | F3 |
Engine.GRIDMODE |
栅格 0/1 | F7 |
Engine.ORTHOMODE |
正交 0/1 | F8 |
Engine.POLARMODE |
极轴追踪 0/1 | F10 |
Engine.SNAPMODE |
❌ 不存在——栅格捕捉开关在源码里没有独立 sysvar,只有 GRIDMODE/ORTHOMODE 等 | F9 |
// 程序化打开 / 关闭
Engine.ORTHOMODE = 1;
Engine.GRIDMODE = 1;
// 设置对象捕捉位
const OSNAP = {
END: 1, MID: 2, CEN: 4, NODE: 8, QUA: 16, INT: 32,
INS: 64, PER: 128, TAN: 256, NEA: 512
};
Engine.OSMODE = OSNAP.END | OSNAP.MID | OSNAP.CEN;
变量改了之后状态栏按钮 会自动更新(双向绑定)。
5. 主题变更监听
没有 CadEvents.ThemeChanged 事件。Engine.THEME_MODE setter 内部已经做了三件事:写 localStorage(THEME_CACHE_KEY)、更新状态栏主题按钮、pcanvas.setBgc(0|255)。要感知主题变化,只能包一层 setter 或轮询:
let last = Engine.THEME_MODE;
setInterval(() => {
if (Engine.THEME_MODE !== last) {
last = Engine.THEME_MODE;
console.log('当前主题:', last === 0 ? '深色' : '浅色');
}
}, 500);
6. 状态栏自定义按钮(高级)
没有往状态栏加按钮的 API。coordsBar.funcButtons(<func-buttons>)是 Lit 组件,按钮都渲染在它自己的 shadow DOM 里且没有 <slot>——funcBar.appendChild(btn) 只会挂到 light DOM,不会显示:
const funcBar = Engine.view.coordsBar.funcButtons;
funcBar.appendChild(myBtn); // ❌ 无效:无 slot,不渲染
要放自定义开关,改用浮动工具栏 createFloatingToolbar、Ribbon 按钮(plugin/menu-ribbon)或自己定位的 DOM。自绘按钮想跟随 UI 配色,用真实存在的变量 --theme-color-button-bg / --theme-color-button-hover-bg / --theme-color-font / --theme-color-border(由 setThemeColors 写到 document.documentElement)。
7. 完全隐藏状态栏
new MainView({
showBottomBar: false, // 不显示底栏(没有 showFuncButtons 键)
showCoordsBar: false, // 不显示坐标
});
// 或:
new MainView({ viewMode: 'viewer' }); // 强制隐藏整个状态栏(viewer 下 showCoordsBar:true 也无效)
8. 实战:主题持久化
// THEME_MODE setter 自带 localStorage 持久化 + setBgc + 状态栏按钮同步,
// 启动时无需手动读存——赋一次值即可(它内部已写 THEME_CACHE_KEY)
Engine.THEME_MODE = 1; // 浅色
Engine.isDarkTheme(); // 读当前
Engine.getThemeBackground(); // 当前背景色 hex
红旗
THEME_MODE只管画布(并已自动setBgc),不改 UI 外壳颜色;想 UI 也变浅要另调setThemeColors(...)(或 MainViewthemeColors配置)setBgc内部已自动重绘(深浅类型变化时regen,否则redraw),无需再调Engine.redraw();默认深色底是setBgc(0)(#212830),不是 33- 状态栏按钮的
isOn是只读的;要切换状态请改对应 Engine 变量(如Engine.ORTHOMODE = 1),按钮会自动同步 Engine.OSMODE是 位掩码;= 0关闭所有捕捉,全开用1023(1~512 十个模式位);临时关闭保留各模式用Engine.OSMODE |= 16384,恢复&= ~16384。⚠️ 别写0xFFFF——它含 16384 位,等于关闭捕捉- 颜色 7 在某些导出 / 转 PDF 场景下不会跟随主题(取决于导出器实现),强制可见的题图请显式设颜色
viewMode: 'viewer'会一并隐藏状态栏,且 viewer 分支只认sidebarStyle / enableContextMenu:true / showGrips:true,showCoordsBar: true无效;要坐标条就用viewMode:'full'+ 细粒度开关(无 showFuncButtons 键)
参考(官方文档 MCP)
- 文档:
vjcad/doc/ui/index.md(theme + statusbar 段) - 示例:
vjcad/example/ui/07theme.js— 主题切换vjcad/example/ui/08statusbar.js— 状态栏功能按钮