先从movable-view开始说起吧. movable-view是微信小程序自定义的组件.其描述为:”可移动的视图容器,在页面中可以拖拽滑动”.

值得注意的是文档中有一段备注: “当movable-view小于movable-area时,movable-view的移动范围是在movable-area内;当movable-view大于movable-area时,movable-view的移动范围必须包含movable-area(x轴方向和y轴方向分开考虑)”. 也就是说父容器movable-area是可以比子容器movable-view小的,但是子容器的移动范围必须包括父容器.

先看官方实例代码:

 1 <view class="section">2   <view class="section__title">movable-view区域小于movable-areaview>3   <movable-area style="height: 200px;width: 200px;background: red;">4     <movable-view style="height: 50px; width: 50px; background: blue;" x="{{x}}" y="{{y}}" direction="all">5     movable-view>6   movable-area>7   <view class="btn-area">8     <button size="mini" bindtap="tap">click me to move to (30px, 30px)button>9   view>
10   <view class="section__title">movable-view区域大于movable-areaview>
11   <movable-area style="height: 100px;width: 100px;background: red;" direction="all">
12     <movable-view style="height: 200px; width: 200px; background: blue;">
13     movable-view>
14   movable-area>
15 view>

这里面有个错误,应该是编写人的一点小失误吧. 第二个movable-area的属性direction应该写在movable-view上.

1  "height: 100px;width: 100px;background: red;" >
2     view style="height: 200px; width: 200px; background: blue;" direction="all">
3     view>
4

看下效果:

1) 当movable-view区域小于movable-area时,子容器movable-view只能在父容器内移动. 下图的效果是设置了属性 out-of-bounds=”true”的效果. out-of-bounds可以染子容器到达父容器边界时有个超出边界然后回弹的动画. 并不是真正能让子容器移动到父容器以外.

2) 当movable-view区域大于movable-area时,子容器移动的范围必须包括父容器.

第二种情况中,把父容器看做手机屏幕可视区域,子容器看做要查看的长图,大图. 就可以实现拖动查看图片的效果. 如果图片时动态加载的,不是固定的图片,就要兼容图片宽高小于屏幕可视宽高和图片宽高大于可视屏幕宽高的可能性,也就是要考虑到以上两种情况.

我们要在movable组件加载的同时设置好movable-view的宽高,因为movable组件加载成功后再去改变movable-view的大小,可移动区域是不会变的. 我们可以通过页面中要查看的图片的onload事件中获取图片宽高(目前我只发现bindload事件能获取到图片宽高),然后存储起来imgWidth和imgHeight. 当用户点击图片时,在bindtap事件中设置好movable-view的宽高,同时将movable-area的弹窗wx;if设置为true.

1
2           <view class="flex-wrap flex-pic">
3               <view class="picList">
4                   for="{{item.imglist}}" wx:for-item="itemImg" wx:key="*this" id="{{'rfnd_'+index}}" bindload="imageOnload" src="{{ itemImg}}" bindtap="showResizeModal" data-src="{{itemImg}}">
5               view>
6           view>

因为要查看的是一个图片列表, 我用了一个数组去存储每个图片的宽高,然后通过图片id来关联

 1   /**2    * 加载图片3    */4   imageOnload:function(e){5     var id = e.currentTarget.id6     this.data.imgIdList[id] = {7       width:e.detail.width,8       height:e.detail.height9     }
10
11   },

模板页面

 1 3 <template name="resizePic">4 5   <scroll-view class="backdrop"> 6     <view class="close-icon" bindtap="closeResizeModal"> 7       取消预览8     view>9     <movable-area style="width:100%;height:100%;"  >
10         <movable-view direction="all"
11         out-of-bounds="true"  x="{{img.x}}" y="{{img.y}}" >
12         <image  mode="widthFix" class="dtl-img" src="{{img.currentSrc}}">image>
13         movable-view>
14
15     movable-area>
16   scroll-view>
17  template>
 1   /**2    * 打开弹窗3    */4   showResizeModal: function (e) {5     var src = e.currentTarget.dataset.src;6     var x = 07     var y =08     try {9       var width = this.imgIdList[e.currentTarget.id].width; //图片原宽
10       var height = this.imgIdList[e.currentTarget.id].height; //图片原高
11
12       //小程序默认固定宽320px,获取top和left值,使图片居中显示
13       height = height * (320 / width);
14       width = 320;
15     
16       x = (app.windowWidth - width) / 2
17       y = (app.windowHeight - height) / 2
18
19     } catch (e) { }
20     var img = {
21       x: x,
22       y: y,
26      currentSrc: src,
27     };
28     this.setData({ img: img, isCheckDtl: true });
29
30   },

