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

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

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

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

微信小程序用swiper 和 movable-view实现wx.previewImage功能_第1张图片

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

24

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


     
      
        
          
            
          
          
          
  

10

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

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


     
      
        
          
            
          
          
          
  



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    我这里之前设置的横屏竖屏事件,然后横屏那一段代码没有写放大拖动这些事件


  
     
      
        
          
            
          
          
          
  
  




  
  
  
    
  
  
  

②、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") 的这个字段,确定是左还是右触碰到边界,然后动态修改轮播图的下标完成,虽然有一点小瑕疵  大家多测试就会发现了,但是整体功能是实现的。小瑕疵捣鼓了两三个小时没捣鼓好 烦躁了。。。。。先把代码贴这里吧。


  
     
      
        
          
            
          
          
          
  
  




  
  
  
    
  
  
  

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;//赋值给第一次触发的时间,这样就保存了第二次触发的时间
      }
    };
  },

你可能感兴趣的:(前端,javascript,微信小程序)