> **本文回答**：CAD 深色 / 浅色主题切换 —— `openMapDarkStyle` / `openMapLightStyle` / `svc.cmdUpdateStyle`。

## 一、内置两套主题

```js
// 浅色（白底黑线）
const res = await svc.openMap({
  mapid,
  mapopenway: vjmap.MapOpenWay.GeomRender,
  style: vjmap.openMapLightStyle()
});

// 深色（黑底白线）
await svc.openMap({
  mapid,
  mapopenway: vjmap.MapOpenWay.GeomRender,
  style: vjmap.openMapDarkStyle()
});
```

传给 `openMap` 的 style 是**后端渲染表达式**，不是前端样式规范。

## 二、openMapDarkStyle 实际是什么

```js
vjmap.openMapDarkStyle();   // → { backcolor: 0 }
vjmap.openMapLightStyle();  // → { backcolor: 16777215 }（0xFFFFFF）
```

注意：返回值**只有 `backcolor` 一个字段**——深/浅主题的实际反色逻辑由服务端按 backcolor 推断（`svc.currentMapParam().darkMode` 也是 `style.backcolor === 0` 判定）。要自定义反色规则，在 style 里自行加 `expression`（见 [backend/svr-style-var](../backend/svr-style-var.md)）。

## 三、动态切换主题

### 方式 A：重新 openMap

```js
const res = await svc.openMap({
  mapid: curMapId,
  style: isDark ? vjmap.openMapDarkStyle() : vjmap.openMapLightStyle(),
  mapopenway: vjmap.MapOpenWay.GeomRender
});
// 重新设置 map.style（setStyle 会清掉自定义 source/layer；只换主题优先用方式 B 的 map.updateStyle）
map.setStyle(svc.rasterStyle());
```

### 方式 B：只改后端样式 + 刷新瓦片

```js
// map.updateStyle = svc.cmdUpdateStyle + 换瓦片 URL 刷新（栅格模式只换 tiles，自定义图层不丢）
await map.updateStyle(svc, {
  name: "customStyle",
  backcolor: 0,
  expression: "gOutColorRed := 255 - gInColorRed; gOutColorGreen := 255 - gInColorGreen; gOutColorBlue := 255 - gInColorBlue;"
});
```

若已单独调过 `svc.cmdUpdateStyle(...)`，再 `map.changeSourceTiles(svc.rasterTileUrl())` 刷新。⚠️ raster 源**没有** `setTiles`（只有 vector 源有），`map.getSource(...).setTiles(...)` 会抛 TypeError。

## 四、前端 div 背景色同步

深色主题时地图底色如果是白色，出现闪白。必须同步：

```css
#map { background: #000; }
```

或 JS：

```js
map.getContainer().style.background = isDark ? "#000" : "#fff";
```

## 五、UI 主题色

Marker / Popup / ContextMenu 都有 light / dark 选择：

```js
new vjmap.ContextMenu({ event, theme: "dark", items: [...] });
new vjmap.Popup({ className: "dark-popup" });
```

Marker 和 Popup 的 CSS 可以通过 className 覆盖。

## 六、Marker 图标的明暗

如果 Marker 用 PNG，切换主题时可以切两张图：

```js
marker.getElement().style.backgroundImage = `url(${isDark ? "pin-light.png" : "pin-dark.png"})`;
```

## 七、矢量 CAD 主题

矢量瓦片模式下，颜色存在 `properties.color` 里，可以用样式表达式动态反色：

```js
// 矢量瓦片模式同样走 updateStyle：darkMode（backcolor）变化时，内部用 svc.vectorStyle() 的同名图层替换当前图层配色
await map.updateStyle(svc, { backcolor: isDark ? 0 : 0xFFFFFF });
```

（表达式里不能调用 JS 函数，`invertHex(["get", "color"])` 之类写法无法运行。）

更简单的做法：提前在前端写两套配色。

## 八、互联网地图主题

| 底图 | 深色样式 |
|---|---|
| 高德 | 无公开的深色 XYZ 样式：`style=8` 是矢量道路图，`style=6` 是**卫星影像**（不是黑夜样式） |
| 天地图 | `T=vec_w`（白底） / `T=ter_w`（地形） |
| 标准国际底图 | `streets-v12` / `dark-v11` / `light-v11` 等主题 |
| 百度 | v1 / dark / midnight（需参数 `customid`） |

## 九、常见坑

1. **切换主题后 CAD 图没变** → 只调了 `svc.cmdUpdateStyle` 没刷瓦片（用 `map.updateStyle` 或补 `map.changeSourceTiles`），或没传对 `svrStyleVar`。
2. **白闪问题**：背景色没改。
3. **同时打开 light + dark 两张地图对比**：用不同 map 实例，各自 style。
4. **用户自定义 CAD 图层色 vs 主题色**：主题色通常是"反色"逻辑，前端改 CAD 图层独立颜色时需关闭反色。
