微信小程序用swiper 和 movable-view实现wx.previewImage功能

注:7.13号写的残缺版,7.14号写出来了完整版来了,最终代码贴文章最下边了 相对于13号代码只改了html和js,和一个app.js中的节流方法。

---------------------------------------------------------------------------------------------------------------------------------

7.13号写的-------1、需求原因:在播放的音频文件中调用wx.previewImage查看图片时会中止语音- -测试不让(怒起杀狗心),只能用swiper 和 movable-view来模拟。最终实现效果残缺,暂时只能实现将图片缩小回1倍大小后再允许执行swiper滑动。原因过程接着看。

13号效果(必须缩回一倍才能用轮播图):

24

2、调试过程 简单的把movable-area和movable-view嵌入进swiper,此时效果如下,swiper的滑动和缩放功能的拖动会同时触发,显然这样的效果是不行的。

<swiper class="swiper" indicator-dots="{{true}}"   indicator-color="rgb(247, 247, 247,1)" 	indicator-active-color="#1bb7b5">
    <swiper-item class="swiper-item" wx:for="{{imgList}}" data-index="index" wx:key="index"> 
      <movable-area class="moswiper1" scale-area>
        <movable-view class="moswiper2" direction="all" out-of-bounds scale scale-min="1" scale-max="4"  scale-value="1">
          <view class="swiper-view" >
            <image mode="widthFix" src="{{item}}"></image>
          </view>
          </movable-view>
      </movable-area>    
  </swiper-item>
</swiper>

10

 3、这个时候考虑到既然放大后swiper滑动会触发 ,在js方法中添加放大事件监听放大倍数和html 中添加三元表达式若是放大了图片那就禁止轮播图滑动

 catchtouchmove="{{amplification>1?'任意字符别问我为啥随便打个字他就好使' : ''}}"

<swiper class="swiper" indicator-dots="{{true}}"   indicator-color="rgb(247, 247, 247,1)" 	indicator-active-color="#1bb7b5">
    <swiper-item class="swiper-item" wx:for="{{imgList}}" data-index="index" wx:key="index"  catchtouchmove="{{amplification>1?'slideshow' : ''}}"> 
      <movable-area class="moswiper1" scale-area>
        <movable-view class="moswiper2" direction="all" out-of-bounds scale scale-min="1" scale-max="4"  scale-value="1">
          <view class="swiper-view" >
            <image mode="widthFix" src="{{item}}"></image>
          </view>
          </movable-view>
      </movable-area>    
  </swiper-item>
</swiper>


js
amplification:1 ,  //放大倍数

movableScale(e){//放大事件,只要图片放大就给轮播图禁止了
      console.log('放大倍数=====>',e.detail);
      this.setData(({
        amplification:e.detail.scale
      }))
}

4、如上基本是没问题了但是会触发小bug,比如用一根手指先滑动轮播图到一半,然后第二根手机放上缩放可以触发,这样翻过去的话因为amplification>1了,所以滑不回来了。

5、不一层层细写了在这说一下之后的逻辑,直接出最终代码。如上问题我又加了swiper的bindchange事件 只要划过去了就设置amplification=1 ,发现虽然能滑了但是轮播图变畸形了,第一张大第二张小,之前的amplification有用又 仿佛无用。最后我添加了位移事件 只要轮播图移动开始就禁止缩放,和轮播图移动结束事件 结束了就允许滑动。

上最终代码、效果

①、html    我这里之前设置的横屏竖屏事件,然后横屏那一段代码没有写放大拖动这些事件

<match-media orientation="portrait" bindtap="close" class="preview-img-mask" wx:if="{{imgList!=0}}">
  <swiper class="swiper" indicator-dots="{{true}}"   indicator-color="rgb(247, 247, 247,1)" 	indicator-active-color="#1bb7b5" bindchange='onChange' bindtransition='alter' bindanimationfinish='finish'>
    <swiper-item class="swiper-item" wx:for="{{imgList}}" data-index="index" wx:key="index" catchtouchmove="{{amplification>1?'slideshow' : ''}}"> 
      <movable-area class="moswiper1" scale-area>
        <movable-view class="moswiper2" direction="all" out-of-bounds scale scale-min="1" scale-max="4" scale="{{!isstop}}" scale-value="1" bindscale="movableScale">
          <view class="swiper-view" catchtap="nothing">
            <image mode="widthFix" src="{{item}}"></image>
          </view>
          </movable-view>
      </movable-area>    
  </swiper-item>
  </swiper>


