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