视觉设计系统:古纸水墨的数字化表达¶
本文是 主文章 的扩展阅读,聚焦于系统视觉语言的设计过程——如何用 CSS 和 ECharts 构建一套有古桥文化温度的数字界面。
一、设计目标¶
这个项目不是一个通用的数据可视化仪表盘。它展示的是中国古桥——一种有历史厚度、材料质感和文化记忆的实体遗产。视觉设计的目标是让用户在操作数据的同时,能感受到"一卷展开的古桥图谱"的氛围。
基于这个定位,我确定了三个设计准则:
- 温暖而非冰冷:不用蓝灰色系的"数据仪表盘"风格,而是用暖纸色、桥木褐、河川蓝构建色彩基调
- 有质感而非扁平:不追求纯粹的 Flat Design,而是通过多层渐变、阴影和玻璃拟态模拟"纸张叠放"的物理层次
- 克制而非花哨:动画和装饰服务于信息传达,不做"微信公众号"式的炫技风格
二、色彩体系¶
2.1 主色板¶
整套系统的色彩围绕古桥的物质本体展开——石料的灰褐、木材的棕黄、河水的青蓝、旧纸的米白:
| 色彩角色 | 色值 | 命名 | 灵感来源 |
|---|---|---|---|
| 主色 | #6a4735 |
Bridge Brown(桥木褐) | 古桥木材的深棕色调 |
| 强调色 | #c57b3a |
Earth Orange(土壤橙) | 夯土碑基、古砖 |
| 辅助色 | #4f7681 |
River Blue(河川蓝) | 桥下河水的青绿色 |
| 底色 | #f3ece3 |
Paper Background | 宣纸/古籍的泛黄米色 |
| 卡片底色 | #fbf7f1 |
Card Background | 稍白的纸面 |
| 文字色 | #241b15 |
Ink Dark(墨黑) | 书法墨色 |
| 次文字色 | #665a50 |
Text Secondary | 褪色的墨色 |
2.2 在 ECharts 中的应用¶
ECharts 图表不使用官方默认色板,而是通过 chartTheme.js 统一配置:
export const chartTheme = {
bridgeBrown: "#6a4735", // 图表主色
riverBlue: "#4f7681", // 辅助色系
earthOrange: "#c57b3a", // 强调色
paperBg: "#f3ece3", // 图表背景
// 调色板:6 色有主次呼应
palette: ["#6a4735", "#c57b3a", "#4f7681", "#92745d", "#8f6241", "#7a8f91"],
// 色阶渐变(热力图/地图用)
ramp: ["#efe2d3", "#d9a36d", "#c57b3a", "#6a4735"],
// 坐标轴、分割线用透明度控制层次
axisLine: "rgba(106, 71, 53, 0.24)",
splitLine: "rgba(106, 71, 53, 0.12)",
// Tooltip 样式:古纸底色 + 暖色阴影
tooltipBg: "rgba(251, 247, 241, 0.96)",
};
所有图表组件(省域地图、散点图、桥型饼图、排名柱图、时期趋势图)共用这一套主题,统一了视觉语言。Tooltip 有 border-radius: 12px 和 box-shadow: 0 14px 30px rgba(63, 47, 34, 0.14) 的温暖阴影。
2.3 地图配色¶
ECharts 地图的配色也特别调过:
- 普通省份:
#f7eee2(暖纸色) - 鼠标悬停:
#e7d4be(加深的纸色) - 非激活省份:
#efe6da(更浅的静默色)
这样中国地图看起来不像蓝白色的"Google Maps 风格",而像一张旧纸上的舆图。
三、字体系统¶
3.1 书法字体¶
系统定义了一个 BridgeCalligraphy 字体族,按优先级依次尝试:
@font-face {
font-family: "BridgeCalligraphy";
src:
local("YuWeiShuFa"), local("禹卫书法"),
local("XianRenJianTi"), local("显仁简体"),
local("STXingkai"), local("华文行楷"),
local("FZShuTi"), local("方正舒体"),
local("STKaiti"), local("KaiTi");
font-display: swap;
}
这个字体用于首页 Hero 区的标题、大尺寸装饰文字等需要"手书感"的场景。优先检测用户系统是否已安装行楷/书法字体,层层降级到楷体,不额外加载网络字体文件。
3.2 正文字体¶
- 衬线字体(标题/引用):Noto Serif SC → STSong → SimSun(宋/宋体家族)
- 无衬线字体(正文/数据):Source Han Sans SC → Noto Sans SC → PingFang SC → Microsoft YaHei
这种衬线 + 无衬线的搭配让标题有"碑刻感",正文保持清晰可读。
四、界面质感层¶
4.1 多层渐变背景¶
系统中几乎所有的卡片和面板都不是纯色背景,而是多层渐变叠加:
/* AI 面板的背景 */
background:
linear-gradient(180deg, rgba(252, 248, 242, 0.98), rgba(241, 231, 218, 0.94)),
radial-gradient(circle at 100% 0%, rgba(79, 118, 129, 0.12), transparent 28%);
第一层是从上到下的微妙明暗渐变(模拟光照),第二层是右上角的微弱蓝绿色径向渐变(模拟环境光反射)。这种手法让卡片看起来像是有厚度和光泽的实体,而非贴在屏幕上的色块。
4.2 Surface 面板系统¶
CSS 中定义了多种 surface-* 类,对应不同的界面区域语义:
| 类名 | 用途 | 视觉特征 |
|---|---|---|
surface-arch |
建筑/结构类面板 | 暖纸底 + 细微纹理 |
surface-stele |
碑刻/档案类面板 | 石色底 + 内阴影 |
surface-analysis |
数据分析区域 | 清爽底 + 蓝调点缀 |
surface-culture |
文化/人文区域 | 暖调加深 |
surface-river |
水系相关区域 | 青蓝微渐变 |
surface-info |
信息/状态卡片 | 毛玻璃效果 |
4.3 "地形线"装饰纹理¶
多个面板类名中包含 terrain-lines 修饰符,这是一个 CSS 伪元素生成的装饰纹理——以极低透明度的细线模拟等高线/地形图效果,让空白区域不至于完全"死白"。
五、桥型图鉴¶
5.1 AI 生成的结构示意图¶
项目为 5 种古桥类型各制作了一张 AI 辅助生成的素描风格结构示意图(存放于 assets/bridge_ai/ 目录):
- 廊桥(屋桥合一)
- 拱桥(弧光跨越)
- 梁桥(平直秩序)
- 浮桥(顺势而为)
- 索桥(凌空虚位)
每张图的命名副标题都遵循"四字结构描述 + 副标题(力学主题 + 美学主题)"的格式,例如"拱桥:弧光跨越(力学结构与圆融美学)"。
5.2 结构化力学解读¶
每种桥型配有 3 条 structurePoints,从力学和美学两个维度解读该结构:
以拱桥为例:
- 拱券作为主要承重部件,其弧形轮廓直接决定了压力传导路径,形成了稳定而凝练的跨越体系。
- 桥身曲线与水面倒影交相辉映,勾勒出虚实相生的圆融轮廓,在加固桥体结构的同时,赋予建筑以极高的艺术审美价值。
- 拱石间的相互挤压与摩擦共同抵消重力,生动诠释了传统营造工艺中"以压代拉"的结构逻辑。
5.3 标注数智重构¶
底部统一标注:"数智重构:此示意图由 AI 辅助生成,以素描笔触解构古桥力学美学,供通识参考,非考古复原实证。"
这种透明标注既展示了 AI 的辅助能力,也划清了"数字化解读"与"考古实证"的边界。
六、交互微动效¶
6.1 AI 加载态¶
AI 回答的加载过程不是简单的 spinner,而是一整套多阶段动画:
- 脉冲核心(
ai-answer-pulse):一个渐变色圆点做呼吸式缩放 - 轨道环(
ai-answer-loading-orbit):两层圆环以不同延迟做缩放呼吸 - 骨架屏条(
loading-shimmer):三条不同宽度的条带做从左到右的扫光动画 - 阶段标签:文字提示当前处理进度("正在检索...""正在生成回答...")
这套加载动画传达的信息不只是"请等待",而是"系统正在认真处理你的问题"。
6.2 卡片悬浮交互¶
所有交互卡片统一了 hover 效果:
transition:
transform 0.2s ease,
border-color 0.2s ease,
box-shadow 0.2s ease;
&:hover {
transform: translateY(-2px);
border-color: rgba(61, 112, 128, 0.22);
box-shadow: 0 10px 24px rgba(61, 112, 128, 0.12);
}
上浮 2px + 边框变蓝绿 + 阴影扩散——微妙但一致。
6.3 AI 回答淡入¶
AI 生成的回答通过 ai-rich-answer-fade 动画从下方淡入:
@keyframes ai-rich-answer-fade {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
0.24 秒、4px 位移——刚好让用户感知到"这是刚生成的内容",不会因为太快而没注意到。
七、图片降级策略¶
BridgeImage.vue 组件(2.2KB)内建了图片加载失败的降级逻辑:
- 优先加载桥梁实景图片
- 如果图片 404 或加载超时 → 显示该桥类型对应的桥型轮廓占位图(从
bridgeTypeIllustrations.js中引用) - 如果连占位图也没有 → 显示一个通用的桥梁线稿占位
这保证了 100 座桥中即使有 n 张图片缺失,页面也不会出现白矩形。
八、设计复盘¶
做对的事¶
- 一开始就定色板:不是写完功能再"美化",而是从第一个组件开始就用
chartTheme.js里的颜色。这省去了后期统一风格的大量返工。 - Surface 语义类:用语义类名替代 ad-hoc 样式,让同类面板的视觉一致性自然达成。
- 字体降级链:不加载外部字体文件,利用用户系统已有的中文字体做层层降级,页面加载零延迟。
可以改进的¶
- CSS 体积:当前
styles.css有 8145 行(175KB),虽然 gzip 后很小,但维护成本高。如果项目继续演进,应该拆分为组件级样式。 - 自适应断点:当前的响应式主要靠
clamp()和少量媒体查询,平板端的体验还有优化空间。 - 暗色模式:色板是基于暖白底色设计的,没有做暗色模式支持。如果需要,需要重新定义一整套暗色变量。