【山竹记账前端-react】18.自制日期选择器(下) 大纲链接 § [toc] 1. 一列变三列 ⇧ 提取单个日期栏组件到 DateTimeColumn.tsx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
【山竹记账】日期选择组件弹性动画分析
前言:一个日期滚轮,为什么不只是修改 translateY?
移动端的日期选择器通常由年、月、日三列组成。用户上下拖动某一列,数字跟随手指移动;拖过首项或末项时,列表还能被稍微拉出去,但越拉越费力;松手后,列表又弹回最近的合法选项。
看上去只是几个数字在移动,实际上需要同时处理四件事:
- 跟手:正常范围内,手指移动多少,列表就移动多少。
- 越界阻尼:超过首尾边界后,不突然卡住,也不无限移动。
- 离散吸附:松手时,选中项必须对齐到一整行,不能停在两项中间。
- 弹性过渡:从松手位置到目标项之间,有自然的回弹过程,而且可以被下一次手势打断。
本文结合山竹记账中的以下文件,拆解这套交互的实现:
| 文件 | 职责 |
|---|---|
src/components/form/DatePickerPopup.tsx |
组织年月日三列、生成选项、绘制遮罩和选中框 |
src/components/form/DateTimeColumn.tsx |
处理触摸生命周期、驱动动画、同步选中值 |
src/components/form/dateTimeColumnMotion.ts |
提供拖动、阻尼、索引计算三个纯函数 |
src/components/form/__test__/dateTimeColumnMotion.test.ts |
用 Vitest 验证核心数值规则 |
动画使用 @react-spring/web,当前项目中的版本是 10.1.2。本文代码与分析以当前实现为准,不把后文讨论的改进方向描述成已经完成的功能。
先给出全文最重要的结论:
拖动时的“阻力感”来自位移映射,松手后的“回弹感”来自弹簧动画。前者解决“显示在哪里”,后者解决“如何随时间到达目标”。两者不是同一件事。
【山竹记账前端-react】18.自制日期选择器(上)
【山竹记账前端-react】18.自制日期选择器(上) 大纲链接 § [toc] 1. 搞定输入面板的样式 ⇧ 数字面板的样式 ⇧ vscode多行文字内容包裹html
【山竹记账前端-react】17.Grid + Flex 布局实战
【山竹记账前端-react】17.Grid + Flex 布局实战 大纲链接 § [toc] 1. 记账页面 ⇧ 包括收入、支出tab切换 tab内容中的标签列表,添加标签按钮 输
【山竹记账前端-react】16.手机上的 bug
【山竹记账前端-react】16.手机上的 bug 大纲链接 § [toc] 手机调试 完成一个页面后就应该使用真手机查看 1. 手机调试步骤 ⇧ 1.1. 防火墙开启端口 ⇧ 搜索 windows 防
【山竹记账前端-react】14.无限加载列表
【山竹记账前端-react】14.无限加载列表 大纲链接 § [toc] 1. 无限加载的实现思路 ⇧ 访问 /items 页面,请求 /items?page=1 每次加载10项数据,返回 { resources: [], pager: {count: 10, per_page: 10, page:
【山竹记账前端-react】13.滑动菜单暗藏玄机
【山竹记账前端-react】13.滑动菜单暗藏玄机 大纲链接 § [toc] 1. 滑动菜单之样式制作 ⇧ @/components/FloatingOverlayMenu.tsx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import { MenuList } from "@/components/menu/MenuList" import { UserHeader }
【山竹记账前端-react】12.两种组件间通信的方式
【山竹记账前端-react】12.两种组件间通信的方式 大纲链接 § [toc] 1. 组件化有利有弊 ⇧ 组件化的缺点 使得每个组件模块自成一体,需要额外通信交流 一