Skip to content

tongxunlu/mini-image-preview

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

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

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

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

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

<iframe id="4LFKpnLW-1657691121918" src="https://live.csdn.net/v/embed/224290" allowfullscreen="true" data-mediaembed="csdn"></iframe>

24

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

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

<iframe id="msbbMLIa-1657682544031" src="https://live.csdn.net/v/embed/224294" allowfullscreen="true" data-mediaembed="csdn"></iframe>

10

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

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

  1. <swiper class="swiper" indicator-dots="{{true}}" indicator-color="rgb(247, 247, 247,1)" indicator-active-color="#1bb7b5">
  2. <swiper-item class="swiper-item" wx:for="{{imgList}}" data-index="index" wx:key="index" catchtouchmove="{{amplification>1?'slideshow' : ''}}">
  3. <movable-area class="moswiper1" scale-area>
  4. <movable-view class="moswiper2" direction="all" out-of-bounds scale scale-min="1" scale-max="4" scale-value="1">
  5. <view class="swiper-view" >
  6. <image mode="widthFix" src="{{item}}"></image>
  7. </view>
  8. </movable-view>
  9. </movable-area>
  10. </swiper-item>
  11. </swiper>
  12. js
  13. amplification:1 , //放大倍数
  14. movableScale(e){//放大事件,只要图片放大就给轮播图禁止了
  15. console.log('放大倍数=====>',e.detail);
  16. this.setData(({
  17. amplification:e.detail.scale
  18. }))
  19. }

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

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

上最终代码、效果

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

  1. <match-media orientation="portrait" bindtap="close" class="preview-img-mask" wx:if="{{imgList!=0}}">
  2. <swiper class="swiper" indicator-dots="{{true}}" indicator-color="rgb(247, 247, 247,1)" indicator-active-color="#1bb7b5" bindchange='onChange' bindtransition='alter' bindanimationfinish='finish'>
  3. <swiper-item class="swiper-item" wx:for="{{imgList}}" data-index="index" wx:key="index" catchtouchmove="{{amplification>1?'slideshow' : ''}}">
  4. <movable-area class="moswiper1" scale-area>
  5. <movable-view class="moswiper2" direction="all" out-of-bounds scale scale-min="1" scale-max="4" scale="{{!isstop}}" scale-value="1" bindscale="movableScale">
  6. <view class="swiper-view" catchtap="nothing">
  7. <image mode="widthFix" src="{{item}}"></image>
  8. </view>
  9. </movable-view>
  10. </movable-area>
  11. </swiper-item>
  12. </swiper>
  13. </match-media>
  14. <match-media orientation="landscape" bindtap="close" class="preview-img-mask" wx:if="{{imgList!=0}}">
  15. <swiper class="swiper1" indicator-dots="{{true}}" indicator-color="rgb(247, 247, 247,1)" indicator-active-color="#1bb7b5" bindtransition='onChange'>
  16. <swiper-item class="swiper-item1" wx:for="{{imgList}}" data-index="index" wx:key="index">
  17. <view class="swiper-view1" catchtap="nothing">
  18. <image show-menu-by-longpress src="{{item}}"></image>
  19. </view>
  20. </swiper-item>
  21. </swiper>
  22. </match-media>

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

  1. // 我这里是个组件
  2. Component({
  3. /**
  4. * 组件的属性列表
  5. */
  6. properties: {
  7. imgList:{
  8. value:[],
  9. type:Array
  10. },
  11. },
  12. /**
  13. * 组件的初始数据
  14. */
  15. data: {
  16. swiperIndex: 0, // 第一次加载默认第一张图片选中
  17. amplification:1 , //放大倍数
  18. iscurrent:0 , //当前在哪一张
  19. isdx:'', //记录x
  20. isdy:'', //记录y
  21. isstop:false, //禁止缩放
  22. },
  23. /**
  24. * 组件的方法列表
  25. */
  26. methods: {
  27. close(){
  28. // debugger
  29. this.triggerEvent("close")
  30. },
  31. onChange(e){ //如果不加这个方法那放大和滑动屏幕如果同时触发了
  32. let current = e.detail.current //那因为此时amplification可能大于设定值将不可滑动
  33. if (current != this.data.iscurrent) {
  34. // console.log('只要图片改变了,就可以滑动~~~~');
  35. this.setData({
  36. amplification:1,
  37. })
  38. }
  39. this.setData({iscurrent:current})
  40. },
  41. alter(e){ //swiper位移事件
  42. let [dx, dy] = [e.detail.dx,e.detail.dy];
  43. this.setData({
  44. isdx:dx,
  45. isdy:dy
  46. })
  47. //这个>10是因为手指触碰时会被轻微的滑动影响到而造成不能缩放
  48. if (this.data.isdx>10 || this.data.isdy>10) {
  49. // console.log('说明有位移操作,此时禁止缩放~~');
  50. this.setData({
  51. isstop:true
  52. })
  53. }else{
  54. //否则允许缩放
  55. this.setData({
  56. isstop:false
  57. })
  58. }
  59. },
  60. finish(e){ //轮播图移动完毕事件
  61. this.setData({
  62. isdx:0, //xy每一次跳转完毕赋值0 给下面重新判断用,并且允许新页面缩放
  63. isdy:0,
  64. isstop:false
  65. })
  66. },
  67. nothing(e){
  68. console.log(e);
  69. },
  70. movableScale(e){//放大事件,只要图片放大就给轮播图禁止了
  71. console.log('放大倍数=====>',e.detail);
  72. this.setData(({
  73. amplification:e.detail.scale
  74. }))
  75. }
  76. }
  77. })

