/**
 * wx-cropper 2.0
 * 基于微信小程序的图片裁剪工具
 * @author ifmiss
 */

// 裁剪图片的宽度设置
const CROPPER_WIDTH = 720

// 裁剪显示的最大比例，如果裁剪的图片过长，则做限制，默认最大宽高比例为 宽640 / 高960 (宽高比例)
const CROPPER_RATIO = 0.7

/**
 * 初始化裁剪的比例 如果是正方形则是 1
 * 比例为宽高比 建议区间为 0.25 - 4
 * 设置为0的时候则是不固定宽高
 */
const CROPPER_AREA_RATIO = 1

// 裁剪的位置
let CUT_L, // 初始化拖拽元素的left值
  CUT_T, // 初始化拖拽元素的top值
  CUT_R, // 初始化拖拽元素的
  CUT_B, // 初始化拖拽元素的

  // 裁剪的宽度
  CUT_W, // 初始化拖拽元素的宽度
  CUT_H, //  初始化拖拽元素的高度

  // 拖拽相关
  PAGE_X, // 手按下的x位置
  PAGE_Y, // 手按下y的位置
  T_PAGE_X, // 手移动的时候x的位置
  T_PAGE_Y, // 手移动的时候Y的位置x

  // 图片比例
  IMG_RATIO,

  // 图片实际宽高
  IMG_REAL_W, // 图片实际的宽度
  IMG_REAL_H, // 图片实际的高度

  // 裁剪图片区域的信息
  CROPPER_IMG_W,
  CROPPER_IMG_H,

  // 移动的比例
  DRAFG_MOVE_RATIO = 750 / wx.getSystemInfoSync().windowWidth, //移动时候的比例,


  INIT_DRAG_POSITION = 0, // 初始化屏幕宽度和裁剪区域的宽度之差，用于设置初始化裁剪的宽度

  DRAW_IMAGE_W, // 设置生成的图片宽度

  // 最大可显示得图片宽度，需要设定最大值，否则安卓部分机器会闪退, 控制qualityWidth的最大值
  maxQW = 2550

/**
 * 最小裁剪宽度  由于设置了裁剪的UI样式，裁剪的宽高必须要有最小宽度，这个宽度是裁剪长或者宽的最短一方的宽度
 * 如 400 200
 * 那么如果只能设置为100的时候
 * 那么最小缩放到200 100的效果，之后只能放大不能缩小
 */
const MIN_CROPPER_DIS = 100
const app = getApp()



