1. 程式人生 > >縮放類小程式實踐心得

縮放類小程式實踐心得

這是目前最近開發的一個小程式完成後的一些心得。

  • 需求是有一張靜態地圖,使用者點選對應的縣要進入二級頁面,
  • 二級頁面裡面底圖是一張靜態地圖,上面展示出相應的景點。點選景點顯示景點簡介
  • 一級頁面和二級頁面都是可以拖動和縮放的,雙擊可以縮放

具體功能頁如下:
二級頁面

我先是通過自己寫touch事件體驗,使用正常的h5測試已經能明顯感覺到體驗不是很流暢。
改寫成小程式,滑動資料都是用setData,本身又有個延遲操作。體驗後發現效果非常之差勁,卡頓現象特別嚴重。放棄了該方案!

後來發現小程式有提供movable-area和movable-view的拖動元件,嘗試寫了個demo,體驗後拖動縮放流暢,效果流暢,我想沒跑了這就是我想要的。

不過真正開發後發現還有很多問題需要解決,具體如下:

  1. 沒有事件監聽使用者是否結束了拖動和縮放。

  2. 移動端是沒有雙擊事件的,如何解決

  3. transform-scale用於縮放元素的話,會導致子元素被等比例縮放了,如何解決

  4. 如何判斷使用者點選那個區塊,進而跳轉二級頁面做出不同的響應

接下來,我們來一一解決上面的幾個問題!

問題1: 沒有事件監聽使用者是否結束了拖動和縮放?
我們可以通過touchend事件來兼聽使用者手指是否離開螢幕從而知道使用者是否停止了拖動和縮放操作。

但是,但是,如果我是通過程式碼控制滑動和縮放的情況下又要怎麼監聽呢???這裡從一位做IOS工程師的同事那裡得到一個很巧妙的解決方案。具體看如下程式碼:

//微信自帶生命週期
onLoad(options){
  this.checkAnimalEnd=true;//開啟檢查功能
  this.setData({
      scale: 2//將movable-view自動放大兩倍
  })
},
//movable-view自帶監聽縮放事件
onScale(e){
//只有是自動設定縮放的情況才需要檢查
if(this.checkAnimalEnd){
  this.closeTimer();//每次縮放回調先關閉定時器
  this.timer();//開啟定時器
}
//do something
...
},
//關閉定時器
closeTimer() {
  if
(this.intervalTimer) clearInterval(this.intervalTimer); }, //定時器檢測縮放和拖動是否結束 timer() { //使用interval定時器 this.intervalTimer = setInterval(()=>{ console.log('setInterval'); this.closeTimer(); //do something .... }, 500); },

問題2: 移動端是沒有雙擊事件的,如何解決?
這個網路上都有很多種方案了,現在我是使用下面這種方式實現的,同上面的定時器方案類似,就是給單擊事件掛載到一個延時器中,然後在檢查到使用者進行了雙擊操作就取消單擊事件延時器。否則就執行單擊事件,具體程式碼如下:

//params.oneTap=》執行單擊事件
//params.dbTap =》執行雙擊事件
checkTap(params = {}) {
  let nowTime = new Date().getTime();
  if (nowTime - this.lastClickTime < 300) {
    /*雙擊*/
    this.lastClickTime = 0;
    this.clickTimer && clearTimeout(this.clickTimer);

    console.log('雙擊');
    typeof params.dbTap === 'function' && params.dbTap();

  } else {
    /*單擊*/
    this.lastClickTime = nowTime;
    this.clickTimer = setTimeout(() => {
      console.log('單擊');

      typeof params.oneTap === 'function' && params.oneTap();
    }, 300);
  }
},
//點選moveable-view事件
onTap(e) {
  let that = this;
  this.checkTap({
    //oneTap: a => { this.oneTap(e) },
    dbTap: this.dbTap
  });
},

問題3: transform-scale用於縮放元素的話,會導致子元素被等比例縮放了,如何解決?
這個確實困擾了我好久,一開始是給子元素設定了初始尺寸,然後縮放後,針對width和height進行計算。結果不太理想。後來同樣是使用transform-scale反向縮放回去了。具體做法如下:

<!--注意看{{這裡的寫法}}-->
<movable-area style="width: 100%;height:100%;">
    <movable-view style="width: 1500px;height: 1500px;" scale scale-min="0.5" scale-max="2" scale-value="{{scale}}">
        <view style="transform: scale({{1/scale}});">我是子元素啊</view>
    </movable-view>
</movable-area>

問題4: 如何判斷使用者點選那個區塊,進而跳轉二級頁面做出不同的響應?
這個其實就是判斷下使用者點選的位置是否在一個多邊形內。
具體原理這裡不做討論了,在網上找到一個講的很不錯的部落格,我用的就是方案1,請認真看下原理在翻到第二篇看原始碼。
指路=》https://blog.csdn.net/u283056051/article/details/53980832

因此,我們要做的就是將圖片中每個不規則版塊的臨界點位置描出來儲存在一個二維陣列即可解決。

以上,是我在開發該小程式中遇到的幾個我自己感覺比較有難度的問題以及解決方案,如果你有不同的解決方案,歡迎留言告知。

最後,謝謝閱讀!