uni.previewImage本身不支持平滑缩放,仅提供基础缩放且无动画过渡;必须手动封装touch事件,用transform: scale() + translate()配合动态transform-origin和requestAnimationFrame实现平滑缩放。

uni.previewImage 本身不支持平滑缩放,必须手动封装
uni.previewImage 是原生调起的系统预览器,iOS 和安卓 WebView 默认禁用手势缩放(双指放大/拖拽),这不是 bug,而是 WebView 安全策略限制。它只提供左右滑动和基础缩放(部分平台点两下放大,但无动画、无平滑过渡)。真要「平滑缩放」,就得自己写基于 touchstart/touchmove/touchend 的 canvas 或 image 缩放逻辑,用 transform: scale() + translate() 配合 requestAnimationFrame 实现帧率可控的动画效果。
常见错误现象:直接在 <image> 上加 @touchmove 却没阻止默认行为,导致页面滚动干扰;或未动态计算缩放中心点(两指中点),放大后图片偏移严重。
- 缩放中心必须是两指当前中点位置,不是屏幕中心 —— 要用
getBoundingClientRect()算相对坐标再更新transform-origin - 单指移动时只做
translate,双指距离变化才驱动scale,且需记录上一次距离用于 delta 计算 - 最大缩放建议限制在 3x 以内,避免 canvas 渲染模糊或内存溢出(尤其安卓低端机)
- 缩放后若要保存,不能直接截原图,得用
canvas.drawImage按当前 scale/translate 坐标重绘到新 canvas 再导出
多图预览必须传 urls 数组,current 只能是数字索引
很多人以为点哪张就传哪张 URL 进去,结果只能看一张、无法滑动 —— uni.previewImage 的 urls 是必填项,哪怕只预览单图也得写成 urls: [singleUrl],current 必须是数组索引(如 0),不能是字符串 URL。传字符串会触发遍历匹配,大小写、query 参数差异(如 ?v=1 vs ?v=2)都会导致定位失败,预览器直接跳首图。
使用场景:九宫格点击、列表页图片卡片、用户相册页。若数据来自分页或搜索过滤,注意 index 是渲染时的局部索引,要映射回全局图片数组下标,否则滑动后 current 错乱。
- 服务端返回的图片列表务必提前过滤掉
null、undefined、空字符串、视频地址 - 微信小程序不支持临时路径(
tempFilePath)直传urls,必须先上传或转 base64(加前缀data:image/png;base64,) - H5 支持本地路径(如
/static/xxx.jpg),但 App 端对file://或_www/路径更稳定
长按保存必须走 longPressActions,不能绑 @longpress
在 <image> 标签上写 @longpress="saveImg" 在微信小程序里完全无效 —— 小程序禁止对 <image> 直接绑定长按事件。唯一可靠方式是通过 uni.previewImage 的 longPressActions 配置项触发菜单,且仅微信小程序支持该配置,H5 和 App 端不识别。
保存前必须先 uni.downloadFile,不能直接传网络 URL 给 uni.saveImageToPhotosAlbum。微信小程序会报错 fail errCode: -1,因为相册 API 要求的是本地临时路径。
-
longPressActions.success回调里的res.tapIndex是菜单点击序号(从 0 开始),res.index是当前预览图在urls中的真实索引(非传入的current,因用户可能已滑动) - 下载前建议校验
res.index是否有效,防止越界取this.imgList[res.index] - 下载失败要提示用户检查网络或图片地址,而不是静默失败
- H5 端不支持
uni.saveImageToPhotosAlbum,可降级为a[href].download触发浏览器下载
loop 和 indicator 不跨端一致,别依赖默认配置
loop: true 在 H5 端不生效,部分安卓 App 滑到末尾再划会卡顿;indicator: 'number' 在微信小程序显示 “1/3”,H5 端压根不显示。这不是 bug,是各端原生组件能力差异。如果你需要全端统一指示器,别用 indicator,改用自定义悬浮层 + 监听 uni.onPreviewImageChange(仅 App 支持),或放弃 indicator、靠用户滑动直觉判断。
性能影响:开启 loop 后,某些安卓 WebView 会因边界检测逻辑增加渲染开销,导致滑动卡顿,尤其图片尺寸 > 2000px 宽时更明显。
- 多图预览前建议用
uni.getImageInfo对关键图片做轻量校验(非必须,但高可用场景值得加) - 图片尺寸过大(如原图 4000×3000)会导致预览加载慢、缩放卡顿,建议服务端返回适配预览尺寸的缩略图 URL(如
xxx.jpg?imageView2/2/w/1200/h/800) - 如果用了自定义缩放器,
urls数组里每张图都要支持独立缩放状态管理,不能共用同一套scale/translate值


















