Files
wechat_wc/docs/ui-overlay-components.md

185 lines
7.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.
# 智绘微刻小程序 - UI 覆层组件文档
本文档说明两个全局 UI 覆层能力:**顶部滚动遮罩(ScrollTopMask** 和 **自定义 Tab BarCustomTabBar**
---
## 一、顶部滚动遮罩 ScrollTopMask
### 作用
信息流页面上下滚动时,在页面顶部形成分层模糊 + 渐变透明遮罩:
- 上滑到大标题接近状态栏区域时遮罩淡入,状态栏时间/电量更清晰;
- 遮罩内水平居中显示当前页面标题,标题位于遮罩下 1/4 区域(`bottom: 38%`);
- 下拉回顶时按相同进度淡出;
- 大标题本身仍随页面自然滚动,不做吸顶/缩放/变色。
### 组件位置
```text
src/components/ScrollTopMask/
├── index.tsx # 组件逻辑
└── index.scss # 模糊层 / 渐变层 / 标题样式
```
### 使用方式
在任意页面的根 View`theme-*` 容器)内、`<ThemedPageMeta />` 之后放置:
```tsx
import ScrollTopMask from '../../components/ScrollTopMask'
<View className={`theme-${resolvedTheme}`}>
<ThemedPageMeta />
<ScrollTopMask title="页面标题" targetSelector=".page-header" />
{/* 页面内容 */}
</View>
```
> 二级页面(`src/pages/shop/detail`、`src/pages/diy/stickerEdit` 等)相对路径为 `../../../components/ScrollTopMask`。
二级页面开启返回按钮(`showBack`),遮罩随滚动淡入时,左上角会显示 `←` 返回按钮,点击回调 `Taro.navigateBack()`
```tsx
<ScrollTopMask title="商品详情" targetSelector=".page-header" showBack />
```
当前开启 `showBack` 的页面:商品详情、产品详情、设计工作台、贴纸编辑、结算、订单详情、收货地址、设置、AI 词云。
### Props
| Prop | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| `title` | `string` | 是 | - | 遮罩内居中显示的标题文本 |
| `targetSelector` | `string` | 否 | `.page-header` | 顶部测量节点,用于计算遮罩出现的滚动阈值 |
| `showBack` | `boolean` | 否 | `false` | 是否在遮罩左上方显示返回按钮(二级页面用) |
`targetSelector` 按页面页头选择:
| 页面 | title | targetSelector |
|---|---|---|
| 首页 `index` | 智绘微刻 | `.home-header` |
| 商品 `shop/index` | 智绘精选 | `.shop-header` |
| 设计清单 `designList` | 我的设计清单 | `.page-header.design-header` |
| 订单 `orders` | 我的订单 | `.orders-page .page-header` |
| 我的 `profile` | 我的 | `.profile-header` |
| 商品详情 `shop/detail` | 商品详情 | `.shop-back-btn` |
| 产品详情 `product` | 商品详情 | `.page-header` |
| 订单详情 `orderDetail` | 订单详情 | `.page-header` |
| 设计工作台 `diy` | 设计工作台 | `.page-header.surface-card` |
| 贴纸编辑 `diy/stickerEdit` | 编辑贴纸 | `.edit-header` |
| 结算 `checkout` | 设计效果确认 | `.page-header` |
| 收货地址 `address` | 收货地址 | `.page-header` |
| 设置 `settings` | 设置 | `.page-header.settings-header` |
| 客服 `service` | 联系客服 | `.page-header.service-header` |
| 定制协议 `agreement` | 定制协议 | `.agreement-title` |
| AI 词云 `wordcloud` | AI词云生成 | `.page-header.cloud-header` |
| 用户数据库 `userDatabase` | 本地用户数据库 | `.page-header.udb-header` |
### 实现原理
1. `useSafeArea()` 提供状态栏 / 胶囊按钮安全区;
2. `Taro.usePageScroll` 监听页面滚动(Taro 3 子组件可通过页面 Context 注册);
3. `createSelectorQuery().select(targetSelector)` 测量页头位置;
4. `getTopMaskStartY` 把「视口相对 bottom + 当前 scrollTop」换算成文档相对阈值,避免提前滚动导致阈值塌缩;
5. `getTopMaskProgress` 输出 0~1 遮罩进度,节流到定时器内更新;
6. 标题淡入使用二次映射:遮罩进度 0.5 后才开始出现。
### 视觉参数(当前值)
| 参数 | 值 | 位置 |
|---|---|---|
| 中模糊层 | `blur(12rpx)`,纵向淡出到 76% | `index.scss` |
| 弱模糊层 | `blur(6rpx)`,纵向淡出到 100% | `index.scss` |
| 渐变层高度 | mask 高度的 80% | `index.scss` |
| 渐变顶部不透明度 | `0.94` | `index.scss` |
| 渐变 50% 处 | `0.9` | `index.scss` |
| 渐变 78% 处 | `0.58`,之后到 0 | `index.scss` |
| 标题位置 | `bottom: 38%`,水平居中 | `index.scss` |
| 遮罩高度 | `max(menuButtonTop+menuButtonHeight+18, statusBarHeight+52) + 24(px)` | `index.tsx` |
### 注意事项
- 遮罩 `pointer-events: none`,不影响点击;二级页左侧返回按钮仍可操作;
- 多层 `backdrop-filter` + `mask-image` 真机兼容性需要实测,不支持的设备会退回纯渐变;
- 修改视觉参数只需改 `src/components/ScrollTopMask/index.scss`,无需逐页调整。
---
## 二、自定义 Tab Bar CustomTabBar
### 作用
微信自定义 tabBar,提供毛玻璃悬浮胶囊导航 + 浅色/深色主题自适应 + 路由切换联动。
### 组件位置
```text
src/custom-tab-bar/
├── index.json
├── index.tsx # tab 配置与切换逻辑
└── index.scss # 毛玻璃 / 渐变 / 主题样式
```
### 启用方式
`src/app.config.ts`
```ts
tabBar: {
custom: true,
list: [
{ pagePath: 'pages/index/index', text: '首页' },
{ pagePath: 'pages/shop/index', text: '商品' },
{ pagePath: 'pages/designList/index', text: '设计清单' },
{ pagePath: 'pages/orders/index', text: '订单' },
{ pagePath: 'pages/profile/index', text: '我的' }
]
}
```
### Tab 配置
`src/custom-tab-bar/index.tsx` 顶部 `TABS` 数组驱动渲染:
```ts
const TABS = [
{ pagePath: '/pages/index/index', label: '首页', icon: assetUrl('/icon/首页.svg'), iconActive: assetUrl('/icon/首页-fill.svg') },
// ...
]
```
新增/调整 Tab 时需要同时同步:
1. `TABS` 数组(label、pagePath、icon、iconActive);
2. `src/app.config.ts``pages``tabBar.list`
3. 对应图标资源。
### 核心行为
- 选中态由内部 `activeTab` state 维护(自定义 tabBar 不在 React Tree 内,不依赖路由自动感知);
- `switchTab` 调用 `Taro.switchTab` 并触发 `tabBarChange` 事件,页面内部也监听该事件同步选中态;
- 主题:监听 `THEME_CHANGE_EVENT` + 系统 `onThemeChange``auto` 跟随系统,并调用 `applyPageBackground` 兜底刷新页面背景;
- 样式:底部渐变托底 + 悬浮胶囊,`backdrop-filter: blur(32px) saturate(1.2)`,浅/深主题各自配色。
### 注意事项
- `z-index`:渐变托底 `999`,胶囊 `1000`,浮于页面内容之上;
- 自定义 tabBar 与顶部 ScrollTopMask 互不冲突(遮罩 z-index 40,位于胶囊之下的页面层级);
- 修改样式只需改 `src/custom-tab-bar/index.scss`
---
## 相关文件索引
| 文件 | 作用 |
|---|---|
| `src/components/ScrollTopMask/index.tsx` | 顶部遮罩组件逻辑 |
| `src/components/ScrollTopMask/index.scss` | 顶部遮罩视觉参数 |
| `src/custom-tab-bar/index.tsx` | 自定义 Tab Bar 逻辑与 Tab 配置 |
| `src/custom-tab-bar/index.scss` | 自定义 Tab Bar 样式 |
| `src/utils/homeTopMask.js` | 遮罩进度 / 阈值纯函数 |
| `tools/homeTopMask.test.mjs` | 遮罩纯函数单测 |
| `src/app.config.ts` | 页面路由与 tabBar 注册 |