這篇文章主要介紹微信小程序中movable-view移動(dòng)圖片與雙指縮放的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
發(fā)展壯大離不開廣大客戶長(zhǎng)期以來的信賴與支持,我們將始終秉承“誠信為本、服務(wù)至上”的服務(wù)理念,堅(jiān)持“二合一”的優(yōu)良服務(wù)模式,真誠服務(wù)每家企業(yè),認(rèn)真做好每個(gè)細(xì)節(jié),不斷完善自我,成就企業(yè),實(shí)現(xiàn)共贏。行業(yè)涉及封陽臺(tái)等,在網(wǎng)站建設(shè)、成都全網(wǎng)營(yíng)銷推廣、WAP手機(jī)網(wǎng)站、VI設(shè)計(jì)、軟件開發(fā)等項(xiàng)目上具有豐富的設(shè)計(jì)經(jīng)驗(yàn)。
movable-area是微信小程序的新組件,可以用來移動(dòng)視圖區(qū)域movable-view。移動(dòng)方向可選擇任何、垂直和平行??梢苿?dòng)區(qū)域里包含其他文本、圖片、按鈕等組件??梢苿?dòng)區(qū)域可綁定touchend等事件。movable-view的參數(shù)可調(diào)整動(dòng)畫效果。
先從movable-view開始說起吧. movable-view是小程序自定義的組件.其描述為:"可移動(dòng)的視圖容器,在頁面中可以拖拽滑動(dòng)".
值得注意的是文檔中有一段備注: "當(dāng)movable-view小于movable-area時(shí),movable-view的移動(dòng)范圍是在movable-area內(nèi);當(dāng)movable-view大于movable-area時(shí),movable-view的移動(dòng)范圍必須包含movable-area(x軸方向和y軸方向分開考慮)". 也就是說父容器movable-area是可以比子容器movable-view小的,但是子容器的移動(dòng)范圍必須包括父容器.
先看官方實(shí)例代碼:
<view class="section"> <view class="section__title">movable-view區(qū)域小于movable-area</view> <movable-area style="height: 200px;width: 200px;background: red;"> <movable-view style="height: 50px; width: 50px; background: blue;" x="{{x}}" y="{{y}}" direction="all"> </movable-view> </movable-area> <view class="btn-area"> <button size="mini" bindtap="tap">click me to move to (30px, 30px)</button> </view> <view class="section__title">movable-view區(qū)域大于movable-area</view> <movable-area style="height: 100px;width: 100px;background: red;" direction="all"> <movable-view style="height: 200px; width: 200px; background: blue;"> </movable-view> </movable-area> </view>
這里面有個(gè)錯(cuò)誤,應(yīng)該是編寫人的一點(diǎn)小失誤吧. 第二個(gè)movable-area的屬性direction應(yīng)該寫在movable-view上.
<movable-area style="height: 100px;width: 100px;background: red;" > <movable-view style="height: 200px; width: 200px; background: blue;" direction="all"> </movable-view> </movable-area>
看下效果:
1) 當(dāng)movable-view區(qū)域小于movable-area時(shí),子容器movable-view只能在父容器內(nèi)移動(dòng). 下圖的效果是設(shè)置了屬性 out-of-bounds="true"的效果. out-of-bounds可以染子容器到達(dá)父容器邊界時(shí)有個(gè)超出邊界然后回彈的動(dòng)畫. 并不是真正能讓子容器移動(dòng)到父容器以外.
2) 當(dāng)movable-view區(qū)域大于movable-area時(shí),子容器移動(dòng)的范圍必須包括父容器.
第二種情況中,把父容器看做手機(jī)屏幕可視區(qū)域,子容器看做要查看的長(zhǎng)圖,大圖. 就可以實(shí)現(xiàn)拖動(dòng)查看圖片的效果. 如果圖片時(shí)動(dòng)態(tài)加載的,不是固定的圖片,就要兼容圖片寬高小于屏幕可視寬高和圖片寬高大于可視屏幕寬高的可能性,也就是要考慮到以上兩種情況.
我們要在movable組件加載的同時(shí)設(shè)置好movable-view的寬高,因?yàn)閙ovable組件加載成功后再去改變movable-view的大小,可移動(dòng)區(qū)域是不會(huì)變的. 我們可以通過頁面中要查看的圖片的onload事件中獲取圖片寬高(目前我只發(fā)現(xiàn)bindload事件能獲取到圖片寬高),然后存儲(chǔ)起來imgWidth和imgHeight. 當(dāng)用戶點(diǎn)擊圖片時(shí),在bindtap事件中設(shè)置好movable-view的寬高,同時(shí)將movable-area的彈窗wx;if設(shè)置為true.
<!-- 要查看的圖片列表 --> <view class="flex-wrap flex-pic"> <view class="picList"> <image wx:for="{{item.imglist}}" wx:for-item="itemImg" wx:key="*this" id="{{'rfnd_'+index}}" bindload="imageOnload" src="{{ itemImg}}" bindtap="showResizeModal" src="{{itemImg}}"></image> </view> </view>
因?yàn)橐榭吹氖且粋€(gè)圖片列表, 我用了一個(gè)數(shù)組去存儲(chǔ)每個(gè)圖片的寬高,然后通過圖片id來關(guān)聯(lián)
/** * 加載圖片 */ imageOnload:function(e){ var id = e.currentTarget.id this.data.imgIdList[id] = { width:e.detail.width, height:e.detail.height } }, 模板頁面 <!--components/resizePicModal/resizePicModal.wxml--> <template name="resizePic"> <scroll-view class="backdrop"> <view class="close-icon" bindtap="closeResizeModal"> 取消預(yù)覽 </view> <movable-area style="width:100%;height:100%;" > <movable-view direction="all" out-of-bounds="true" x="{{img.x}}" y="{{img.y}}" > <image mode="widthFix" class="dtl-img" src="{{img.currentSrc}}"></image> </movable-view> </movable-area> </scroll-view> </template> /** * 打開彈窗 */ showResizeModal: function (e) { var src = e.currentTarget.dataset.src; var x = 0 var y =0 try { var width = this.imgIdList[e.currentTarget.id].width; //圖片原寬 var height = this.imgIdList[e.currentTarget.id].height; //圖片原高 //小程序默認(rèn)固定寬320px,獲取top和left值,使圖片居中顯示 height = height * (320 / width); width = 320; x = (app.windowWidth - width) / 2 y = (app.windowHeight - height) / 2 } catch (e) { } var img = { x: x, y: y,26 currentSrc: src, }; this.setData({ img: img, isCheckDtl: true }); },
部分CSS代碼
.backdrop{ background: rgba(0, 0, 0, 1); width:100%; height: 100%; position: fixed; top:0; left:0; }
以上基本上可以完成一個(gè)點(diǎn)擊查看圖片的需求.
然而如果再支持雙指縮放的話,movable-view實(shí)現(xiàn)不了.我暫沒想出來怎么實(shí)現(xiàn),如果有人知道,希望能夠指點(diǎn)迷津. 主要原因是因?yàn)檫€是我上文提到的那句話:"movable組件加載成功后再去改變movable-view的大小,可移動(dòng)區(qū)域是不會(huì)變的".縮放后圖片大小肯定會(huì)改變的. 縮小還好,一旦放大,可移動(dòng)區(qū)域還是原來的不會(huì)改變.想象一下,如果一張寬度剛剛好時(shí)屏幕可視寬度的圖片,放大后,這張圖片就只能在屏幕可視寬度windowWidth的范圍中移動(dòng),看不到左也看不到右邊超出的部分.
所以如果既要可移動(dòng)圖片又要可縮放,就不能用movable-view組件了,自己寫個(gè)吧. 原來bindtouchmove會(huì)觸發(fā)頁面的滾動(dòng)條,但是現(xiàn)在微信好像已經(jīng)修復(fù)了這個(gè)BUG,我今天在真機(jī)上測(cè)試沒有出現(xiàn)這個(gè)問題.
自定義控件resizePicModal.wxml:
<!-- 縮放 --> <template name="resizePic"> <scroll-view class="backdrop" catchtouchmove="bindTouchMove" catchtouchend="bindTouchEnd" bindtouchstart="bindTouchStart" > <view class="close-icon" bindtap="closeResizeModal"> 取消預(yù)覽 </view> <image catchtouchmove="bindTouchMove" bindtouchend="bindTouchEnd" bindtouchstart="bindTouchStart" style=" transform: scale({{img.baseScale}}); position:absolute; top:{{img.top}}px; left:{{img.left}}px; " mode="widthFix" class="dtl-img" src="{{img.currentSrc}}"></image> </scroll-view> </template>
JS: resizePicModal.js
/** * 使用方法: * 1) WXHTML要縮放的圖片 必須 傳入 src 以及綁定 bindtap事件, * e.g: * <image bindtap="toggleDtl" src="{{item}}" wx:for="{{productCard.arrImg}}" wx:key="*this" src="{{item}}" style="width:100%" mode="widthFix"></image> * 2) WXHTML 要引入Modal模板(isCheckDtl無需再定義): * <view wx:if="{{isCheckDtl}}"> * <import src="/components/resizePicModal/resizePicModal.wxml"/> * <template is="resizePic" data="{{img}}"></template> * </view> * 3) JS頁面要引入JS文件,覆蓋當(dāng)前頁面的事件: * var resizePicModalService = require ('../../components/resizePicModal/resizePicModal.js') * var resizePicModal = {} * 4) 在onLoad事件中,實(shí)例化ResizePicModal * resizePicModal = new resizePicModalService.ResizePicModal() */ var app = getApp() let modalEvent = { distanceList: [0, 0],//存儲(chǔ)縮放時(shí),雙指距離.只有兩個(gè)數(shù)據(jù).第一項(xiàng)為old distance.最后一項(xiàng)為new distance disPoint: { x: 0, y: 0 },//手指touch圖片時(shí),在圖片上的位置 imgIdList:{}, /** * 打開彈窗 */ showResizeModal: function (e) { var src = e.currentTarget.dataset.src; var x = 0 var y =0 try { var width = this.imgIdList[e.currentTarget.id].width; //圖片原寬 var height = this.imgIdList[e.currentTarget.id].height; //圖片原高 //小程序固定寬320px height = height * (320 / width); width = 320; x = (app.windowWidth - width) / 2 //> 0 ? (app.windowWidth - width) / 2 : 0; y = (app.windowHeight - height) / 2// > 0 ? (app.windowHeight - height) / 2 : 0; } catch (e) { } var img = { top: y, left: x, x: x, y: y, width: '100%', baseScale: 1, currentSrc: src, }; this.setData({ img: img, isCheckDtl: true }); }, /** * 關(guān)閉彈窗 */ closeResizeModal:function(){ this.setData({ isCheckDtl: false }) }, /** * 加載圖片 */ imageOnload:function(e){ var id = e.currentTarget.id this.imgIdList[id] = { width:e.detail.width, height:e.detail.height } }, /** * bindtouchmove */ bindTouchMove: function (e) { if (e.touches.length == 1) {//一指移動(dòng)當(dāng)前圖片 this.data.img.left = e.touches[0].clientX - this.disPoint.x this.data.img.top = e.touches[0].clientY - this.disPoint.y this.setData({ img: this.data.img }) } if (e.touches.length == 2) {//二指縮放 var xMove = e.touches[1].clientX - e.touches[0].clientX var yMove = e.touches[1].clientY - e.touches[0].clientY var distance = Math.sqrt(xMove * xMove + yMove * yMove);//開根號(hào) this.distanceList.shift() this.distanceList.push(distance) if (this.distanceList[0] == 0) { return } var distanceDiff = this.distanceList[1] - this.distanceList[0]//兩次touch之間, distance的變化. >0,放大圖片.<0 縮小圖片 // 假設(shè)縮放scale基數(shù)為1: newScale = oldScale + 0.005 * distanceDiff var baseScale = this.data.img.baseScale + 0.005 * distanceDiff if(baseScale>0){ this.data.img.baseScale = baseScale var imgWidth = baseScale * parseInt(this.data.img.imgWidth) var imgHeight = baseScale * parseInt(this.data.img.imgHeight) this.setData({ img: this.data.img }) }else{ this.data.img.baseScale = 0 this.setData({ img: this.data.img }) } } }, /** * bindtouchend */ bindTouchEnd: function (e) { if (e.touches.length == 2) {//二指縮放 this.setData({ isCheckDtl: true }) } }, /** * bindtouchstart */ bindTouchStart: function (e) { this.distanceList = [0, 0]//回復(fù)初始值 this.disPoint = { x: 0, y: 0 } if (e.touches.length == 1) { this.disPoint.x = e.touches[0].clientX - this.data.img.left this.disPoint.y = e.touches[0].clientY - this.data.img.top } } } function ResizePicModal(){ let pages = getCurrentPages() let curPage = pages[pages.length - 1] Object.assign(curPage, modalEvent)//覆蓋原生頁面事件 this.page = curPage curPage.resizePicModal = this return this } module.exports = { ResizePicModal }
業(yè)務(wù)頁面wxml:引入自定義控件模板
<view class="flex-wrap flex-pic"> <view class="picList"> <image wx:for="{{item.imglist}}" wx:for-item="itemImg" wx:key="*this" id="{{'rfnd_'+index}}" bindload="imageOnload" src="{{ itemImg}}" bindtap="showResizeModal" src="{{itemImg}}"></image> </view> </view> <!-- 縮放 --> <view wx:if="{{isCheckDtl}}"> <import src="/components/resizePicModal/resizePicModal.wxml"/> <template is="resizePic" data="{{img}}"></template> </view>
業(yè)務(wù)頁面js,引用js文件,實(shí)例化resizePicModal
var that var resizePicModal = {} var app = getApp() var resizePicModalService = require('../../components/resizePicModal/resizePicModal.js') /** * 生命周期函數(shù)--監(jiān)聽頁面加載 */ onLoad: function (options) { that = this 8 resizePicModal = new resizePicModalService.ResizePicModal() }
以上是“微信小程序中movable-view移動(dòng)圖片與雙指縮放的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站題目:微信小程序中movable-view移動(dòng)圖片與雙指縮放的示例分析
文章分享:http://jinyejixie.com/article36/pggjpg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、建站公司、做網(wǎng)站、網(wǎng)站制作、標(biāo)簽優(yōu)化、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)