跳转至

视觉设计系统:古纸水墨的数字化表达

本文是 主文章 的扩展阅读,聚焦于系统视觉语言的设计过程——如何用 CSS 和 ECharts 构建一套有古桥文化温度的数字界面。


一、设计目标

这个项目不是一个通用的数据可视化仪表盘。它展示的是中国古桥——一种有历史厚度、材料质感和文化记忆的实体遗产。视觉设计的目标是让用户在操作数据的同时,能感受到"一卷展开的古桥图谱"的氛围。

基于这个定位,我确定了三个设计准则:

  1. 温暖而非冰冷:不用蓝灰色系的"数据仪表盘"风格,而是用暖纸色、桥木褐、河川蓝构建色彩基调
  2. 有质感而非扁平:不追求纯粹的 Flat Design,而是通过多层渐变、阴影和玻璃拟态模拟"纸张叠放"的物理层次
  3. 克制而非花哨:动画和装饰服务于信息传达,不做"微信公众号"式的炫技风格

二、色彩体系

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 统一配置:

JavaScript
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: 12pxbox-shadow: 0 14px 30px rgba(63, 47, 34, 0.14) 的温暖阴影。

2.3 地图配色

ECharts 地图的配色也特别调过:

  • 普通省份:#f7eee2(暖纸色)
  • 鼠标悬停:#e7d4be(加深的纸色)
  • 非激活省份:#efe6da(更浅的静默色)

这样中国地图看起来不像蓝白色的"Google Maps 风格",而像一张旧纸上的舆图。


三、字体系统

3.1 书法字体

系统定义了一个 BridgeCalligraphy 字体族,按优先级依次尝试:

CSS
@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 多层渐变背景

系统中几乎所有的卡片和面板都不是纯色背景,而是多层渐变叠加:

CSS
/* 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 效果:

CSS
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 动画从下方淡入:

CSS
@keyframes ai-rich-answer-fade {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: translateY(0); }
}

0.24 秒、4px 位移——刚好让用户感知到"这是刚生成的内容",不会因为太快而没注意到。


七、图片降级策略

BridgeImage.vue 组件(2.2KB)内建了图片加载失败的降级逻辑:

  1. 优先加载桥梁实景图片
  2. 如果图片 404 或加载超时 → 显示该桥类型对应的桥型轮廓占位图(从 bridgeTypeIllustrations.js 中引用)
  3. 如果连占位图也没有 → 显示一个通用的桥梁线稿占位

这保证了 100 座桥中即使有 n 张图片缺失,页面也不会出现白矩形


八、设计复盘

做对的事

  1. 一开始就定色板:不是写完功能再"美化",而是从第一个组件开始就用 chartTheme.js 里的颜色。这省去了后期统一风格的大量返工。
  2. Surface 语义类:用语义类名替代 ad-hoc 样式,让同类面板的视觉一致性自然达成。
  3. 字体降级链:不加载外部字体文件,利用用户系统已有的中文字体做层层降级,页面加载零延迟。

可以改进的

  1. CSS 体积:当前 styles.css 有 8145 行(175KB),虽然 gzip 后很小,但维护成本高。如果项目继续演进,应该拆分为组件级样式。
  2. 自适应断点:当前的响应式主要靠 clamp() 和少量媒体查询,平板端的体验还有优化空间。
  3. 暗色模式:色板是基于暖白底色设计的,没有做暗色模式支持。如果需要,需要重新定义一整套暗色变量。