Files
LoveChengke c7f215a09c feat(courseware,docs): 完善课件传输与岛编辑并统一全仓文档
- 增加课件上传、班级可见范围、设备补收与传输进度
- 整合自定义灵动岛编辑器和相关客户端交互
- 同步三端契约、数据库迁移、部署配置与隔离回归
- 按源码统一文档与官网说明,移除过时任务书和审查记录
- 保持产品版本为 1.4.0
2026-10-18 11:53:37 +08:00

100 lines
6.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 外观、主题与动效
description: 深浅色主题、界面风格、设计令牌与动效语言,以及降低动态效果的降级行为。
---
# 外观、主题与动效
## 深浅色主题
**两端都有深色主题,机制完全一致**:在 `<html>` 上挂 `.dark` 类,由各自的样式表覆盖**语义色令牌**,
Element Plus 的深色变量提供组件层的默认值。两端的 `main.ts` 都在挂载之前就把主题落好,
所以深色用户打开时不会"先白后黑"闪一下。
| 行为 | 说明 |
| ------------ | -------------------------------------------------------- |
| 默认 | **跟随系统**(`prefers-color-scheme`,系统改了就跟着变) |
| 手动切换之后 | 以用户的选择为准(系统的偏好是默认值,不是命令) |
| 切换入口 | 客户端在顶栏(日月按钮),Web 管理端也在顶栏 |
| 切换效果 | 从点击位置**扩散的圆**铺满整页换肤 |
**刻意不随主题的区域**:登录页的深色渐变底、桌面端的启动过渡页与全屏作业看板、灵动岛自身、
Web 管理端的侧边栏(本来就是深色),以及深色底上的白色文字。
Web 端还会同步 `<meta name="theme-color">`,并设 `color-scheme` 让**原生控件**
(滚动条、日期选择器弹层、自动填充底色)也跟着走 —— 只改 CSS 变量的话它们会仍是浅色。
## 语义色令牌
组件里**一律引用令牌,不写死颜色**:
| 令牌 | 用途 |
| ------------------------------------------------------ | -------- |
| `--ch-surface` / `-alt` / `-sunken` / `-hover` | 各种表面 |
| `--ch-text` / `-secondary` / `-muted` / `-placeholder` | 文字层级 |
| `--ch-radius-xl / lg / md / sm / pill` | 圆角 |
| `--ch-shadow-sm` / `-md` | 投影 |
`html.dark` **只覆盖颜色,绝不覆盖圆角与动效令牌** —— 两套主题的几何必须完全一致,
否则切换时会看到布局跳一下。
> 改令牌时**只改值**,不要对样式表跑批量替换。"把 `#303133` 全量替换成 `var(--ch-text)`"
> 会把令牌**定义本身**也换掉,自定义属性一旦自引用就整条失效、解析成空串,
> 全站文字颜色静默回落成继承色。
## 界面风格
- 浅色底 `#f3f3f3` + 半透明卡片(`rgba(255,255,255,.7)` + `backdrop-filter: blur(20px)`);
- 强调色 `#0F6CBD`(悬停 `#115EA3`);选中的导航项 = 强调色淡底 + 左侧 3px 强调条;
- 圆角统一:卡片 8px / 控件 4px;描边用半透明黑代替灰线;阴影极轻;
- 字体 `Segoe UI Variable / 微软雅黑 UI`;Element Plus 的变量整体对齐这套规范。
Web 管理端走的是另一套(1Panel 风格:深色侧边栏 + 白色圆角卡片),
圆角与投影集中定义在它的 `:root` 令牌里。
## 动效语言
两端的动画与过渡统一走一套自研的动效语言,**移植自 [beUI](https://beui.dev) 的 `lib/ease.ts`**。
beUI 的组件本身是 React,用不到这里,但它的动效语言与框架无关。
- **令牌单一来源**:`packages/shared/src/motion.ts`。三组缓动曲线 + 六组具名弹簧;
- **弹簧由数值积分算出落定时间**,再生成 CSS `linear()` 缓动字面量 ——
于是弹簧可以纯 CSS 驱动,不必给每个组件挂一个 rAF 循环;
- **运行时注入**:两端在挂载前把令牌写进 `:root` 的自定义属性。CSS 里只引用变量,不抄数值。
落地到界面上的效果:
| 位置 | 动效 |
| --------------------- | ------------------------------------------------------------------ |
| Element Plus 全站过渡 | 时长收紧到 200 / 140ms,缓动换成 EASE_OUT |
| 弹窗 / 抽屉 / 浮层 | 走弹簧;**退出一律比入场快**(用户已经决定关掉它了) |
| 按钮 | 按下 90ms 直落(跟手)、抬起弹回 |
| 侧栏激活项 | 单个"底片"在菜单项之间滑过去,取代"每项各画一块底色" |
| 页面内容 | 按块错峰浮现(30ms 一档,封顶 180ms) |
| 统计数字 | 0 → 实际值滚动 |
| 灵动岛 | **刻意只有单调缓动,不用弹簧**(任何过冲都会让"开合"看起来在震动) |
### 降低动态效果
两端各有一个 `prefers-reduced-motion` 的全局降级块,把动画压到 1ms ——
**是压短而不是删掉**(`transition: none` 会让依赖 `transitionend` 的逻辑失灵)。
主窗口中的例外是**加载指示旋**:它是放慢而不是停,停掉会让界面看起来像卡死。
灵动岛使用独立动画控制,应用内开关优先,具体见[灵动岛](island.md)。
## 客户端设置页
「设置」是可展开分组,常用子页如下;开发者模式还提供开发者页,自定义岛编辑为灵动岛子路由:
| 子页 | 内容 |
| ------ | ----------------------------------------------------------------------------- |
| 通用 | 服务器连接、离线缓存、作业录入短语、使用引导 |
| 外观 | 浅色 / 深色 |
| 灵动岛 | 尺寸、字号、主题色、视觉风格、停靠、边距、空闲细缝(详见[灵动岛](island.md)) |
| 提醒 | 本机课程等提醒开关与行为 |
| 账号 | 当前班级信息、退出登录 |
| 关于 | 版本 / Electron / Chromium / Node、诊断信息、检查更新、鸣谢 |
`/settings` 会自动跳到「通用」。设置页的改动会**立刻生效并写进本机配置**,重启后仍保留。