Page({
  /**
   * 页面的初始数据
   */
  data: {
    // 之后可以动态替换
    // imageSrc: 'http://www.bing.com/az/hprichbg/rb/BulgariaPerseids_ZH-CN11638911564_1920x1080.jpg',
    // imageSrc: 'http://www.bing.com/az/hprichbg/rb/BulgariaPerseids_ZH-CN11638911564_1920x1080.jpg',
    imageSrc: '/images/vcard.png',
    // 是否显示图片(在图片加载完成之后设置为true)
    isShowImg: false,

    // 初始化的宽高
    cropperInitW: CROPPER_WIDTH,
    cropperInitH: CROPPER_WIDTH,

    // 动态的宽高
    cropperW: CROPPER_WIDTH,
    cropperH: CROPPER_WIDTH,

    // 动态的left top值
    cropperL: 0,
    cropperT: 0,

    // 图片缩放值
    scaleP: 0,

    // 裁剪框 宽高
    cutL: 0,
    cutT: 0,
    cutB: 0,
    cutR: 0,

    qualityWidth: DRAW_IMAGE_W,

    innerAspectRadio: DRAFG_MOVE_RATIO
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (e) {
    this.setData({
      imageSrc: e.img
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    // 初始化
    this.loadImage();
  },

  /**
   * 选择本地图片
   * 基于底部中间的按钮的点击事件
   */
  getImage: function () {
    var _this = this
    wx.chooseImage({
      success: function (res) {
        _this.setData({
          isShowImg: false,
          imageSrc: res.tempFilePaths[0],
        })
        _this.loadImage();
      },
    })
  },

  /**
   * 初始化图片信息
   * 获取图片内容，并初始化裁剪框
   */
  loadImage: function () {
    var _this = this
    wx.showLoading({
      title: '图片加载中...',
    })

    wx.getImageInfo({
      src: _this.data.imageSrc,
      success: function success(res) {
        DRAW_IMAGE_W = IMG_REAL_W = res.width
        IMG_REAL_H = res.height
        IMG_RATIO = IMG_REAL_W / IMG_REAL_H

        let MIN_RANGE = IMG_REAL_W > IMG_REAL_H ? IMG_REAL_W : IMG_REAL_H

        // 用于设置图片的比例(以设置裁剪的比例，方便定位裁剪的left right top bottom)
        INIT_DRAG_POSITION = MIN_RANGE > INIT_DRAG_POSITION ? INIT_DRAG_POSITION : MIN_RANGE

        // 拿到裁剪位置
        let cropperPosition = _this.initCropperPosition(IMG_RATIO, CROPPER_WIDTH)

        // 根据图片的宽高显示不同的效果   保证图片可以正常显示  
        if (IMG_RATIO >= 1) {
          _this.setData({
            cropperW: CROPPER_WIDTH,
            cropperH: CROPPER_WIDTH / IMG_RATIO,
            // 初始化left right
            cropperL: Math.ceil((CROPPER_WIDTH - CROPPER_WIDTH) / 2),
            cropperT: 0,
            cutL: cropperPosition.left,
            cutT: cropperPosition.top,
            cutR: cropperPosition.right,
            cutB: cropperPosition.bottom,
            // 图片缩放值
            scaleP: IMG_REAL_W / CROPPER_WIDTH,
            qualityWidth: DRAW_IMAGE_W > maxQW ? maxQW : DRAW_IMAGE_W,
            innerAspectRadio: IMG_RATIO
          })
        } else {
          // 此时需要判断图片的比例以设定显示裁剪区域的比例
          // let cropper_real_ratio = CROPPER_RATIO > IMG_RATIO ? CROPPER_RATIO : IMG_RATIO

          if (CROPPER_RATIO > IMG_RATIO) {
            CROPPER_IMG_W = CROPPER_WIDTH / CROPPER_RATIO * IMG_RATIO
            CROPPER_IMG_H = CROPPER_WIDTH / CROPPER_RATIO
          } else {
            CROPPER_IMG_W = CROPPER_WIDTH
            CROPPER_IMG_H = CROPPER_IMG_W / IMG_RATIO
          }

          // 动态生成新的CROPPER的真实宽度 高度
          // CROPPER_IMG_W = CROPPER_WIDTH * cropper_real_ratio
          // CROPPER_IMG_H = CROPPER_WIDTH / cropper_real_ratio / IMG_RATIO
          // console.log(cropper_real_ratio)
          // console.log(CROPPER_IMG_W)
          // console.log(CROPPER_IMG_H)
          // console.log(CROPPER_IMG_W / CROPPER_IMG_H)

          _this.setData({
            cropperW: CROPPER_IMG_W,
            cropperH: CROPPER_IMG_H,
            // 初始化left right
            cropperL: Math.ceil((CROPPER_WIDTH - CROPPER_IMG_W) / 2),
            cropperT: 0,

            cutL: cropperPosition.left,
            cutT: cropperPosition.top,
            cutR: cropperPosition.right,
            cutB: cropperPosition.bottom,
            // 图片缩放值
            scaleP: IMG_REAL_W / CROPPER_IMG_W,
            qualityWidth: DRAW_IMAGE_W > maxQW ? maxQW : DRAW_IMAGE_W,
            innerAspectRadio: IMG_RATIO
          })
        }
        _this.setData({
          isShowImg: true
        })
        wx.hideLoading()
      }
    })
  },

  /**
   * 初始化裁剪区域的
   * left right top bottom
   * 需要 CROPPER_AREA_RATIO 来判断
   * @return 返回裁剪的left, right, top bottom的值
   */
  initCropperPosition(radio) {
    let left = 0,
      right = 0,
      top = 0,
      bottom = 0,
      cropperW,
      cropperH
    // 如果 CROPPER_AREA_RATIO = 0 则不限制固定宽高 
    if (CROPPER_AREA_RATIO === 0) return {
      left,
      right,
      top,
      bottom
    }

    // 宽大于等于高
    if (radio >= 1) {
      cropperW = CROPPER_WIDTH
      cropperH = CROPPER_WIDTH / IMG_RATIO
      if (radio > CROPPER_AREA_RATIO) {
        return {
          left: Math.ceil((cropperW - cropperH * CROPPER_AREA_RATIO) / 2),
          right: Math.ceil((cropperW - cropperH * CROPPER_AREA_RATIO) / 2),
          top: 0,
          bottom: 0
        }
      }
      return {
        left: 0,
        right: 0,
        top: Math.ceil((cropperH - cropperW / CROPPER_AREA_RATIO) / 2),
        bottom: Math.ceil((cropperH - cropperW / CROPPER_AREA_RATIO) / 2)
      }
    }

    // 此时需要判断图片的比例以设定显示裁剪区域的比例
    let cropper_real_ratio = CROPPER_RATIO > IMG_RATIO ? CROPPER_RATIO : IMG_RATIO
    // 高大于宽
    cropperW = CROPPER_WIDTH / cropper_real_ratio * IMG_RATIO
    cropperH = CROPPER_WIDTH / cropper_real_ratio
    if (radio < CROPPER_AREA_RATIO) {
      return {
        left: 0,
        right: 0,
        top: Math.ceil((cropperH - cropperW / CROPPER_AREA_RATIO) / 2),
        bottom: Math.ceil((cropperH - cropperW / CROPPER_AREA_RATIO) / 2)
      }
    }
    return {
      left: Math.ceil((cropperW - cropperH * CROPPER_AREA_RATIO) / 2),
      right: Math.ceil((cropperW - cropperH * CROPPER_AREA_RATIO) / 2),
      top: 0,
      bottom: 0
    }
  },

  /**
   * 拖动时候触发的touchStart事件
   */
  contentStartMove(e) {
    PAGE_X = e.touches[0].pageX
    PAGE_Y = e.touches[0].pageY
  },

  /**
   * 拖动时候触发的touchMove事件
   */
  contentMoveing(e) {
    var _this = this
    var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
    var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO * DRAFG_MOVE_RATIO

    // 左移右移
    if (dragLengthX > 0) {
      if (this.data.cutL - dragLengthX < 0) dragLengthX = this.data.cutL
    } else {
      if (this.data.cutR + dragLengthX < 0) dragLengthX = -this.data.cutR
    }


    // 上移下移
    if (dragLengthY > 0) {
      if (this.data.cutT - dragLengthY < 0) dragLengthY = this.data.cutT
    } else {
      if (this.data.cutB + dragLengthY < 0) dragLengthY = -this.data.cutB
    }
    this.setData({
      cutL: this.data.cutL - dragLengthX,
      cutT: this.data.cutT - dragLengthY,
      cutR: this.data.cutR + dragLengthX,
      cutB: this.data.cutB + dragLengthY
    })


    PAGE_X = e.touches[0].pageX
    PAGE_Y = e.touches[0].pageY
  },

  contentTouchEnd() {

  },

  /**
   * 点击取消关闭裁剪页面
   */
  close() {
    // wx.redirectTo()
  },

  /**
   * 点击完成之后
   * 生成图片信息
   */
  getImageInfo() {
    var _this = this
    wx.showLoading({
      title: '图片生成中...',
    })
    // 将图片写入画布
    const ctx = wx.createCanvasContext('myCanvas')
    let w = this.data.qualityWidth
    let h = this.data.qualityWidth / IMG_RATIO
    ctx.drawImage(_this.data.imageSrc, 0, 0, w, h);
    ctx.draw(true, () => {
      // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题
      var canvasW = ((_this.data.cropperW - _this.data.cutL - _this.data.cutR) / _this.data.cropperW) * w
      var canvasH = ((_this.data.cropperH - _this.data.cutT - _this.data.cutB) / _this.data.cropperH) * h
      var canvasL = (_this.data.cutL / _this.data.cropperW) * w
      var canvasT = (_this.data.cutT / _this.data.cropperH) * h

      // 生成图片
      wx.canvasToTempFilePath({
        x: canvasL,
        y: canvasT,
        width: canvasW,
        height: canvasH,
        destWidth: canvasW,
        destHeight: canvasH,
        quality: 0.5,
        canvasId: 'myCanvas',
        success: function (res) {
          wx.hideLoading()
          app.Upload(res.tempFilePath, function (res) {
            if (res.code == 0) {
              app.AjaxRequest('POST', {
                'content-type': 'application/json',
                'Authorization': 'Bearer ' + app.Getopenid()
              }, '/user/profile/update', {
                avatar: res.fileName
              }, function (ret) {
                wx.navigateBack()
              })
            }
          })
        }
      })
    })
  },

  /**
   * 设置大小的时候触发的touchStart事件
   * 存数据
   */
  dragStart(e) {
    T_PAGE_X = e.touches[0].pageX
    T_PAGE_Y = e.touches[0].pageY
    CUT_L = this.data.cutL
    CUT_R = this.data.cutR
    CUT_B = this.data.cutB
    CUT_T = this.data.cutT
  },

  /**
   * 设置大小的时候触发的touchMove事件
   * 根据dragType判断类型
   * 4个方向的边线拖拽效果
   * 右下角按钮的拖拽效果
   */
  dragMove(e) {
    var _this = this
    var dragType = e.target.dataset.drag
    switch (dragType) {
      case 'right':
        var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
        if (CUT_R + dragLength < 0) dragLength = -CUT_R
        if (CUT_R + dragLength + MIN_CROPPER_DIS > this.data.cropperW - this.data.cutL) dragLength = (this.data.cropperW - this.data.cutL) - MIN_CROPPER_DIS - CUT_R

        if (CROPPER_AREA_RATIO) {
          // 底部线的限制 不允许超出
          // dragLength 最大不能超过CUT_B
          if (CUT_B + dragLength / CROPPER_AREA_RATIO <= 0) {
            this.setData({
              cutB: 0
            })
            return
          }
          this.setData({
            cutR: CUT_R + dragLength,
            cutB: CUT_B + dragLength / CROPPER_AREA_RATIO
          })
        } else {
          this.setData({
            cutR: CUT_R + dragLength
          })
        }

        break;
      case 'left':
        var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
        if (CUT_L - dragLength < 0) dragLength = CUT_L
        if ((CUT_L - dragLength + MIN_CROPPER_DIS) > (this.data.cropperW - this.data.cutR)) dragLength = CUT_L - (this.data.cropperW - this.data.cutR) + MIN_CROPPER_DIS

        if (CROPPER_AREA_RATIO) {
          // 顶部线的限制 不允许超出
          // dragLength 最大不能超过CUT_T
          if (CUT_T - dragLength / CROPPER_AREA_RATIO < 0) {
            this.setData({
              cutT: 0
            })
            return
          }
          this.setData({
            cutL: CUT_L - dragLength,
            cutT: CUT_T - dragLength / CROPPER_AREA_RATIO
          })
        } else {
          this.setData({
            cutL: CUT_L - dragLength
          })
        }
        break;
      case 'top':
        var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
        if (CUT_T - dragLength < 0) dragLength = CUT_T
        if ((CUT_T - dragLength + MIN_CROPPER_DIS) > this.data.cropperH - this.data.cutB) dragLength = CUT_T - (this.data.cropperH - this.data.cutB) + MIN_CROPPER_DIS

        if (CROPPER_AREA_RATIO) {
          // left 线的限制 不允许超出
          // dragLength 最大不能超过CUT_L
          if (CUT_L - dragLength * CROPPER_AREA_RATIO < 0) {
            this.setData({
              cutL: 0
            })
            return
          }
          this.setData({
            cutL: CUT_L - dragLength * CROPPER_AREA_RATIO,
            cutT: CUT_T - dragLength
          })
        } else {
          this.setData({
            cutT: CUT_T - dragLength
          })
        }
        break;
      case 'bottom':
        var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
        if (CUT_B + dragLength < 0) dragLength = -CUT_B
        if (CUT_B + dragLength + MIN_CROPPER_DIS > this.data.cropperH - this.data.cutT) dragLength = (this.data.cropperH - this.data.cutT) - MIN_CROPPER_DIS - CUT_B

        if (CROPPER_AREA_RATIO) {
          // right 线的限制 不允许超出
          // dragLength 最大不能超过 CUT_R
          if (CUT_R + dragLength * CROPPER_AREA_RATIO < 0) {
            this.setData({
              cutR: 0
            })
            return
          }
          this.setData({
            cutR: CUT_R + dragLength * CROPPER_AREA_RATIO,
            cutB: CUT_B + dragLength
          })
        } else {
          this.setData({
            cutB: CUT_B + dragLength
          })
        }
        break;
      case 'rightBottom':
        var dragType = e.target.dataset.drag
        var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
        var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
        if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B
        if (CUT_B + dragLengthY + MIN_CROPPER_DIS > this.data.cropperH - this.data.cutT) dragLengthY = (this.data.cropperH - this.data.cutT) - MIN_CROPPER_DIS - CUT_B
        if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R
        if (CUT_R + dragLengthX + MIN_CROPPER_DIS > this.data.cropperW - this.data.cutL) dragLengthX = (this.data.cropperW - this.data.cutL) - MIN_CROPPER_DIS - CUT_R

        if (CROPPER_AREA_RATIO) {
          // right 线的限制 不允许超出
          // dragLength 最大不能超过 CUT_R
          if (CUT_R + dragLengthY * CROPPER_AREA_RATIO < 0) {
            this.setData({
              cutR: 0
            })
            return
          }
          this.setData({
            cutR: CUT_R + dragLengthY * CROPPER_AREA_RATIO,
            cutB: CUT_B + dragLengthY
          })
        } else {
          this.setData({
            cutB: CUT_B + dragLengthY,
            cutR: CUT_R + dragLengthX
          })
        }
        break;
      default:
        break;
    }
  }
})