更新记录
1.0.2(2026-03-25) 下载此版本
优化翻页效果
1.0.1(2026-03-25) 下载此版本
加入canvas
1.0.0(2026-03-25) 下载此版本
init
查看更多平台兼容性
uni-app(3.7.2)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
uni-app x
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | × | × | × | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | × | √ |
📖 3D 仿真物理翻页引擎原理说明
1. 核心原理解析:是谁在驱动动画?
本翻页引擎抛弃了传统的"DOM 平移"或"纯 Canvas 绘制页面"的方案,采用了顶级阅读软件(如 Apple Books)的混合渲染架构。
它的核心由三个部分协同工作:
| 角色 | 技术 | 职责 |
|---|---|---|
| 🧠 大脑 | JS 纯数学几何引擎 | 负责计算物理折痕 |
| ✂️ 剪刀 | CSS clip-path |
负责隐藏被翻过去的文字 |
| 🎨 画笔 | Canvas API | 负责绘制翻过来的纸张背面和 3D 光影 |
为什么不全用 Canvas?
因为 Canvas 渲染复杂排版的文字(特别是跨端环境下的富文本、字体缩放、行距调整)非常困难且模糊。保留 DOM 层渲染文字,能保证文字的绝对清晰和原生排版能力。
为什么不全用 CSS?
CSS 的 3D 变换(transform: rotate3d)无法完美模拟纸张卷曲时的"圆柱体高光"和"折痕内阴影"。只有 Canvas 才能通过动态的多边形渐变(LinearGradient)画出极其逼真的光影。
2. 渲染流水线 (Render Pipeline)
当用户手指在屏幕上拖拽时,引擎会以 60FPS 的帧率执行以下流水线:
Step 1:几何计算 (JS)
- 记录手指当前坐标 $F(x, y)$ 和起始角落坐标 $C(x, y)$。
- 计算线段 $FC$ 的垂直平分线,这条线就是物理世界中的 "折痕"。
- 利用折痕将屏幕划分为两部分,计算出所有交点,生成两个多边形数组:
- 平铺区多边形(留在原地的部分)
- 翻折区多边形(被折起来的部分)
Step 2:DOM 裁切 (CSS)
获取到"平铺区多边形"的顶点坐标后,将其转化为 CSS 属性:
clip-path: polygon(x1 y1, x2 y2, x3 y3...);
视觉效果:当前页面的文字完全静止没有移动,但被折痕"切"掉了一个角,露出了位于底层的下一页。
Step 3:镜像与光影渲染 (Canvas)
- 将"翻折区多边形"沿着折痕做 1:1 的代数镜像反射,算出纸张背面在空中的坐标。
- 在 Canvas 中绘制这个反射后的多边形。
- 动态背景融合:先用书本的背景色(
bgColor)铺底。 - 3D 光影遮罩:在这个多边形上叠加一层从
rgba(255,255,255,0.3)(高光)到rgba(0,0,0,0.25)(暗角)的透明渐变。 - 绘制投射在底层页面上的窄阴影(40px 宽的渐变)。
3. 三大顶级物理仿真特性
为了让手感达到"原生 App 级别",引擎内部植入了三个关键的物理约束算法:
✨ 特性一:防撕书约束 (Anti-Tear Constraint)
在现实中,纸张的长度是固定的。如果你拉住右下角一直往左拉,折痕绝对不可能越过左侧的书脊,否则纸就被撕断了。
算法实现:以书脊为圆心,书本宽度 $W$ 为半径,画一个隐形的圆。如果手指坐标超出了这个圆,JS 会利用三角函数强制将手指坐标"拉回"到圆周上。
✨ 特性二:滞后透视算法 (Lag & Perspective)
如果纸张 1:1 跟着手指移动,看起来会像一张扁平的硬纸板。
算法实现:引入
curlRatio = 0.85。纸张的尖端只跟随手指 85% 的距离。这在绝对保持纸页直角为 90° 的前提下,让翻折面在视觉上变小了,完美模拟了纸张卷曲时的 3D 纵深感。
✨ 特性三:动量与回弹判定 (Momentum & Snap)
翻页不应该只看拖拽距离,还要看手指的加速度。
算法实现:
- 慢慢拖拽且距离
< 35%:判定为偷看,松手后平滑回弹。- 拖拽距离
> 35%:判定为翻页,触发飞出动画。- 拖拽距离小,但滑动速度极快(
velocity > 0.6):触发动量机制,瞬间顺滑翻页。
4. 边界消亡算法 (Boundary Extinction)
这是解决"回弹闪烁"和"飞出残留"的核心逻辑。
当折痕越过屏幕边缘时(多边形交点少于 2 个):
if (X 轴位移 > 屏幕宽度的一半):
判定纸张已飞出屏幕
CSS clip-path = polygon(0 0, 0 0, 0 0) → 彻底隐藏当前页
else:
判定纸张正在回弹到角落
CSS clip-path = none → 完全显示当前页
5. 总结
| 技术栈 | 负责模块 | 作用 |
|---|---|---|
| Vue (JS) | 状态管理、物理引擎、事件监听 | 大脑,每帧计算 2D 坐标、折痕、速度和约束 |
| CSS | clip-path 多边形遮罩 |
剪刀,切掉当前页,露出下一页,保持文字清晰 |
| Canvas | 2D 绘图 API(createLinearGradient) |
画笔,绘制翻折面、高光、阴影,提供立体感 |
这就是为什么这套代码既能保持纯原生 HTML 文字的极度清晰,又能拥有媲美 3D 引擎的丝滑翻页手感的原因。

收藏人数:
下载插件并导入HBuilderX
下载示例项目ZIP
赞赏(1)
下载 14
赞赏 1
下载 11846036
赞赏 1911
赞赏
京公网安备:11010802035340号