③、css

  1. .preview-img-mask{
  2. position: fixed !important;
  3. background-color: #000000;
  4. top: 0;
  5. bottom: 0;
  6. left: 0;
  7. right: 0;
  8. z-index: 10000;
  9. display: flex;
  10. align-items: center;
  11. justify-content: center;
  12. }
  13. .swiper-item{
  14. display: flex;
  15. align-items: center;
  16. justify-content: center;
  17. }
  18. .swiper{
  19. width: 100%;
  20. height: 90%;
  21. /* display: flex;
  22. justify-content: center;
  23. align-items: center; */
  24. }
  25. .swiper-view{
  26. width: 100%;
  27. }
  28. .swiper-view image{
  29. width: 100%;
  30. }
  31. .swiper-item1{
  32. display: flex;
  33. align-items: center;
  34. justify-content: center;
  35. }
  36. .swiper1{
  37. width: 90%;
  38. height: 100%;
  39. }
  40. .swiper-view1{
  41. width: 100%;
  42. height: 100%;
  43. }
  44. .swiper-view1 image{
  45. width: 100%;
  46. height: 100%;
  47. }
  48. .moswiper1{
  49. width: 99%;
  50. height: 420rpx;
  51. }
  52. .moswiper2{
  53. width: 100%;
  54. height: 100%;
  55. }

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

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

  1. <match-media orientation="portrait" bindtap="close" class="preview-img-mask" wx:if="{{imgList!=0}}">
  2. <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}}">
  3. <swiper-item class="swiper-item" wx:for="{{imgList}}" data-index="index" wx:key="index" catchtouchmove="{{amplification>1?'slideshow' : ''}}">
  4. <movable-area class="moswiper1" scale-area>
  5. <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">
  6. <view class="swiper-view" catchtap="nothing">
  7. <image mode="widthFix" src="{{item}}"></image>
  8. </view>
  9. </movable-view>
  10. </movable-area>
  11. </swiper-item>
  12. </swiper>
  13. </match-media>
  14. <match-media orientation="landscape" bindtap="close" class="preview-img-mask" wx:if="{{imgList!=0}}">
  15. <swiper class="swiper1" indicator-dots="{{true}}" indicator-color="rgb(247, 247, 247,1)" indicator-active-color="#1bb7b5" bindtransition='onChange'>
  16. <swiper-item class="swiper-item1" wx:for="{{imgList}}" data-index="index" wx:key="index">
  17. <view class="swiper-view1" catchtap="nothing">
  18. <image show-menu-by-longpress src="{{item}}"></image>
  19. </view>
  20. </swiper-item>
  21. </swiper>
  22. </match-media>

