@caoguo/theme
v0.0.12
Published
草果地图主题样式 — 矢量主题构造 + 暗/亮双套配色 + CSS 变量体系
Maintainers
Readme
@caoguo/theme
草果地图主题样式包 — 矢量主题构造 + 暗/亮双套配色 + CSS 变量体系
安装
npm install @caoguo/theme
# 或
pnpm add @caoguo/thememaplibre-gl@^4.7.1 是 peerDependency,请确保已安装。
功能
- 提供两套矢量主题:
caoguo-dark(指挥中心/大屏)和caoguo-light(日常浏览)。 - 通过
buildStyle()构造完整 MapLibre Style Spec(含地形、水系、道路、行政边界、注记)。 - 支持中文字体覆盖(Noto Sans SC / 思源黑体)。
- 提供 CSS 变量主题系统(
data-theme="..."),与 VitePress 等 SPA 框架天然兼容。 - 主题构造为纯函数,可在 Node 环境测试、可在浏览器端直接使用。
buildStyle始终保证输出含glyphs(style 自身未声明且无opts.glyphs时回退DEFAULT_GLYPHS),避免 symbol 层中文注记渲染失败。
内置图层清单(每套主题 15 层)
| 图层 id | 类型 | source-layer | 说明 |
|---------|------|--------------|------|
| background | background | — | 底色铺底(始终可见) |
| water | fill | water | 水系面 |
| landuse | fill | landuse | 土地利用 |
| landcover | fill | landcover | 地表覆盖 |
| road-minor | line | roads(class=minor) | 次干道,minzoom=12 |
| road-major | line | roads(primary/secondary/tertiary/motorway) | 主干道,宽度随缩放插值 |
| road-label | symbol | roads(线注记) | 道路名,minzoom=13 |
| boundary | line | boundaries | 行政边界(虚线) |
| waterway | line | waterway | 河流/水渠线 |
| rail | line | railway | 铁路(虚线) |
| park | fill | park | 绿地/公园 |
| building | fill | building | 建筑面,minzoom=13 |
| building-extrusion | fill-extrusion | building | 建筑 3D 挤出(基于 height/min_height),minzoom=15 |
| place-label-major | symbol | places(scalerank≤3) | 主要地名(粗体) |
| place-label-minor | symbol | places(scalerank>3) | 次要地名,minzoom=8 |
注记分级依据矢量源的
scalerank字段;若你的瓦片源无该字段,可改用registerTheme自定义主题。
缩放层级覆盖(PRD 验收「3-18 无断裂」)
包内测试对 themeNames 每套主题在 zoom 3..18 做静态校验:background/water 全程可见,z≥8 至少有主干道或注记之一,z≥13 出现建筑层。真机渲染断档仍需以实际瓦片源在浏览器验收。
快速开始
主题切换 composable(useTheme)
useTheme() 封装 injectTheme 并监听 cg:themechange,适合在 VitePress enhanceApp / 组件内使用,返回响应式 theme 与 setTheme/toggle。当任意处(含地图实例)切换主题时,这里会自动同步。
import { useTheme } from '@caoguo/theme';
const { theme, setTheme, toggle } = useTheme({
initial: 'caoguo-dark',
onChange: (name) => map?.setStyle(buildStyle({ theme: name })), // 联动地图换肤
});
setTheme('caoguo-light');浏览器:构造主题样式
import { buildStyle, darkStyle, lightStyle, injectTheme } from '@caoguo/theme';
// 1. 选择主题
const style = darkStyle;
// 或按需构造
// const style = buildStyle({ theme: 'caoguo-light', notoFonts: true });
// 2. 配合 @caoguo/maplibre 使用
import { Map } from '@caoguo/maplibre';
const map = new Map({ container: 'map', style });
// 3. SPA 场景:注入 data-theme 让 CSS 变量生效
injectTheme('caoguo-dark');仅注入 CSS 变量主题
import { injectTheme, themeNames } from '@caoguo/theme';
console.log(themeNames); // ['caoguo-dark', 'caoguo-light']
injectTheme('caoguo-dark');API 概览
| 导出 | 类型 | 说明 |
|------|------|------|
| darkStyle | StyleSpecification | 预构造的暗色主题 |
| lightStyle | StyleSpecification | 预构造的亮色主题 |
| buildStyle(opts?) | (opts?: BuildStyleOptions \| ThemeName, legacyOpts?: BuildStyleOptions) => StyleSpecification | 自定义构造(支持对象式 / 旧式位置参数) |
| themeNames | readonly ['caoguo-dark', 'caoguo-light'] | 内置基础主题名常量(向后兼容;动态列表见 getThemeList) |
| getThemeList() | () => string[] | 返回所有可用主题名(内置 + 运行时注册行业主题,去重) |
| registerTheme(name, style) | (name: string, style: StyleSpecification) => void | 注册行业主题(六张网) |
| registerIndustryThemes() | () => void | 一键注入六张网行业主题变体(幂等) |
| INDUSTRY_META | Record<IndustryKey, IndustryMeta> | 六张网元信息(themeId / 中文名 / 主色) |
| INDUSTRY_PALETTES | Record<IndustryKey, IndustryTheme> | 六张网权威色板(语义色 / 分级色 / 状态色) |
| buildIndustryStyle(key, mode?) | (key: IndustryKey, mode?: 'dark' \| 'light') => StyleSpecification | 直接派生某张网行业底图 |
| getRegisteredThemes() | () => string[] | 返回所有已注册主题名(含运行时注册的) |
| hasTheme(name) | (name: string) => boolean | 判断是否为已知主题 |
| injectTheme(name, onChange?) | (name: string, onChange?: (name: string) => void) => void | 给 <html> 设置 data-theme;切换时触发 onChange 并派发 cg:themechange 事件,便于联动地图 setStyle |
| useTheme(opts?) | (opts?: UseThemeOptions) => UseThemeReturn | 轻量主题 composable:响应式 theme + setTheme/toggle,监听 cg:themechange 同步 |
类型:ThemeName(内置)、AnyTheme = string(含行业主题)、BuildStyleOptions、UseThemeOptions、UseThemeReturn、DEFAULT_GLYPHS、IndustryKey、IndustryMeta、IndustryTheme、Palette。
行业主题(六张网真实配色)
六张网(管网 / 电网 / 水网 / 交通 / 算力 / 通信)的真实语义配色已沉淀到本包。INDUSTRY_PALETTES 汇总了各业务包(@caoguo/{grid,water,transport,compute,telecom,pipeline})既已落地的 *Theme.ts 颜色常量,作为权威色板供大屏换肤、图例与 demo 统一复用;registerIndustryThemes() 则将六张网行业主题变体注入注册表,使 buildStyle({ theme: 'caoguo-ind-<key>' }) 可直接使用。
import {
INDUSTRY_PALETTES, // 六张网权威色板(语义色 / 分级色 / 状态色)
INDUSTRY_META, // 六张网元信息:themeId / 中文名 / 主色
registerIndustryThemes,
buildStyle,
buildIndustryStyle,
} from '@caoguo/theme';
// 1. 注册六张网行业主题(建议在应用启动时调用一次)
registerIndustryThemes();
// 2. 直接构造某张网的行业底图(基于 dark 派生,注入行业主色)
const gridStyle = buildStyle({ theme: 'caoguo-ind-grid' });
// 或显式取派生对象:
const waterStyle = buildIndustryStyle('water', 'dark');
// 3. 复用色板(替代各包各自硬编码颜色)
console.log(INDUSTRY_PALETTES.grid.palette); // { uhv:'#ef4444', high:'#f59e0b', ... }六张网主色与语义色一览
| 行业 | themeId | 主色 | 核心语义色(要素 / 类型) |
|------|---------|------|---------------------------|
| 管网 pipeline | caoguo-ind-pipeline | #0891b2 | 输气 #f97316 / 输油 #fbbf24 / 供水 #3b82f6 / 排水 #0ea5e9 / 综合管廊 #8b5cf6 |
| 电网 grid | caoguo-ind-grid | #f59e0b | 特高压 #ef4444 / 高压 #f59e0b / 中压 #3b82f6 / 低压 #22c55e / 配电 #a855f7 |
| 水网 water | caoguo-ind-water | #3b82f6 | 流域 #0ea5e9 / 干流 #3b82f6 / 支流 #60a5fa / 水库 #0ea5e9 / 闸站 #f59e0b / 堤防 #fbbf24 |
| 交通 transport | caoguo-ind-transport | #f97316 | 高速 #f59e0b / 国道 #ef4444 / 省道 #8b5cf6 / 城市道路 #6b7280 / 轨道 #22d3ee |
| 算力 compute | caoguo-ind-compute | #8b5cf6 | 主节点 #3b82f6 / 区域云 #8b5cf6 / 骨干网 #22d3ee / 边缘 #14b8a6 / 集群 #f59e0b |
| 通信 telecom | caoguo-ind-telecom | #10b981 | 光纤 #22d3ee / 5G #10b981 / 微波 #f59e0b / 卫星 #8b5cf6 / 基站 #14b8a6 |
每网还含 ramp(数值分级色,常用于流量 / 负载 / 信号热力)与 status(状态色,如安全 / 预警 / 危险)。完整取值见 INDUSTRY_PALETTES。
行业底图变体基于
caoguo-dark克隆并在metadata注入cg:industry/cg:industry-label/cg:industry-primary,业务图层与大屏辉光可据此统一取色。如需替换真实矢量源,仍可用buildStyle({ theme, sourceUrl, glyphs })。
CSS 变量
tokens.css 内置 CSS 变量,组件层可直接消费:
:root[data-theme="caoguo-dark"] {
--cg-bg: #0a0e1a;
--cg-fg: #e8edf3;
--cg-accent: #4a9eff;
/* ... */
}直接 import 即可:
import '@caoguo/theme/dist/tokens.css';浏览器 / 环境要求
- 现代浏览器(Chrome 90+ / Firefox 88+ / Edge 90+)
- SSR 友好:
injectTheme内置typeof document守卫 - 纯函数模块可在 Node.js 环境单独测试(已含 vitest 用例)
许可
Apache-2.0
