先從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 看下效果:app 1) 當movable-view區域小於movable-area時,子容器movable-view只能在父容器內移動. 下圖的效果是設置了屬性 out-of-bounds=」true」的效果. out-of-bounds能夠染子容器到達父容器邊界時有個超出邊界而後回彈的動畫. 並非真正能讓子容器移動到父容器之外.函數 2) 當movable-view區域大於movable-area時,子容器移動的範圍必須包括父容器.測試 第二種狀況中,把父容器看作手機屏幕可視區域,子容器看作要查看的長圖,大圖. 就能夠實現拖動查看圖片的效果. 若是圖片時動態加載的,不是固定的圖片,就要兼容圖片寬高小於屏幕可視寬高和圖片寬高大於可視屏幕寬高的可能性,也就是要考慮到以上兩種狀況.flex 咱們要在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來關聯ui 1 /** 2 * 加載圖片 3 */ 4 imageOnload:function(e){ 5 var id = e.currentTarget.id 6 this.data.imgIdList[id] = { 7 width:e.detail.width, 8 height:e.detail.height 9 } 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 = 0 7 var y =0 8 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事件中,實例化ResizePicModal 15 * resizePicModal = new resizePicModalService.ResizePicModal() 16 */ 17 var app = getApp() 18 let modalEvent = { 19 distanceList: [0, 0],//存儲縮放時,雙指距離.只有兩個數據.第一項爲old distance.最後一項爲new distance 20 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 = 0 29 var y =0 30 try { 31 var width = this.imgIdList[e.currentTarget.id].width; //圖片原寬 32 var height = this.imgIdList[e.currentTarget.id].height; //圖片原高 33 34 //小程序固定寬320px 35 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.id 64 this.imgIdList[id] = { 65 width:e.detail.width, 66 height:e.detail.height 67 } 68 69 }, 70 /** 71 * bindtouchmove 72 */ 73 bindTouchMove: function (e) { 74 if (e.touches.length == 1) {//一指移動當前圖片 75 this.data.img.left = e.touches[0].clientX - this.disPoint.x 76 this.data.img.top = e.touches[0].clientY - this.disPoint.y 77 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].clientX 84 var yMove = e.touches[1].clientY - e.touches[0].clientY 85 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 * distanceDiff 91 var baseScale = this.data.img.baseScale + 0.005 * distanceDiff 92 if(baseScale>0){ 93 this.data.img.baseScale = baseScale 94 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 = 0 99 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() } 新手一枚,有未完善支出謝謝指點出來. |