</match-media>
<match-media orientation="landscape" bindtap="close" class="preview-img-mask" wx:if="{{imgList!=0}}">
  <swiper class="swiper1" indicator-dots="{{true}}"   indicator-color="rgb(247, 247, 247,1)" 	indicator-active-color="#1bb7b5" bindtransition='onChange'>
  <swiper-item class="swiper-item1" wx:for="{{imgList}}" data-index="index" wx:key="index">
  <view class="swiper-view1" catchtap="nothing">
    <image show-menu-by-longpress src="{{item}}"></image>
  </view>
  </swiper-item>
  </swiper>
</match-media>

②、js    我是写在了组件里,可以自己cv出去自己需要的部分,properties放自己的data里面就行了

// 我这里是个组件
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    imgList:{
      value:[],
      type:Array
    },
    
  },
  /**
   * 组件的初始数据
   */
  data: {
    
    swiperIndex: 0,  // 第一次加载默认第一张图片选中
    amplification:1 ,  //放大倍数
    iscurrent:0  ,     //当前在哪一张
    isdx:'',          //记录x
    isdy:'',          //记录y
    isstop:false,        //禁止缩放
  },

  /**
   * 组件的方法列表
   */
  methods: {
    close(){
      // debugger
      this.triggerEvent("close")
    },
    onChange(e){                       //如果不加这个方法那放大和滑动屏幕如果同时触发了
      let current = e.detail.current      //那因为此时amplification可能大于设定值将不可滑动
      if (current != this.data.iscurrent) {
        // console.log('只要图片改变了,就可以滑动~~~~');
        this.setData({
          amplification:1,
        })

      }
      this.setData({iscurrent:current})
    },
    alter(e){  //swiper位移事件
      let [dx, dy] = [e.detail.dx,e.detail.dy];
      this.setData({
        isdx:dx,
        isdy:dy
      })
      //这个>10是因为手指触碰时会被轻微的滑动影响到而造成不能缩放
      if (this.data.isdx>10 || this.data.isdy>10) {  
        // console.log('说明有位移操作,此时禁止缩放~~');
        this.setData({
          isstop:true
        })
      }else{
        //否则允许缩放
        this.setData({
          isstop:false
        })
      }
    },
    finish(e){  //轮播图移动完毕事件
      this.setData({
        isdx:0,      //xy每一次跳转完毕赋值0  给下面重新判断用,并且允许新页面缩放
        isdy:0,
        isstop:false
      })
  },
    nothing(e){
      console.log(e);   
    },    
    movableScale(e){//放大事件,只要图片放大就给轮播图禁止了
      console.log('放大倍数=====>',e.detail);
      this.setData(({
        amplification:e.detail.scale
      }))
    }
  }
})

③、css

.preview-img-mask{
  position: fixed !important;
  background-color: #000000;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.swiper-item{
  display: flex;
  align-items: center;
  justify-content: center;
}
.swiper{
  width: 100%;
  height: 90%;
  /* display: flex;
  justify-content: center;
  align-items: center; */
}
.swiper-view{
  width: 100%;
}
.swiper-view image{
  width: 100%;
}

.swiper-item1{
  display: flex;
  align-items: center;
  justify-content: center;
}
.swiper1{
  width: 90%;
  height: 100%;
}
.swiper-view1{
  width: 100%;
  height: 100%;
}
.swiper-view1 image{
  width: 100%;
  height: 100%;
}
.moswiper1{
  width: 99%;
  height: 420rpx;
}
.moswiper2{
  width: 100%;
  height: 100%;
}

-------------------------------------------------------------------------------------------------------------------------------

