更新记录

1.0.0(2026-09-18)


平台兼容性

uni-app x(5.25)

Chrome Safari Android iOS 鸿蒙 微信小程序
- -

其他

多语言 暗黑模式 宽屏模式
× ×

st-page-flip-canvas

基于 StPageFlip 核心算法深度移植的 uni-app X 原生 Canvas 2D 3D 仿真翻书组件。
具备逼真的纸张弯曲物理效果、动态高光阴影以及顺滑的手势拖拽体验。


✨ 特性一览

  • 📖 仿真 3D 纸张物理形变:精确的纸张翻卷几何与光影计算,逼真模拟真实书本翻阅手感。
  • 原生 Canvas 2D 高效渲染:基于 uni-app X / UTS 开发,深度适配多端,高帧率平滑过渡。
  • 📐 确定性尺寸管线:支持外部容器显式尺寸传入与内部自动计算,彻底杜绝自适应导致的页面重排与闪烁。
  • 📱 多端手势体系适配
    • 内置原生 Touch/Mouse 手势支持(点击翻页、滑动翻页、拖拽卷角)。
    • 提供外部手势注入接口(startTouchmoveTouchendTouch),完美兼容微信小程序 Skyline 手势协商机制。
  • 🔄 智能图片增量更新:内置 URL 差异对比机制,在图片逐步下载、画质升级或按需加载时仅重绘变化页,避免整书重建导致重置回第 0 页。
  • 🖥️ 单双页自适应 (Spread Mode):支持移动端单页竖屏、桌面/平板双页并排横屏显示,支持封面 (Cover) 特殊渲染。

平台兼容性

App-Android App-iOS Web / H5 微信小程序 其他小程序
✅ 支持 ✅ 支持 ✅ 支持 ✅ 支持 (Canvas 2D) 需支持 Canvas 2D

提示:本组件专为 uni-app X 打造,编写语言为 .uvue.uts


快速上手

由于基于 uni_modules 规范开发,符合 easycom 自动导入机制,安装后在页面中直接使用 <st-page-flip-canvas> 标签即可。

基础示例

<template>
  <view class="container">
    <st-page-flip-canvas
      ref="flipRef"
      canvas-id="myBookCanvas"
      :images="imageList"
      :canvas-width="700"
      :canvas-height="500"
      :flipping-time="800"
      :show-cover="true"
      @flip="onPageFlip"
      @init="onBookInit"
    />

    <view class="controls">
      <button @click="prev">上一页</button>
      <button @click="next">下一页</button>
    </view>
  </view>
</template>

<script setup lang="uts">
import { ref } from 'vue'

const flipRef = ref<any | null>(null)

// 准备展示的图片列表(支持本地路径与网络路径)
const imageList = ref<string[]>([
  '/static/pages/cover.jpg',
  '/static/pages/page1.jpg',
  '/static/pages/page2.jpg',
  '/static/pages/page3.jpg',
  '/static/pages/back.jpg'
])

function onBookInit(data: any) {
  console.log('书本初始化完成:', data)
}

function onPageFlip(pageIndex: number) {
  console.log('当前页码变更:', pageIndex)
}

function prev() {
  flipRef.value?.flipPrev()
}

function next() {
  flipRef.value?.flipNext()
}
</script>

<style>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.controls {
  display: flex;
  flex-direction: row;
  margin-top: 20px;
  gap: 16px;
}
</style>

属性说明 (Props)

属性名 类型 默认值 必填 说明
images Array<string> [] 书本页面图片列表(网络 URL 或本地绝对路径)
canvasWidth Number 0 建议 画布展示区域的 CSS 逻辑宽度 (px)。设置后启用确定性尺寸管线
canvasHeight Number 0 建议 画布展示区域的 CSS 逻辑高度 (px)。设置后启用确定性尺寸管线
width Number 400 单页基准逻辑宽度(比例参考)
height Number 600 单页基准逻辑高度(比例参考)
spreadMode Number 0 每屏显示页数:0 自动判定,1 单页模式 (Portrait),2 双页展开模式 (Landscape)
startPage Number 0 起始页码(从 0 开始)
showCover Boolean false 是否启用硬皮封面模式(首尾两页单页显示且质感为硬壳)
flippingTime Number 1000 翻页平滑动画时长 (ms)
drawShadow Boolean true 是否绘制纸张翻转时的逼真阴影和背脊阴影
maxShadowOpacity Number 1 阴影最大透明度(范围 0 ~ 1,建议 0.3 ~ 0.5 观感更自然)
swipeDistance Number 30 触发滑动手势翻页的最小像素滑动阈值
showPageCorners Boolean true 鼠标/手势靠近书角时是否自动轻微翘起书角
disableFlipByClick Boolean false 是否禁用点击书本任意处直接翻页(设为 true 则仅能通过拖拽/滑动翻页)
autoSize Boolean true 是否自动缩放适配父容器尺寸
usePortrait Boolean true 是否允许自动切换到单页纵向显示
canvasId String 'stPageFlipCanvas' Canvas 组件 ID,页面中存在多个实例时请保持唯一

事件说明 (Events)

事件名 回调参数 说明
@init { page: number, mode: string } 画布及书本初始化完成时触发,返回当前页码和当前单双页模式
@flip pageIndex: number 页码发生翻页切换时触发,返回翻转后的当前页索引(从 0 开始)
@changeState state: string 翻页状态变更时触发。可选值:'read' (静止阅读), 'user_fold' (手动拖拽), 'fold_corner' (折角), 'flipping' (动画翻页中)
@changeOrientation orientation: string 书本排版方向变化时触发:'portrait' (单页), 'landscape' (双页)

实例方法 (Methods)

通过在组件上绑定 ref="flipRef" 即可调用内部提供的实例方法:

方法名 参数 说明
flipNext() (corner?: FlipCorner) 播放动画翻到下一页(可选触发角 FlipCorner.TOP / FlipCorner.BOTTOM
flipPrev() (corner?: FlipCorner) 播放动画翻到上一页
turnToPage(page) page: number 立即跳转到指定页(无翻页过渡动画)
startTouch(x, y) x: number, y: number 外部注入手势开始事件(用于对接微信小程序 Worklet 等手势组件)
moveTouch(x, y) x: number, y: number 外部注入手势移动事件
endTouch(x, y, isSwipe) x: number, y: number, isSwipe: boolean 外部注入手势抬起/结束事件

进阶:高级手势对接(微信小程序 Skyline)

在微信小程序中,如需配合 <horizontal-drag-gesture-handler> 进行手势冲突管理,可结合组件暴露的方法使用:

<horizontal-drag-gesture-handler
  tag="flipGesture"
  worklet:ongesture="onFlipGesture"
>
  <st-page-flip-canvas
    ref="flipRef"
    canvas-id="flipCanvas"
    :images="images"
    :canvas-width="canvasWidth"
    :canvas-height="canvasHeight"
    :disable-flip-by-click="true"
    @flip="onFlip"
  />
</horizontal-drag-gesture-handler>

注意事项

  1. 网络图片跨域:在 Web / 小程序端加载网络图片时,需确保图片 CDN 开启了 CORS 跨域头,小程序端需配置合法域名。
  2. 尺寸测量:推荐使用 :canvas-width:canvas-height 传入确切的像素尺寸(可根据屏幕宽高在页面 onReady 时计算出保持书本宽高比的尺寸),避免异步测量导致的视觉抖动。

隐私、权限声明

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

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

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

暂无用户评论。