部分CSS代码

.backdrop{background: rgba(0, 0, 0, 1);width:100%;height: 100%;position: fixed;top:0;left:0;
}

以上基本上可以完成一个点击查看图片的需求.

然而如果再支持双指缩放的话,movable-view实现不了.我暂没想出来怎么实现,如果有人知道,希望能够指点迷津. 主要原因是因为还是我上文提到的那句话:”movable组件加载成功后再去改变movable-view的大小,可移动区域是不会变的”.缩放后图片大小肯定会改变的. 缩小还好,一旦放大,可移动区域还是原来的不会改变.想象一下,如果一张宽度刚刚好时屏幕可视宽度的图片,放大后,这张图片就只能在屏幕可视宽度windowWidth的范围中移动,看不到左也看不到右边超出的部分.

所以如果既要可移动图片又要可缩放,就不能用movable-view组件了,自己写个吧. 原来bindtouchmove会触发页面的滚动条,但是现在微信好像已经修复了这个BUG,我今天在真机上测试没有出现这个问题.

自定义控件resizePicModal.wxml:

 1 2 <template name="resizePic">3   <scroll-view class="backdrop"  catchtouchmove="bindTouchMove" catchtouchend="bindTouchEnd" bindtouchstart="bindTouchStart" > 4     <view class="close-icon" bindtap="closeResizeModal"> 5       取消预览6     view>7        <image catchtouchmove="bindTouchMove" bindtouchend="bindTouchEnd" bindtouchstart="bindTouchStart"  8       style=" transform: scale({{img.baseScale}}); position:absolute; top:{{img.top}}px; left:{{img.left}}px; "9       mode="widthFix" class="dtl-img" src="{{img.currentSrc}}">image>
10
11
12   scroll-view>
13  template>

