微信小程序仿系统预览大图功能

问题:
微信小程序系统自带的 wx.previewImage 预览大图功能很好用,用起来很顺畅丝滑,但是有一个致命问题:预览大图的时候是在新页面中打开,当前页面的生命周期会销毁,如果当前页面中没有实时的东西还好,但如果有类似 <live_player> <live_push> <video> 等组件,或者有计时器之类的变量的时候,你会发现当前页面的这些组件或变量就没法使用了,如果想在当前页面下打开大图,那么就无法使用官方 wx.previewImage 这个方法,这是需要我们自定义一个大图预览组件。

扫一下体验效果:

两种预览大图方式:
1、系统方法:wx.previewImage
优点:系统自带,效果好,全屏,手势顺畅丝滑,使用方便简单
缺点:在新页面中打开,预览时会调用当前页面的生命周期onHide方法,会导致当前页面的变量无法使用,具体表现形式为:live_play 没有声音,暂停播放,倒计时无法继续计时等问题

1
2
3
4
wx.previewImage({
    current: imgUrl, // 当前显示图片的http链接
    urls: [imgUrl] // 需要预览的图片http链接列表
})

2、自定义组件:< previewImg >
优点:可解决 wx.previewImage 的致命缺点,调用后是在当前页面展示预览图,不会调用当前页面的生命周期方法,不会对当前页面逻辑造成影响
缺点:体验不如系统自带控件,无法隐藏胶囊,无法实现全屏。(如果想要全屏效果,只能设置当前页面的navigationStyle来控制隐藏navigationBar 达到全屏的效果)

使用:

.json:

1
2
3
"usingComponents": {
    "previewImg":"/components/previewImg/previewImg"
},
1
<previewImg id="previewComponent" previewImgList="{{imgList}}" previewImg="{{currentImg}}" />

openpreviewImg() {
this.selectComponent("#previewComponent").showPreview();
this.setData({
//imgList 图片地址数组
currentImg: this.data.imgList[0]
})
}

 

组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<view class="preview_box" wx:if="{{previewHideStatus}}" style="top:{{preview_box_top}}" catchtouchmove='stopPageScroll'>
  <view class="totalimg">{{imgindex}}/{{previewImgList.length}}</view>
  <view class="preview_box1" style="left:{{left}}" bindtap="jingzhi">
    <block wx:for="{{previewImgList}}" wx:key="key">
      <view class="img_box">
        <view bindtouchstart='touchStart' bindtouchmove='touchMove' bindtouchend='touchEnd'>
          <movable-area scale-area>
            <movable-view direction="all" animation catchscale="onScale" scale scale-min="1" scale-max="5" scale-value="{{scale}}">
              <image src="{{item}}" style="width:100%;" mode="widthFix"></image>
            </movable-view>
          </movable-area>
        </view>
      </view>
    </block>
  </view>
</view>

js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//最困难最核心的代码就是处理手指移动的位置和距离来对图片进行相应的操作
touchStart: function(e) {
      this.data.touchStartTime = e.timeStamp //时间点
      let sx = e.touches[0].pageX
      let sy = e.touches[0].pageY
      this.data.touchS = [sx, sy];
    },
 
    touchMove: function(e) {
      let start = this.data.touchS;
      let sx = e.touches[0].pageX;
      let sy = e.touches[0].pageY;
      this.data.touchE = [sx, sy];
    },
 
    touchEnd: function(e) {
      this.data.touchEndTime = e.timeStamp //时间点
      let start = this.data.touchS
      let end = this.data.touchE
      let scaleObj = this.data.scaleObj
      //如果((start[0] < end[0] - 50) && (scaleObj.scale==1&&scaleObj.x==0&&scaleObj.y==0)) //左滑动
      //如果((start[0] > end[0] + 50) && (scaleObj.scale==1&&scaleObj.x==0&&scaleObj.y==0)) //右滑动
      if (scaleObj.yes) {
        if (end[0] == 0) {
          console.log('点击')
        } else if ((start[0] < end[0] - 50) && (scaleObj.scale == 1 && scaleObj.x == 0 && scaleObj.y == 0)) {
          if (this.data.index !== 0) {
            this.data.index -= 1;
            this.data.imgindex -= 1;
            this.setData({
              index: this.data.index,
              left: '-' + this.data.index + '00%;transition: all .5s;',
              imgindex: this.data.imgindex
            });
          }
        } else if ((start[0] > end[0] + 50) && (scaleObj.scale == 1 && scaleObj.x == 0 && scaleObj.y == 0)) {
          if (this.data.index !== this.data.previewImgList.length - 1) {
            this.data.index += 1;
            this.data.imgindex += 1;
            this.setData({
              index: this.data.index,
              left: '-' + this.data.index + '00%;transition: all .5s;',
              imgindex: this.data.imgindex
            });
          }
        } else {
          console.log('下滑/上滑');
          this.setData({
            preview_box_top: '100%'
          })
        }
        this.data.touchE = [0, 0];
      }
 
      setTimeout(() => {
        if (this.data.scaleObj.x == 0 && this.data.scaleObj.y == 0 && this.data.scaleObj.scale == 1) {
          // console.log('yes is true');
          this.data.scaleObj.yes = true;
        }
      }, 500)
    }

  

 来源:https://blog.csdn.net/small_years/article/details/107316537

posted @   小小强学习网  阅读(485)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示