7.14号  完整版,加了监听移动画布事件,通过监听x轴与上一次的坐标位置大小关系确定左右移动,再监听触到边界if (e.detail.source == "out-of-bounds" || e.detail.source == "touch-out-of-bounds") 的这个字段,确定是左还是右触碰到边界,然后动态修改轮播图的下标完成,虽然有一点小瑕疵  大家多测试就会发现了,但是整体功能是实现的。小瑕疵捣鼓了两三个小时没捣鼓好 烦躁了。。。。。先把代码贴这里吧。

<match-media orientation="portrait" bindtap="close" class="preview-img-mask" wx:if="{{imgList!=0}}">
  <swiper class="swiper" indicator-dots="{{true}}"   indicator-color="rgb(247, 247, 247,1)" 	indicator-active-color="#1bb7b5" bindchange='onChange' bindtransition='alter' bindanimationfinish='finish' current="{{current}}">
    <swiper-item class="swiper-item" wx:for="{{imgList}}" data-index="index" wx:key="index" catchtouchmove="{{amplification>1?'slideshow' : ''}}"> 
      <movable-area class="moswiper1" scale-area>
        <movable-view class="moswiper2" direction="all" out-of-bounds damping="999" scale scale-min="1" scale-max="4" scale="{{!isstop}}" scale-value="{{suofang}}" bindscale="movableScale" bindchange="slideChange">
          <view class="swiper-view" catchtap="nothing">
            <image mode="widthFix" src="{{item}}"></image>
          </view>
          </movable-view>
      </movable-area>    
  </swiper-item>
  </swiper>


</match-media>
<match-media orientation="landscape" bindtap="close" class="preview-img-mask" wx:if="{{imgList!=0}}">
  <swiper class="swiper1" indicator-dots="{{true}}"   indicator-color="rgb(247, 247, 247,1)" 	indicator-active-color="#1bb7b5" bindtransition='onChange'>
  <swiper-item class="swiper-item1" wx:for="{{imgList}}" data-index="index" wx:key="index">
  <view class="swiper-view1" catchtap="nothing">
    <image show-menu-by-longpress src="{{item}}"></image>
  </view>
  </swiper-item>
  </swiper>
</match-media>

js

// component/previewImg/previewImg.js
const app = getApp();
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    imgList:{
      value:[],
      type:Array
    },
    
  },
  /**
   * 组件的初始数据
   */
  data: {
    
    swiperIndex: 0,  // 第一次加载默认第一张图片选中
    amplification:1 ,  //放大倍数
    iscurrent:0  ,     //当前在哪一张
    isdx:'',          //记录缩放x
    isdy:'',          //记录缩放y
    isstop:false,        //禁止缩放
    current:0 ,       //哪一个
    suofang:1,       //缩放倍数
    x_axis:0,     //x轴坐标
  },

  /**
   * 组件的方法列表
   */
  methods: {
    close(){
      // debugger
      this.triggerEvent("close")
    },
    onChange(e){                       //如果不加这个方法那放大和滑动屏幕如果同时触发了
      let current = e.detail.current      //那因为此时amplification可能大于设定值将不可滑动
      console.log('current',e.detail);
      this.setData({
        current:current
      })
      if (current != this.data.iscurrent) {
        // console.log('只要图片改变了,就可以滑动~~~~');
        this.setData({
          amplification:1,
        })

      }
      this.setData({iscurrent:current})
    },
    alter(e){  //swiper位移事件
      let [dx, dy] = [e.detail.dx,e.detail.dy];
      this.setData({
        isdx:dx,
        isdy:dy
      })
      //这个>10是因为手指触碰时会被轻微的滑动影响到而造成不能缩放
      if (this.data.isdx>10 || this.data.isdy>10) {  
        // console.log('说明有位移操作,此时禁止缩放~~');
        this.setData({
          isstop:true
        })
      }else{
        //否则允许缩放
        this.setData({
          isstop:false
        })
      }
    },
    finish(e){  //轮播图移动完毕事件
      console.log(e);
      this.setData({
        isdx:0,      //xy每一次跳转完毕赋值0  给下面重新判断用,并且允许新页面缩放
        isdy:0,
        isstop:false,    //允许缩放
        suofang:1,       //缩放回1倍
      })
  },
    nothing(e){
      console.log(e);   
    },    
    movableScale(e){//放大事件,只要图片放大就给轮播图禁止了
      // console.log('放大倍数=====>',e.detail);
      this.setData(({
        amplification:e.detail.scale,
      }))
    },
    //如果x越来越小就是往右,越来越大就是往左移动
    slideChange: app.throttle(function(e){
      if (this.data.amplification<1.1) {
        console.log('没放大不走拖动换页那一套~');
      }else{

    
      console.log('movable-view滑动事件====>',e.detail);
      let xzhi = this.data.x_axis
      console.log('之前的x轴位置====>',xzhi);
      let x = e.detail.x       //当前的x坐标轴-610 与 以前的x坐标轴对比-609
      let xdang1 = x-5
      let xdang2 = x+5
      if (x > this.data.x_axis) {   //如果x轴坐标大于上次记录的
        this.setData({x_axis:xdang2})
        console.log('图片是左移');
        if (e.detail.source == "out-of-bounds" || e.detail.source == "touch-out-of-bounds") {
          console.log('触碰到左左左边界了=====>');
          if (this.data.current>0) {     
            this.setData({
              // amplification:1,
              current:this.data.current-1
            })
          }else{
            this.setData({
              current:0
            })
          }
        }
      }else{  //x < this.data.x_axis
        this.setData({x_axis:xdang1})
        console.log('图片右移右移~~');
        if (e.detail.source == "out-of-bounds" || e.detail.source == "touch-out-of-bounds") {
          console.log('触碰到右边界了=====>');
          if (this.data.current < this.properties.imgList.length-1) {
            this.setData({
              current:this.data.current+1
            })
          }else{
            this.setData({
              current:this.data.current
            })
          }
        }
      }
    }
    },800),
    
  
  }
})