JS: resizePicModal.js

  1 /**2  * 使用方法:3  * 1) WXHTML要缩放的图片 必须 传入 src 以及绑定 bindtap事件,4  *    e.g:     5  *    6  * 2) WXHTML 要引入Modal模板(isCheckDtl无需再定义):7  *      8  *        9  *        10  *      11  * 3) JS页面要引入JS文件,覆盖当前页面的事件:12  *    var resizePicModalService =  require ('../../components/resizePicModal/resizePicModal.js')13  *    var resizePicModal = {}14  * 4) 在onLoad事件中,实例化ResizePicModal15  *        resizePicModal = new resizePicModalService.ResizePicModal()16  */17 var app = getApp()18 let modalEvent = {19   distanceList: [0, 0],//存储缩放时,双指距离.只有两个数据.第一项为old distance.最后一项为new distance20   disPoint: { x: 0, y: 0 },//手指touch图片时,在图片上的位置21   imgIdList:{},22   23   /**24    * 打开弹窗25    */26   showResizeModal: function (e) {27     var src = e.currentTarget.dataset.src;28     var x = 029     var y =030     try {31       var width = this.imgIdList[e.currentTarget.id].width; //图片原宽32       var height = this.imgIdList[e.currentTarget.id].height; //图片原高33      34       //小程序固定宽320px35       height = height * (320 / width);36       width = 320;37 38       x = (app.windowWidth - width) / 2 //> 0 ? (app.windowWidth - width) / 2 : 0;39       y = (app.windowHeight - height) / 2// > 0 ? (app.windowHeight - height) / 2 : 0;40 41     } catch (e) { }42     var img = {43       top: y,44       left: x,45       x: x, y: y,46       width: '100%',47       baseScale: 1,48       currentSrc: src,49     };50     this.setData({ img: img, isCheckDtl: true });51     52   },53   /**54    * 关闭弹窗55    */56   closeResizeModal:function(){57     this.setData({  isCheckDtl: false })58   },59   /**60    * 加载图片61    */62   imageOnload:function(e){63     var id = e.currentTarget.id64     this.imgIdList[id] = {65       width:e.detail.width,66       height:e.detail.height67     }68     69   },70   /**71    * bindtouchmove72    */73   bindTouchMove: function (e) {74     if (e.touches.length == 1) {//一指移动当前图片75       this.data.img.left = e.touches[0].clientX - this.disPoint.x76       this.data.img.top = e.touches[0].clientY - this.disPoint.y77 78       this.setData({ img: this.data.img })79     }80   82     if (e.touches.length == 2) {//二指缩放83       var xMove = e.touches[1].clientX - e.touches[0].clientX84       var yMove = e.touches[1].clientY - e.touches[0].clientY85       var distance = Math.sqrt(xMove * xMove + yMove * yMove);//开根号86       this.distanceList.shift()87       this.distanceList.push(distance)88       if (this.distanceList[0] == 0) { return }89       var distanceDiff = this.distanceList[1] - this.distanceList[0]//两次touch之间, distance的变化. >0,放大图片.<0 缩小图片90       // 假设缩放scale基数为1:  newScale = oldScale + 0.005 * distanceDiff91       var baseScale = this.data.img.baseScale + 0.005 * distanceDiff92       if(baseScale>0){93         this.data.img.baseScale = baseScale94         var imgWidth = baseScale * parseInt(this.data.img.imgWidth) 95         var imgHeight = baseScale * parseInt(this.data.img.imgHeight)96         this.setData({ img: this.data.img })97       }else{98         this.data.img.baseScale = 099         this.setData({ img: this.data.img })
100       }
101
102     }
103
104   },
105   /**
106    * bindtouchend
107    */
108   bindTouchEnd: function (e) {
109     if (e.touches.length == 2) {//二指缩放
110       this.setData({ isCheckDtl: true })
111     }
112   },
113   /**
114    * bindtouchstart
115    */
116   bindTouchStart: function (e) {
117     this.distanceList = [0, 0]//回复初始值
118     this.disPoint = { x: 0, y: 0 }
119     if (e.touches.length == 1) {
120       this.disPoint.x = e.touches[0].clientX - this.data.img.left
121       this.disPoint.y = e.touches[0].clientY - this.data.img.top
122     }
123
124   }
125 }
126
127 function ResizePicModal(){
128   let pages = getCurrentPages()
129   let curPage = pages[pages.length - 1]
130   Object.assign(curPage, modalEvent)//覆盖原生页面事件
131   this.page = curPage
132   curPage.resizePicModal = this
133   return this
134 }
135 module.exports = {
136   ResizePicModal
137 }

业务页面wxml:引入自定义控件模板

 1   <view class="flex-wrap flex-pic">2               <view class="picList">            3                   <image  wx:for="{{item.imglist}}" wx:for-item="itemImg" wx:key="*this" id="{{'rfnd_'+index}}" bindload="imageOnload" src="{{ itemImg}}" bindtap="showResizeModal" data-src="{{itemImg}}">image>           4               view>5   view>6 7  <view wx:if="{{isCheckDtl}}">8    <import src="/components/resizePicModal/resizePicModal.wxml"/>9   <template is="resizePic" data="{{img}}">template>
10  view>

业务页面js,引用js文件,实例化resizePicModal

1 var that
2 var resizePicModal = {}
3 var app = getApp()
4 var resizePicModalService = require('../../components/resizePicModal/resizePicModal.js')
 1  /**2    * 生命周期函数--监听页面加载3    */4   onLoad: function (options) {5     that = this 8     resizePicModal = new resizePicModalService.ResizePicModal()}

新手一枚,有未完善支出谢谢指点出来.

