微信小程序實現圖片放大縮小,並截取指定區域圖片

要在小程序中實現圖片放大縮小是着實不容易呀,還要把用戶選擇的指定區域生成圖片,簡直令人髮指。

不多說,上燒雞(代碼)

首先還是先來看看要實現的效果

這裏寫圖片描述

用戶可以在指定的區域中滑動,放大,縮小自己的圖片,點擊確定之後,把方框中的區域生成圖片。這個和上傳頭像功能差不多。

首頁我們要做的就是怎麼才能讓照片完美的顯示在頁面。圖片一般分爲橫版和豎版圖片,這兩種情況要分開顯示。

wx.chooseImage({
      count: 1, 
      sizeType: ['original'], 
      success: function (res) {
        wx.getImageInfo({
          src: res.tempFilePaths[0],
          success: function (res) {
            //console.log(res.width);
            //console.log(res.height);
            var str = res.width / res.height;
            if(str > 1){//橫版圖片

            }else{//豎版圖片

            }
          }
        })
      }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

調用wx.getImageInfo方法,拿到用戶選擇的圖片的寬高,用寬除以高就可以判斷圖片的類型了。

接下來就是處理圖片的寬高了,假設方框的大小是400*400,那麼:

wx.chooseImage({
      count: 1, 
      sizeType: ['original'], 
      success: function (res) {
        wx.getImageInfo({
          src: res.tempFilePaths[0],
          success: function (res) {
            //console.log(res.width);
            //console.log(res.height);
            var str = res.width / res.height;//圖片的寬高比
            if(str > 1){//橫版圖片
              _this.data.height = 400;//圖片的顯示高度爲400
              _this.data.width = str  * _this.data.height; //圖片的寬度 = 寬高比 * 圖片的顯示高度

            }else{//豎版圖片
              _this.data.width = 400;//圖片的顯示寬度爲400
              _this.data.height = str  * _this.data.width; //圖片的高度 = 寬高比 * 圖片的顯示寬度
            }
          }
        })
      }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

這樣,當是橫版圖片的時候,用戶能左右滑動自己的圖片,上下不讓他滑動,豎版同理。

關於怎麼讓圖片和方框居中顯示,我是用的padding填充,不是啥難事,這個就自己去摸索吧。

完成了圖片的顯示之後,接下來就是進入正題了,首先我們先完成圖片的放大縮小功能。

在小程序中提供了touchstart,touchmove,touchend這三個方法,分別是手指觸摸動作開始,手指觸摸後移動,手指觸摸動作結束,我們要用到這三個方法來完成圖片的放大縮小功能。

wxml:

<scroll-view scroll-y="true" scroll-x="true" class = "FilePath" bindtouchmove="scroll" bindtouchstart='scroll' bindtouchend='endTou'>
    <image src='{{src}}' style="width: {{width}}px;height: {{height}}px;" bindtouchmove="touch"></image>
  </scroll-view>
  • 1
  • 2
  • 3

監聽手指觸摸的方法:

olddistance,//上一次兩個手指的距離
newdistance:"",//本次兩手指之間的距離,兩個一減咱們就知道了滑動了多少,以及放大還是縮小(正負嘛)  
diffdistance:'', //這個是新的比例,新的比例一定是建立在舊的比例上面的,給人一種連續的假象  
Scale: 1,//圖片放大的比例,
baseHeight:'',       //原始高  
baseWidth:'',        //原始寬  

//手指在屏幕上移動
scroll: function (e) {
    var _this = this;
    //當e.touches.length等於1的時候,表示是單指觸摸,我們要的是雙指
    if (e.touches.length == 2) {//兩個手指滑動的時候
      var xMove = e.touches[1].clientX - e.touches[0].clientX;//手指在x軸移動距離
      var yMove = e.touches[1].clientY - e.touches[0].clientY;//手指在y軸移動距離
      var distance = Math.sqrt(xMove * xMove + yMove * yMove);//根據勾股定理算出兩手指之間的距離  
      if (_this.data.olddistance == 0) {
        _this.data.olddistance = distance; //要是第一次就給他弄上值,什麼都不操作  
       // console.log("第一次");
      }else {
        _this.data.newdistance = distance; //第二次就可以計算它們的差值了  
        _this.data.diffdistance = _this.data.newdistance - _this.data.olddistance;//兩次差值
        _this.data.olddistance = _this.data.newdistance; //計算之後更新比例  
        _this.data.Scale = _this.data.oldscaleA + 0.005 * _this.data.diffdistance;//這條公式是我查閱資料後找到的,按照這條公式計算出來的比例來處理圖片,能給用戶比較好的體驗
        if (_this.data.Scale > 2.5){//放大的最大倍數
          return;
        } else if (_this.data.Scale < 1) {//縮小不能小於當前
          return;
        }
        //刷新.wxml ,每次相乘,都是乘以圖片的顯示寬高
        _this.setData({
          height: _this.data.baseHeight * _this.data.Scale,
          width: _this.data.baseWidth * _this.data.Scale
        })
        _this.data.oldscaleA = _this.data.Scale;//更新比例 


      }  
    }
  },
  //手指離開屏幕
  endTou: function (e) {
   this.data.olddistance = 0;//重置
   this.getRect();
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

getRect()是我用來獲取節點信息的方法,用於得到wx.canvasToTempFilePath方法的座標點。(不懂得朋友可以點進去看看)

getRect: function () {
    var _this = this;
    wx.createSelectorQuery().select('.FilePath').boundingClientRect(function (rect) {
              _this.data.x = Math.abs(rect.left);//x座標
              _this.data.y = Math.abs(rect.top);//y座標
              }).exec()
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

wx.createSelectorQuery()可以獲取到節點的信息。

估計看到這裏有人就蒙了,其實rect.left和rect.top分別是節點的左邊界座標和節點的上邊界座標,這個座標可以視爲偏移量,就是說’.FilePath’這個節點也就是我放圖片的標籤往左邊和上邊偏移了多少,再取他們的絕對值,就得到了我們需要的座標點了。

接下來就是最後一步了,我們要來截取圖片,

wxml:

<canvas canvas-id="myCanvas_A" style="width: {{width}}px;height: {{height}}px;"/>
  • 1

js:

generate: function () {
    var _this = this;
    const ctx_A = wx.createCanvasContext('myCanvas_A');
   var baseWidth = _this.data.baseWidth * _this.data.Scale;//圖片放大之後的寬
    var baseHeight = _this.data.baseHeight * _this.data.Scale;//圖片放大之後的高
    ctx_A.drawImage(_this.data.src, 0, 0, baseWidth, baseHeight);//我們要在canvas中畫一張和放大之後的圖片寬高一樣的圖片
    ctx_A.draw();
     wx.showToast({
      title: '截取中...',
      icon: 'loading',
      duration: 10000
    });//
    setTimeout(function(){//給延時是因爲canvas畫圖需要時間
      wx.canvasToTempFilePath({//調用方法,開始截取
        x: _this.data.x,
        y: _this.data.y,
        width: 400,
        height: 400,
        destWidth: 400,
        destHeight: 400,
        canvasId: 'myCanvas_A',
        success: function (res) {
          console.log(res.tempFilePath);
        }
      })
    }, 2000)

  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

終於,世界都安靜了,完成!!!!!!!!!!

我該開始接到這個任務的時候,我的內心其實是挺崩潰的,後來靜下心來,一個功能一個功能的慢慢來,最終,還是弄出來了,挺開心的。

弄出來之後,發現其實也不難,只要處理好了圖片的縮放,其他的都不是啥難事,就是調試的時候特別坑爹,只能在手機上調試,在控制檯打了很多輸出,慢慢看着來弄的。

總結:

圖片的縮放就是監聽用戶雙指滑動的距離,在通過公式得到比例,然後拿這個比例和圖片的基本寬高相乘就可以了。截取圖片這個就很簡單了,就是wx.canvasToTempFilePath的開始座標這個我是廢了一番腦子纔想到方法取得的。世上無難事,只怕有心人啊。

再廢話一句,這個頁面的功能的實現,可頁面的樣式也是有關的喲。照片的寬高,照片父節點的寬高。。。


轉自:http://blog.csdn.net/yang7789/article/details/78933734

發佈了30 篇原創文章 · 獲贊 42 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章