js

  1. // component/previewImg/previewImg.js
  2. const app = getApp();
  3. Component({
  4. /**
  5. * 组件的属性列表
  6. */
  7. properties: {
  8. imgList:{
  9. value:[],
  10. type:Array
  11. },
  12. },
  13. /**
  14. * 组件的初始数据
  15. */
  16. data: {
  17. swiperIndex: 0, // 第一次加载默认第一张图片选中
  18. amplification:1 , //放大倍数
  19. iscurrent:0 , //当前在哪一张
  20. isdx:'', //记录缩放x
  21. isdy:'', //记录缩放y
  22. isstop:false, //禁止缩放
  23. current:0 , //哪一个
  24. suofang:1, //缩放倍数
  25. x_axis:0, //x轴坐标
  26. },
  27. /**
  28. * 组件的方法列表
  29. */
  30. methods: {
  31. close(){
  32. // debugger
  33. this.triggerEvent("close")
  34. },
  35. onChange(e){ //如果不加这个方法那放大和滑动屏幕如果同时触发了
  36. let current = e.detail.current //那因为此时amplification可能大于设定值将不可滑动
  37. console.log('current',e.detail);
  38. this.setData({
  39. current:current
  40. })
  41. if (current != this.data.iscurrent) {
  42. // console.log('只要图片改变了,就可以滑动~~~~');
  43. this.setData({
  44. amplification:1,
  45. })
  46. }
  47. this.setData({iscurrent:current})
  48. },
  49. alter(e){ //swiper位移事件
  50. let [dx, dy] = [e.detail.dx,e.detail.dy];
  51. this.setData({
  52. isdx:dx,
  53. isdy:dy
  54. })
  55. //这个>10是因为手指触碰时会被轻微的滑动影响到而造成不能缩放
  56. if (this.data.isdx>10 || this.data.isdy>10) {
  57. // console.log('说明有位移操作,此时禁止缩放~~');
  58. this.setData({
  59. isstop:true
  60. })
  61. }else{
  62. //否则允许缩放
  63. this.setData({
  64. isstop:false
  65. })
  66. }
  67. },
  68. finish(e){ //轮播图移动完毕事件
  69. console.log(e);
  70. this.setData({
  71. isdx:0, //xy每一次跳转完毕赋值0 给下面重新判断用,并且允许新页面缩放
  72. isdy:0,
  73. isstop:false, //允许缩放
  74. suofang:1, //缩放回1倍
  75. })
  76. },
  77. nothing(e){
  78. console.log(e);
  79. },
  80. movableScale(e){//放大事件,只要图片放大就给轮播图禁止了
  81. // console.log('放大倍数=====>',e.detail);
  82. this.setData(({
  83. amplification:e.detail.scale,
  84. }))
  85. },
  86. //如果x越来越小就是往右,越来越大就是往左移动
  87. slideChange: app.throttle(function(e){
  88. if (this.data.amplification<1.1) {
  89. console.log('没放大不走拖动换页那一套~');
  90. }else{
  91. console.log('movable-view滑动事件====>',e.detail);
  92. let xzhi = this.data.x_axis
  93. console.log('之前的x轴位置====>',xzhi);
  94. let x = e.detail.x //当前的x坐标轴-610 与 以前的x坐标轴对比-609
  95. let xdang1 = x-5
  96. let xdang2 = x+5
  97. if (x > this.data.x_axis) { //如果x轴坐标大于上次记录的
  98. this.setData({x_axis:xdang2})
  99. console.log('图片是左移');
  100. if (e.detail.source == "out-of-bounds" || e.detail.source == "touch-out-of-bounds") {
  101. console.log('触碰到左左左边界了=====>');
  102. if (this.data.current>0) {
  103. this.setData({
  104. // amplification:1,
  105. current:this.data.current-1
  106. })
  107. }else{
  108. this.setData({
  109. current:0
  110. })
  111. }
  112. }
  113. }else{ //x < this.data.x_axis
  114. this.setData({x_axis:xdang1})
  115. console.log('图片右移右移~~');
  116. if (e.detail.source == "out-of-bounds" || e.detail.source == "touch-out-of-bounds") {
  117. console.log('触碰到右边界了=====>');
  118. if (this.data.current < this.properties.imgList.length-1) {
  119. this.setData({
  120. current:this.data.current+1
  121. })
  122. }else{
  123. this.setData({
  124. current:this.data.current
  125. })
  126. }
  127. }
  128. }
  129. }
  130. },800),
  131. }
  132. })

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

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

About

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

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published