微信小程序movable-view移动图片和双指缩放相关推荐

  1. 微信小程序单指拖拽和双指缩放旋转

    前言 小程序单指拖拽和双指操作是一个比较常用的功能,效果如下图 实现这三个功能,主要用三个触摸事件touchstart.touchmove.touchend <view style=" ...

  2. 微信小程序 实现报表(表格)双指缩放功能

    实现前提要景: 1.本次实现双指缩放 是用css3中的scale配合translate 实现 2.小程序 不支持动态改变scale的大小 即使在写在行内样式中也不生效(在调试中不生效)故需借助小程序自 ...

  3. 微信小程序-从相册获取图片,视频 使用相机拍照,录像上传+服务器(nodejs版)接收

    在本文 微信小程序-从相册获取图片 使用相机拍照 本地图片上传之前需要看看 微信小程序-获取用户session_key,openid,unionid - 后端为nodejs 代码封装是在上文添加的. ...

  4. 微信小程录制视频上传服务器,微信小程序-从相册获取图片,视频使用相机拍照,录像上传+服务器nodejs版接收-微信小程序视频上传功能-微信小程序视频上传...

    在本文微信小程序-从相册获取图片使用相机拍照本地图片上传之前需要看看微信小程序-获取用户session_key,openid,unionid-后端为nodejs代码封装是在上文添加的.本文知识点:1. ...

  5. [微信小程序]聊天对话(文本,图片)的功能(完整代码附效果图)

    相关文章: 1.小程序聊天群,发送语音,文字,图片. 2.微信小程序集成腾讯IM,实现实时音视频通话,1V1聊天 3.云开发微信小程序聊天群 4.接入网易云信IM即时通讯的微信小程序聊天室 5.微信小 ...

  6. 微信小程序实现PDF转图片(java spring实现)

    微信小程序实现PDF转图片前后端(两种方式) 1.前端传PDF的url地址至后端 1.1前端 1.2后端 2.前端传PDF文件至后端 2.1前端 2.2后端 1.前端传PDF的url地址至后端 1.1 ...

  7. 【微信小程序】将base64图片保存至本地

    需求描述 微信小程序中,下载一个报告文件,直接可获取到的是报告图片的base64格式. 参考文章 1.微信小程序实现图片下载功能 2.微信小程序把base64的图片保存到手机相册 代码实现 1.wxm ...

  8. 微信小程序导航条配置图片背景

    文章目录 微信小程序导航条配置图片背景 全部页面替换 就首页特殊,其他页面纯色导航条(沿用微信那套) 相关代码 如果你觉得写的不错或者帮到你了,记得给我点个赞哟~ 微信小程序导航条配置图片背景 需要实 ...

  9. 微信小程序拍照视频上传php,微信小程序-拍照或选择图片并上传文件

    微信小程序-拍照或选择图片并上传文件 调用拍照API:https://mp.weixin.qq.com/debug/wxadoc/dev/api/media-picture.html?t=201612 ...

  10. 微信小程序开发——设置默认图片、错误加载图片

    wxml: <image src='{{imgArr[index]==""?defaultImg:imgList[index]}}' binderror="erro ...

最新文章

  1. “万物就只是5万亿个参数”,AI模型GPT-3让人怀疑人生
  2. MAC能登录微信,浏览器连不上网
  3. 【ABAP】BASE64加密及解密
  4. Java的代理模式之静态代理和动态代理
  5. python得读音_python3 - 文本读音器
  6. uiwebview 修改html,修改UIWebView加载的html文本属性
  7. 将图片处理成圆形_设计基本功!图片处理技巧
  8. 《大道至简》阅读笔记02
  9. 单调栈求全1(或全0)子矩阵的个数 洛谷P5300与或和 P3400仓鼠窝
  10. MPlayer源代码分析
  11. POJ 2492 A Bug's Life
  12. [转]win7添加xp的快速启动栏
  13. mysql 3.23.49,将旧的3.23.49 MySQL数据库转移到5.0.51 MySQL数据库 – 用ANSI和UTF-8编码...
  14. linux mysql远程连接
  15. wap2.0技巧篇(转)
  16. R语言:关于我国各地区消费水平的聚类分析
  17. 卡巴斯基最新激活码,卡巴斯基免费下载
  18. 读《采购与供应链管理》
  19. C++实现cmd界面简单贪吃蛇游戏
  20. 对与连连看求解算法的研究

热门文章

  1. 微信小程序中的Page
  2. Bert最新进展,继续在NLP各领域开花结果!
  3. PETRv2:一个多摄像头图像3D感知的统一框架
  4. LSS功能介绍及其应用
  5. Farrago for Mac(好用的音频编辑软件)
  6. table 列宽计算方式
  7. opencv背景虚化(后篇)
  8. 加班丧?来看看这些句子给你满满正能量
  9. 验证码不显示该怎么办
  10. 一些好的Android开源项目