小程序圖片預覽裁剪插件

最近在幫工作室做一個小程序,在換背景圖的時候需要預覽圖片,並且需要裁剪成固定的尺寸。因爲小程序並不支持原生的dom操作,導致很多現有的插件都無法使用,所以花了半天專門做了一個小程序的預覽裁剪插件。下面貼上代碼和效果圖。

wxml:
<canvas hidden='{{hide_canvas}}' id='cover-preview' bindtouchstart='canvas_start' bindtouchmove='canvas_move' bindtouchend='canvas_end' disable-scroll='true' canvas-id='cover-preview'>
    <cover-view catchtap='upload_bg' id='croper-sure'>確定</cover-view>
    <cover-view catchtap='cancel_croper' id='croper-cancel'>取消</cover-view>
    <cover-view id='croper'></cover-view>
 </canvas> 
    注意:canvas裏面一定要用cover-view,否則無法覆蓋canvas

js:
const ctx = wx.createCanvasContext('cover-preview');
var start_position = {};//移動圖片時手指起始座標
var tempFilePath;//圖片路徑
var tempWidth;//圖片初始寬度
var tempHeight;//圖片初始高度
var old_x = 0;//圖片初始x座標
var old_y = 0;//圖片初始y座標
var _touches = 1;//觸屏的手指數
var old_scale = 1;//原始放大倍數
var new_scale = 1;//新的放大倍數
var is_move = false;//是否移動
var bg_url;
Page({
data: {
 hide_canvas:true,//繪圖層顯示控制變量
},
//選擇並將圖片輸出到canvas
change_cover:function(){
    var that = this;
    wx.showModal({
      title: '提示',
      content: '更改我的封面',
      confirmColor: '#39bae8',
      success: function (res) {
        if (res.confirm) {
          
         
          wx.chooseImage({
            count: 1, // 默認9
            sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有
            sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有
            success: function (res0) {
              
              tempFilePath = res0.tempFilePaths[0];
              that.setData({
                hide_canvas: false,
                // edit_url: tempFilePath
              })
              wx.getImageInfo({
                src: tempFilePath,
                success: function (res) {
                  // console.log(res.width)
                  // console.log(res.height)
                  tempWidth = res.width;
                  tempHeight = res.height;
                  ctx.drawImage(tempFilePath,0, 0, 375,res.height/res.width*375);
                  ctx.draw();
                }
              })
              
            }
          })
        } else if (res.cancel) {
          console.log('用戶點擊取消')
        }
      }
    })
  },
  //監聽手指觸摸事件,並判斷是移動還是縮放,並記錄初始狀態
  canvas_start:function(e){
    // console.log(e);
    var touches = e.touches.length;
    if(touches == 1){
      _touches = 1;
      start_position = { x: e.touches[0].x, y: e.touches[0].y, timeStamp:e.timeStamp}
    }else if(touches == 2){
      _touches = 2;
      start_position = { x: e.touches[0].x, y: e.touches[0].y,x1: e.touches[1].x, y1: e.touches[1].y, timeStamp: e.timeStamp }
    }else{
      _touches = 1;
    }
  },
  //監聽手指移動事件,並做出相應調整
  canvas_move: function (e) {
    // console.log(e);
    var touches = e.touches.length;
    if (_touches == 1 && e.timeStamp - start_position.timeStamp > 150) {
      ctx.drawImage(tempFilePath, old_x + e.touches[0].x - start_position.x, old_y + e.touches[0].y - start_position.y, 375 * new_scale, tempHeight / tempWidth * 375 * new_scale);
      ctx.draw();
      is_move = true;
    } else if (_touches == 2 && e.timeStamp - start_position.timeStamp > 150) {
      var change_x = Math.abs(Math.abs(e.touches[0].x - e.touches[1].x) - Math.abs(start_position.x - start_position.x1));
      var change_y = Math.abs(Math.abs(e.touches[0].y - e.touches[1].y) - Math.abs(start_position.y - start_position.y1));
      if(change_x - change_y > 10){
        old_scale = Math.abs(e.touches[0].x - e.touches[1].x) / Math.abs(start_position.x - start_position.x1);
      }else{
        old_scale = Math.abs(e.touches[0].y - e.touches[1].y) / Math.abs(start_position.y - start_position.y1);
      }
      ctx.drawImage(tempFilePath, old_x, old_y, 375 * old_scale * new_scale, tempHeight / tempWidth * 375 * old_scale * new_scale);
      ctx.draw();
      is_move = true;
    }else{
      is_move = false;
    }
  },
  //監聽手指離開動作,並保存當前狀態數據
  canvas_end: function (e) {
    // console.log(e);
    if (_touches == 1 && is_move) {
      old_x = old_x + e.changedTouches[0].x - start_position.x;
      old_y = old_y + e.changedTouches[0].y - start_position.y;
    } else if (_touches == 2 && is_move) {
      new_scale = old_scale * new_scale;
    }
    
  },
  //確定並上傳背景圖
  upload_bg:function(){
    var that = this;
    var screenWidth = wx.getSystemInfoSync().screenWidth;
    // console.log(screenWidth);
    wx.canvasToTempFilePath({
      x: 0,
      y: screenWidth / 750 * 400,
      width: screenWidth,
      height: screenWidth / 750 * 526,
      destWidth: screenWidth,
      screenHeight: screenWidth / 750 * 526,
      quality:1,
      canvasId: 'cover-preview',
      success: function (res) {
        that.setData({
          hide_canvas: true,
        })
        //res.tempFilePath即爲生成的圖片路徑
        console.log(res.tempFilePath)
        
      }
    })
  },
  //取消圖片預覽編輯
  cancel_croper:function(){
    ctx.clearActions();
    this.setData({
      hide_canvas: true,
      // edit_url: tempFilePath
    })
  },
})

wxss:
#cover-preview{
  width: 100%;
  height: 100%;
  background-color: black;
}
#croper{
  width: 750rpx;
  height: 526rpx;
  position: absolute;
  top: 400rpx;
  left: 0;
  background-color: rgba(135,206,250,0.5);
}

#croper-sure{
  width: 120rpx;
  height: 50rpx;
  border-radius: 10rpx;
  color: black;
  background-color: rgba(135,206,250,0.8);
  font-size: 40rpx;
  position: absolute;
  top: 946rpx;
  right: 10rpx;
  text-align: center
}
#croper-cancel{
  width: 120rpx;
  height: 50rpx;
  border-radius: 10rpx;
  color: black;
  background-color: rgba(135,206,250,0.8);
  font-size: 40rpx;
  position: absolute;
  top: 946rpx;
  right: 150rpx;
  text-align: center
}
效果圖


demo中可對圖片進行移動和縮放,點擊確定後,將截取藍色半透明框裏的內容,並生成圖片

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章