【问题】
桌面端(Electron)切换主题时颜色变化速度不一致、明显卡顿。
根因分析(4 轮迭代):
1. 过渡时长不统一(body 0.3s / 组件 0.15s)→ 统一到 0.2s
2. antd CSS-in-JS 标签替换导致瞬间变色 → 尝试 cssVar(无效,仍走标签替换)
3. applyHtmlTheme 在 updater 回调中执行,与 antd CSS 变更不同帧 → 移入 useLayoutEffect
4. html * 全局过渡在 Electron 中为数千 DOM 节点同步插值 → 合成器掉帧
终极方案:View Transitions API(GPU 合成器 1 次 cross-fade 替代 N 个 CSS 过渡)
+ 精准 CSS 过渡覆盖 ~80 个 antd 容器类(回退方案)
【修改】
ThemeProvider.tsx — 核心重构
- applyHtmlTheme 从 setIsDark updater → useLayoutEffect([isDark])
确保自定义 CSS 变量与 antd CSS-in-JS 在同一次 React 提交中生效
- View Transitions API:document.startViewTransition + flushSync
GPU 合成器截取旧/新两帧做单次 cross-fade,消除多元素插值卡顿
- 浏览器不支持时自动回退到 CSS transition 方案
globals.css — 过渡策略
- body: 0.3s ease → 0.15s linear
- View Transitions 动画:::view-transition-old/new(root) 0.15s linear
- ~80 个 antd 容器类精准过渡(Layout/Card/Modal/Table/Input/
Select/Picker/Menu/Tabs/Tag/Alert/Empty/Result/Skeleton 等)
按功能分组:布局 → 表格 → 表单 → 导航 → 反馈
不覆盖交互组件自有 transition(Button/Switch/Slider 等)
linear 替代 ease — 匀速插值,桌面应用更利落
Layout.tsx / HomeContent.tsx / LeftPanel.tsx / ModelSelector.tsx
- 过渡参数对齐:全部 0.2s → 0.15s linear
SettingsPage.tsx — 用户体验
- Modal 取消 keyboard={false},Esc 键可关闭
- macOS:关闭按钮移至标题左侧(遵循 macOS HIG)
- afterClose 中 blur 当前焦点元素,防止聚焦跳到导航栏
【文档】
CHANGELOG.md — 新增 0.0.15 版本记录
CLAUDE.md — 新增主题系统架构章节(双轨颜色体系 / 时序 / 过渡策略)
119 lines
4.0 KiB
JSON
119 lines
4.0 KiB
JSON
{
|
|
"name": "ele-heixiu",
|
|
"private": true,
|
|
"version": "0.0.14",
|
|
"description": "船长·HeiXiu — 桌面效率工作台",
|
|
"author": "HeiXiu 杨烨",
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "chcp 65001 > null && cross-env ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ vite",
|
|
"build": "node build.mjs --win --personal --build",
|
|
"build:win": "node build.mjs --win --personal --build",
|
|
"build:win:enterprise": "node build.mjs --win --enterprise --build",
|
|
"build:mac": "node build.mjs --mac --personal --build",
|
|
"build:mac:enterprise": "node build.mjs --mac --enterprise --build",
|
|
"build:linux": "node build.mjs --linux --personal --build",
|
|
"build:linux:enterprise": "node build.mjs --linux --enterprise --build",
|
|
"build:clean": "node scripts/clean.mjs",
|
|
"upload:oss": "node scripts/upload-oss.mjs",
|
|
"publish:release": "node scripts/publish-release.mjs",
|
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
"preview": "vite preview",
|
|
"format": "prettier --write \"src/**/*.{ts,tsx,css}\" \"electron/**/*.ts\" \"shared/**/*.ts\"",
|
|
"format:check": "prettier --check \"src/**/*.{ts,tsx,css}\" \"electron/**/*.ts\" \"shared/**/*.ts\"",
|
|
"test": "vitest run",
|
|
"test:watch": "vitest",
|
|
"test:e2e": "playwright test.json"
|
|
},
|
|
"dependencies": {
|
|
"@react-buddy/ide-toolbox": "^2.5.0",
|
|
"antd": "^6.4.3",
|
|
"axios": "^1.16.1",
|
|
"electron-updater": "^6.8.3",
|
|
"react": "^19.2.7",
|
|
"react-dom": "^19.2.7"
|
|
},
|
|
"build": {
|
|
"appId": "com.heixiu.electron",
|
|
"productName": "船长·HeiXiu",
|
|
"asar": true,
|
|
"directories": {
|
|
"output": "release/${version}"
|
|
},
|
|
"files": [
|
|
"dist",
|
|
"dist-electron"
|
|
],
|
|
"electronDownload": {
|
|
"mirror": "https://npmmirror.com/mirrors/electron/"
|
|
},
|
|
"publish": {
|
|
"provider": "generic",
|
|
"url": "https://update.heixiu.com"
|
|
},
|
|
"win": {
|
|
"icon": "src/assets/logo/heixiu.ico",
|
|
"target": [
|
|
{
|
|
"target": "NSIS",
|
|
"arch": [
|
|
"x64"
|
|
]
|
|
}
|
|
],
|
|
"artifactName": "${productName}-Windows-${version}-${env.EDITION}-Setup.${ext}"
|
|
},
|
|
"mac": {
|
|
"icon": "src/assets/logo/heixiu.icns",
|
|
"target": [
|
|
"dmg"
|
|
],
|
|
"artifactName": "${productName}-Mac-${version}-${env.EDITION}-Installer.${ext}"
|
|
},
|
|
"linux": {
|
|
"icon": "src/assets/logo/HX.png",
|
|
"target": [
|
|
"AppImage"
|
|
],
|
|
"artifactName": "${productName}-Linux-${version}-${env.EDITION}.${ext}"
|
|
},
|
|
"nsis": {
|
|
"oneClick": false,
|
|
"perMachine": false,
|
|
"allowToChangeInstallationDirectory": true,
|
|
"deleteAppDataOnUninstall": false,
|
|
"differentialPackage": true,
|
|
"installerIcon": "src/assets/logo/heixiu.ico",
|
|
"uninstallerIcon": "src/assets/logo/heixiu.ico"
|
|
}
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "^1.60.0",
|
|
"@tailwindcss/vite": "^4.3.0",
|
|
"@types/electron": "^1.4.38",
|
|
"@types/node": "^25.9.1",
|
|
"@types/react": "^19.2.16",
|
|
"@types/react-dom": "^19.2.3",
|
|
"@typescript-eslint/eslint-plugin": "^8.60.1",
|
|
"@typescript-eslint/parser": "^8.60.1",
|
|
"@vitejs/plugin-react": "^6.0.0",
|
|
"autoprefixer": "^10.5.0",
|
|
"cross-env": "^10.1.0",
|
|
"electron": "42.3.0",
|
|
"electron-builder": "^26.8.1",
|
|
"eslint": "^10.4.1",
|
|
"eslint-config-prettier": "^10.1.8",
|
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
"eslint-plugin-react-refresh": "^0.5.2",
|
|
"postcss": "^8.5.15",
|
|
"prettier": "^3.8.3",
|
|
"rollup-plugin-visualizer": "^7.0.1",
|
|
"tailwindcss": "^4.3.0",
|
|
"typescript": "^6.0.3",
|
|
"vite": "8.0.16",
|
|
"vite-plugin-electron": "^1.0.0",
|
|
"vite-plugin-electron-renderer": "^1.0.0"
|
|
},
|
|
"main": "dist-electron/main.js"
|
|
}
|