更新记录

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)

  1. 记录手指当前坐标 $F(x, y)$ 和起始角落坐标 $C(x, y)$。
  2. 计算线段 $FC$ 的垂直平分线,这条线就是物理世界中的 "折痕"
  3. 利用折痕将屏幕划分为两部分,计算出所有交点,生成两个多边形数组:
    • 平铺区多边形(留在原地的部分)
    • 翻折区多边形(被折起来的部分)

Step 2:DOM 裁切 (CSS)

获取到"平铺区多边形"的顶点坐标后,将其转化为 CSS 属性:

clip-path: polygon(x1 y1, x2 y2, x3 y3...);

视觉效果:当前页面的文字完全静止没有移动,但被折痕"切"掉了一个角,露出了位于底层的下一页。

Step 3:镜像与光影渲染 (Canvas)

  1. 将"翻折区多边形"沿着折痕做 1:1 的代数镜像反射,算出纸张背面在空中的坐标。
  2. 在 Canvas 中绘制这个反射后的多边形。
  3. 动态背景融合:先用书本的背景色(bgColor)铺底。
  4. 3D 光影遮罩:在这个多边形上叠加一层从 rgba(255,255,255,0.3)(高光)到 rgba(0,0,0,0.25)(暗角)的透明渐变。
  5. 绘制投射在底层页面上的窄阴影(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 引擎的丝滑翻页手感的原因。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。