app.js中一个节流方法,不加的话触碰到边界的时候出来100个触碰结果

throttle(fn, interval) {  //节流
    var enterTime = 0;//触发的时间
    var gapTime = interval || 300 ;//间隔时间,如果interval不传,则默认300ms
    return function() {
      var context = this;
      var backTime = new Date();//第一次函数return即触发的时间
      if (backTime - enterTime > gapTime) {
        fn.call(context,arguments[0]);
        enterTime = backTime;//赋值给第一次触发的时间,这样就保存了第二次触发的时间
      }
    };
  },

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
是的,可以使用swiper和scroll-view组件来实现微信小程序的左右分页功能。 首先,在wxml文件中添加swiper和scroll-view组件,并设置相应的属性。 ```html <swiper class="swiper-container" current="{{current}}" duration="{{500}}" style="height:{{pageHeight}}px"> <swiper-item> <scroll-view class="scroll-view" scroll-x="{{true}}" scroll-y="{{false}}" style="width:{{windowWidth}}px;height:{{pageHeight}}px;"> <!--第一页内容--> </scroll-view> </swiper-item> <swiper-item> <scroll-view class="scroll-view" scroll-x="{{true}}" scroll-y="{{false}}" style="width:{{windowWidth}}px;height:{{pageHeight}}px;"> <!--第二页内容--> </scroll-view> </swiper-item> <!--更多swiper-item--> </swiper> ``` 其中,swiper组件设置了current属性,用于控制当前显示的页码;scroll-view组件设置了scroll-x属性,用于开启水平方向的滚动,并设置了样式宽度为屏幕宽度,高度为页面高度。 接着,在js文件中,监听swiper组件的change事件,用于动态更新当前页码。 ```javascript Page({ data: { current: 0, windowWidth: wx.getSystemInfoSync().windowWidth, pageHeight: wx.getSystemInfoSync().windowHeight }, onLoad: function () { //... }, onPageChange: function (e) { this.setData({ current: e.detail.current }) } }) ``` 最后,在样式文件中,设置swiper-container和scroll-view的样式,用于实现左右分页效果。 ```css .swiper-container { overflow: hidden; position: relative; } .scroll-view { white-space: nowrap; } .swiper-item { display: inline-block; vertical-align: top; width: 100%; } ``` 以上就是使用swiper和scroll-view组件实现微信小程序左右分页功能的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值