小程序圖片剪裁

一個微信小程序圖片剪裁組件,能夠經過手勢控制旋轉縮放移動,也能夠點擊旋轉進行90度旋轉,先看下效果(視屏不知道爲啥用不了,上個壓縮過分的GIF先),也能夠微信掃一掃下方小程序碼體驗進入 》打印》圖片打印體驗下效果                  css

      圖片剪裁毫無疑問用的是canvas,可是開發太小程序的同窗應該瞭解小程序canvas的一些坑。好比小程序canvas的設定了畫布的大小後不能像web的canvas那樣經過css樣式來調整畫布在手機上顯示的大小、還有canvas不能設置太大由於可能會在某些安卓機上致使小程序崩潰、canvas繪製過大的圖片會讓小程序變得很是卡頓等等。git

  網上能找到的圖片剪裁框架大多采用在canvas上面直接繪製圖片,而後經過監聽canvas上的用戶手勢來控制圖片移動旋轉等,這樣截出來的圖片會出現模糊的問題,由於canvas的過小了。一種解決方法是,在頁面上再放置一個隱藏的canvas大小設爲原來的兩倍或者再大一點也行用來做爲實際剪裁圖片的canvas,固然剪裁數據都是從第一個canvas那裏來的。可是這樣仍是有些小問題,就是canvas繪製大的圖片會出現卡頓的問題,這種方案在監聽用戶手勢的變化的時候要不停的從新繪製canvas,卡頓變得更加嚴重,體驗很是很差。github

  基於上面緣由,我採用的是view裏面放置圖片,監聽view上面的手勢,經過css樣式控制圖片的旋轉、縮放和移動,最後剪裁用隱藏的canvas。先看下頁面佈局:web

<view class="container">
  <!--  剪裁框與初始圖片,剪裁框監聽用戶手勢,獲取移動縮放旋轉值,images經過css樣式顯示變化  -->
  <view class="img" style="width:{{ width }}px; height:{{height}}px" catchtouchstart="touchstartCallback"  catchtouchmove="touchmoveCallback" catchtouchend="touchendCallback"  >
    <image style="transform: translate({{stv.offsetX}}px, {{stv.offsetY}}px) scale({{stv.scale}}) rotate({{ stv.rotate }}deg);width:{{originImg.width}}px; height: {{originImg.height}}px" src="{{ originImg.url }}"></image>
  </view>
  <view class='footer'>
      <view bindtap='uploadTap'>選擇圖片</view> 
      <view bindtap='rotate'>旋轉</view>
      <view bindtap='cropperImg'>剪裁</view>
  </view>

  <!--  canvas長寬設爲初始圖片設置的長款的兩倍,使剪裁獲得的圖片更清晰,也不至於過大  -->
  <canvas class='imgcrop' style="width:{{ width * 2 }}px;height:{{ height * 2}}px;" canvas-id='imgcrop'></canvas>
</view>

  最重要的操做是圖片在view中的位置變化如何在canvas中保持一致再剪裁出來,圖片相對與view中的左上角座標、圖片的長度和寬度咱們都是知道的,還有旋轉值經過用戶手勢變化計算出來,旋轉的時候將畫布的中心移動到圖片的中心點再旋轉就好了。canvas

 1       let ctx = wx.createCanvasContext('imgcrop',this);
 2       let cropData = _this.data.stv;
 3       ctx.save();
 4       // 縮放偏移值
 5       let x = (_this.data.originImg.width - _this.data.originImg.width * cropData.scale) / 2;
 6       let y = (_this.data.originImg.height - _this.data.originImg.height * cropData.scale) / 2;
 7 
 8       //畫布中點座標轉移到圖片中心
 9       let movex = (cropData.offsetX + x) * 2 + _this.data.originImg.width * cropData.scale;
10       let movey = (cropData.offsetY + y) * 2 + _this.data.originImg.height * cropData.scale;
11       ctx.translate(movex, movey);
12       ctx.rotate(cropData.rotate * Math.PI / 180);
13       ctx.translate(-movex, -movey);
14       
15       ctx.drawImage(_this.data.originImg.url, (cropData.offsetX + x) * 2, (cropData.offsetY + y) * 2, _this.data.originImg.width * 2 * cropData.scale, _this.data.originImg.height * 2 * cropData.scale);
16       ctx.restore();

  查看完整代碼請移步到:https://github.com/yuanwyj/Mini-Program-cropper, 喜歡的畫點個start~~
小程序

相關文章
相關標籤/搜索