(微信,支付宝)小程序头像上传选择裁剪区域

<!--微信小程序 -->
<view>
<view bindtap='upEwm'>
  <view>头像</view>
  <image style='width:200rpx;height:200rpx;background-color:red' src='{{headImg}}'></image>
</view>
</view>

<!--裁剪图片浮层-->
<view class='fixed-upimg' wx:if="{{imageFixed}}">
  <view class="wx-content-info">
    <view wx:if="{{isShowImg}}" class="wx-corpper" style="width:{{cropperInitW}}rpx;height:{{cropperInitH}}rpx;background:#000">
      <view bindtap='upLoad' class="wx-corpper-content" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx;left:{{cropperL}}rpx;top:{{cropperT}}rpx">
        <image src="{{imageSrc}}" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx"></image>
        <view class="wx-corpper-crop-box" bindtouchstart="contentStartMove" bindtouchmove="contentMoveing" style="width:{{cutW}}rpx;height:{{cutH}}rpx;left:{{cutL}}rpx;top:{{cutT}}rpx">
          <view class="wx-cropper-view-box">
            <view class="wx-cropper-dashed-h"></view>
            <view class="wx-cropper-dashed-v"></view>
            <view class="wx-cropper-line-t" data-drag="top" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-line-r" data-drag="right" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-line-b" data-drag="bottom" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-line-l" data-drag="left" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-point point-t" data-drag="top" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-point point-tr" data-drag="topTight"></view>
            <view class="wx-cropper-point point-r" data-drag="right" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-point point-rb" data-drag="rightBottom" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-point point-b" data-drag="bottom" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-point point-bl" data-drag="bottomLeft"></view>
            <view class="wx-cropper-point point-l" data-drag="left" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>
            <view class="wx-cropper-point point-lt" data-drag="leftTop"></view>
          </view>
        </view>
      </view>
    </view>
    <canvas canvas-id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}rpx;height:{{imageH}}rpx;top:-9999px;left:-9999px;"></canvas>
    <button type="primary" bindtap="getImageInfo" style="position:fixed;bottom:120rpx;width:90%;left:50%;transform:translate3d(-50%,0,0)"> 确认提交 </button>
  </view>
</view>

  js 部分

// 手机的宽度
var windowWRPX = 750
// 拖动时候的 pageX
var pageX = 0
// 拖动时候的 pageY
var pageY = 0

var pixelRatio = wx.getSystemInfoSync().pixelRatio

// 调整大小时候的 pageX
var sizeConfPageX = 0
// 调整大小时候的 pageY
var sizeConfPageY = 0

var initDragCutW = 0
var initDragCutL = 0
var initDragCutH = 0
var initDragCutT = 0

// 移动时 手势位移与 实际元素位移的比
var dragScaleP = 2

Page({
  /**
   * 页面的初始数据
   */
  data: {
    imageNum: '', //上传的图片id
    headImg: '', //头像上传
    imageFixed: false, //裁剪浮层
    imageSrc: '', //要裁剪的图片
    returnImage: '',
    isShowImg: false,
    // 初始化的宽高
    cropperInitW: windowWRPX,
    cropperInitH: windowWRPX,
    // 动态的宽高
    cropperW: windowWRPX,
    cropperH: windowWRPX,
    // 动态的left top值
    cropperL: 0,
    cropperT: 0,

    // 图片缩放值
    scaleP: 0,
    imageW: 0,
    imageH: 0,

    // 裁剪框 宽高
    cutW: 400,
    cutH: 400,
    cutL: 0,
    cutT: 0,
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onReady: function(options) {},

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onLoad: function() {
    var _this = this
    wx.getImageInfo({
      src: _this.data.imageSrc,
      success: function success(res) {
        var innerAspectRadio = res.width / res.height;
        console.log(innerAspectRadio)
        // 根据图片的宽高显示不同的效果   保证图片可以正常显示
        if (innerAspectRadio >= 1) {
          _this.setData({
            cropperW: windowWRPX,
            cropperH: windowWRPX / innerAspectRadio,
            // 初始化left right
            cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),
            cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),
            // 裁剪框  宽高 
            // cutW: windowWRPX - 200,
            // cutH: windowWRPX / innerAspectRadio - 200,
            cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2),
            cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2),
            // 图片缩放值
            scaleP: res.width * pixelRatio / windowWRPX,
            // 图片原始宽度 rpx
            imageW: res.width * pixelRatio,
            imageH: res.height * pixelRatio
          })
        } else {
          _this.setData({
            cropperW: windowWRPX * innerAspectRadio,
            cropperH: windowWRPX,
            // 初始化left right
            cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),
            cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),
            // 裁剪框的宽高
            // cutW: windowWRPX * innerAspectRadio - 66,
            // cutH: 400,
            cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2),
            cutT: Math.ceil((windowWRPX - 340) / 2),
            // 图片缩放值
            scaleP: res.width * pixelRatio / windowWRPX,
            // 图片原始宽度 rpx
            imageW: res.width * pixelRatio,
            imageH: res.height * pixelRatio
          })
        }
        _this.setData({
          isShowImg: true
        })
      }
    })
  },

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

  // 拖动时候触发的touchMove事件
  contentMoveing(e) {
    var _this = this
    var dragLengthX = (pageX - e.touches[0].pageX) * dragScaleP
    var dragLengthY = (pageY - e.touches[0].pageY) * dragScaleP
    var minX = Math.max(_this.data.cutL - (dragLengthX), 0)
    var minY = Math.max(_this.data.cutT - (dragLengthY), 0)
    var maxX = _this.data.cropperW - _this.data.cutW
    var maxY = _this.data.cropperH - _this.data.cutH
    this.setData({
      cutL: Math.min(maxX, minX),
      cutT: Math.min(maxY, minY),
    })
    console.log(`${maxX} ----- ${minX}`)
    pageX = e.touches[0].pageX
    pageY = e.touches[0].pageY
  },

  // 获取图片
  getImageInfo() {
    var _this = this
    console.log('shengcheng:' + _this.data.imageSrc)
    wx.showLoading({
      title: '图片生成中...',
    })
    // wx.downloadFile({
    //   url:_this.data.imageSrc, //仅为示例,并非真实的资源     
    //   success: function (res) {
    // 将图片写入画布             
    const ctx = wx.createCanvasContext('myCanvas')
    ctx.drawImage(_this.data.imageSrc)

    ctx.draw(true, () => {
      // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题
      var canvasW = (_this.data.cutW / _this.data.cropperW) * (_this.data.imageW / pixelRatio)
      var canvasH = (_this.data.cutH / _this.data.cropperH) * (_this.data.imageH / pixelRatio)
      var canvasL = (_this.data.cutL / _this.data.cropperW) * (_this.data.imageW / pixelRatio)
      var canvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio)
      console.log(`canvasW:${canvasW} --- canvasH: ${canvasH} --- canvasL: ${canvasL} --- canvasT: ${canvasT} -------- _this.data.imageW: ${_this.data.imageW}  ------- _this.data.imageH: ${_this.data.imageH} ---- pixelRatio ${pixelRatio}`)
      wx.canvasToTempFilePath({
        x: canvasL,
        y: canvasT,
        width: canvasW,
        height: canvasH,
        destWidth: canvasW,
        destHeight: canvasH,
        canvasId: 'myCanvas',
        success: function(res) {
          wx.hideLoading()
          console.log('end:' + res.tempFilePath)
          _this.setData({
            imageFixed: false,
            headImg: res.tempFilePath
          })
        }
      })
    })
  },

  // 设置大小的时候触发的touchStart事件
  dragStart(e) {
    var _this = this
    sizeConfPageX = e.touches[0].pageX
    sizeConfPageY = e.touches[0].pageY
    initDragCutW = _this.data.cutW
    initDragCutL = _this.data.cutL
    initDragCutT = _this.data.cutT
    initDragCutH = _this.data.cutH
  },

  // 设置大小的时候触发的touchMove事件
  dragMove(e) {
    var _this = this
    var dragType = e.target.dataset.drag
    switch (dragType) {
      case 'right':
        var dragLength = (sizeConfPageX - e.touches[0].pageX) * dragScaleP
        if (initDragCutW >= dragLength) {
          // 如果 移动小于0 说明是在往下啦  放大裁剪的高度  这样一来 图片的高度  最大 等于 图片的top值加 当前图片的高度  否则就说明超出界限
          if (dragLength < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) {
            this.setData({
              cutW: initDragCutW - dragLength
            })
          }
          // 如果是移动 大于0  说明在缩小  只需要缩小的距离小于原本裁剪的高度就ok
          if (dragLength > 0) {
            this.setData({
              cutW: initDragCutW - dragLength
            })
          } else {
            return
          }
        } else {
          return
        }
        break;
      case 'left':
        var dragLength = (dragLength = sizeConfPageX - e.touches[0].pageX) * dragScaleP
        console.log(dragLength)
        if (initDragCutW >= dragLength && initDragCutL > dragLength) {
          if (dragLength < 0 && Math.abs(dragLength) >= initDragCutW) return
          this.setData({
            cutL: initDragCutL - dragLength,
            cutW: initDragCutW + dragLength
          })
        } else {
          return;
        }
        break;
      case 'top':
        var dragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP
        if (initDragCutH >= dragLength && initDragCutT > dragLength) {
          if (dragLength < 0 && Math.abs(dragLength) >= initDragCutH) return
          this.setData({
            cutT: initDragCutT - dragLength,
            cutH: initDragCutH + dragLength
          })
        } else {
          return;
        }
        break;
      case 'bottom':
        var dragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP
        // console.log(_this.data.cropperH > _this.data.cutT + _this.data.cutH)
        console.log(dragLength)
        console.log(initDragCutH >= dragLength)
        console.log(_this.data.cropperH > initDragCutT + _this.data.cutH)
        // 必须是 dragLength 向上缩小的时候必须小于原本的高度
        if (initDragCutH >= dragLength) {
          // 如果 移动小于0 说明是在往下啦  放大裁剪的高度  这样一来 图片的高度  最大 等于 图片的top值加 当前图片的高度  否则就说明超出界限
          if (dragLength < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) {
            this.setData({
              cutH: initDragCutH - dragLength
            })
          }
          // 如果是移动 大于0  说明在缩小  只需要缩小的距离小于原本裁剪的高度就ok
          if (dragLength > 0) {
            this.setData({
              cutH: initDragCutH - dragLength
            })
          } else {
            return
          }
        } else {
          return
        }
        break;
      case 'rightBottom':
        var dragLengthX = (sizeConfPageX - e.touches[0].pageX) * dragScaleP
        var dragLengthY = (sizeConfPageY - e.touches[0].pageY) * dragScaleP
        if (initDragCutH >= dragLengthY && initDragCutW >= dragLengthX) {
          // bottom 方向的变化
          if ((dragLengthY < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) || (dragLengthY > 0)) {
            this.setData({
              cutH: initDragCutH - dragLengthY
            })
          }
          // right 方向的变化
          if ((dragLengthX < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) || (dragLengthX > 0)) {
            this.setData({
              cutW: initDragCutW - dragLengthX
            })
          } else {
            return
          }
        } else {
          return
        }
        break;
      default:
        break;
    }
  },
  // 图片上传
  upLoad: function() {

  },
  upEwm() {
    var _this = this
    wx.chooseImage({
      count: 1, // 默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function(res) {
        var tempFilePaths = res.tempFilePaths[0];
        console.log('shangchuan:' + tempFilePaths)
        _this.setData({
          imageFixed: true,
          imageSrc: tempFilePaths
        })
        // start
        wx.getImageInfo({
          src: _this.data.imageSrc,
          success: function success(res) {
            var innerAspectRadio = res.width / res.height;
            console.log('bili' + innerAspectRadio)
            // 根据图片的宽高显示不同的效果   保证图片可以正常显示
            if (innerAspectRadio == '1') {
              _this.setData({
                imageFixed: false,
                headImg: tempFilePaths.join()
              })
            } else if (innerAspectRadio > 1) {
              _this.setData({
                cropperW: windowWRPX,
                cropperH: windowWRPX / innerAspectRadio,
                // 初始化left right
                cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),
                cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),
                // 裁剪框  宽高 
                // cutW: windowWRPX - 200,
                // cutH: windowWRPX / innerAspectRadio - 200,
                cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2),
                cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2),
                // 图片缩放值
                scaleP: res.width * pixelRatio / windowWRPX,
                // 图片原始宽度 rpx
                imageW: res.width * pixelRatio,
                imageH: res.height * pixelRatio
              })
            } else {
              _this.setData({
                cropperW: windowWRPX * innerAspectRadio,
                cropperH: windowWRPX,
                // 初始化left right
                cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),
                cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),
                // 裁剪框的宽高
                // cutW: windowWRPX * innerAspectRadio - 66,
                // cutH: 400,
                cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2),
                cutT: Math.ceil((windowWRPX - 340) / 2),
                // 图片缩放值
                scaleP: res.width * pixelRatio / windowWRPX,
                // 图片原始宽度 rpx
                imageW: res.width * pixelRatio,
                imageH: res.height * pixelRatio
              })
            }
            _this.setData({
              isShowImg: true
            })
            wx.hideLoading()
          }
        })
      }
    })
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {

  }
})

  css 部分

/* pages/wx-cropper/index.wxss */
.fixed-upimg{
    position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #fff;
}
.wx-content-info{
  position: fixed;
  top: 130rpx;
  left: 0;
  right: 0;
  bottom: 0;
 
}
 
.wx-corpper{
  position: relative;
  overflow: hidden;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  box-sizing: border-box;
}
 
.wx-corpper-content{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
 
.wx-corpper-content image {
    display: block;
    width: 100%;
    min-width: 0 !important;
    max-width: none !important;
    height: 100%;
    min-height: 0 !important;
    max-height: none !important;
    image-orientation: 0deg !important;
    margin: 0 auto;
}
 
/* 移动图片效果 */
.wx-cropper-drag-box{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    cursor: move;
    background: rgba(0,0,0,0.6);
    z-index: 1;
}
 
/* 内部的信息 */
.wx-corpper-crop-box{
    position: absolute;
    width: 500rpx;
    height: 500rpx;
    background: rgba(255,255,255,0.3);
    z-index: 2;
}
 
.wx-corpper-crop-box .wx-cropper-view-box {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
    outline: 1px solid #69f;
    outline-color: rgba(102, 153, 255, .75)
}
 
/* 横向虚线 */
.wx-cropper-dashed-h{
    position: absolute;
    top: 33.33333333%;
    left: 0;
    width: 100%;
    height: 33.33333333%;
    border-top: 1px dashed rgba(255,255,255,0.5);
    border-bottom: 1px dashed rgba(255,255,255,0.5);
}
 
/* 纵向虚线 */
.wx-cropper-dashed-v{
    position: absolute;
    left: 33.33333333%;
    top: 0;
    width: 33.33333333%;
    height: 100%;
    border-left: 1px dashed rgba(255,255,255,0.5);
    border-right: 1px dashed rgba(255,255,255,0.5);
}
 
/* 四个方向的线  为了之后的拖动事件*/
.wx-cropper-line-t{
    position: absolute;
    display: block;
    width: 100%;
    background-color: #69f;
    top: 0;
    left: 0;
    height: 1px;
    opacity: 0.1;
    cursor: n-resize;
}
 
.wx-cropper-line-t::before{
  content: '';
  position: absolute;
  top: 50%;
  right: 0rpx;
  width: 100%;
  -webkit-transform: translate3d(0,-50%,0);
  transform: translate3d(0,-50%,0);
  bottom: 0;
  height: 41rpx;
  background: transparent;
  z-index: 11;
}
 
.wx-cropper-line-r{
    position: absolute;
    display: block;
    background-color: #69f;
    top: 0;
    right: 0px;
    width: 1px;
    opacity: 0.1;
    height: 100%;
    cursor: e-resize;
}
.wx-cropper-line-r::before{
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 41rpx;
  -webkit-transform: translate3d(-50%,0,0);
  transform: translate3d(-50%,0,0);
  bottom: 0;
  height: 100%;
  background: transparent;
  z-index: 11;
}
 
.wx-cropper-line-b{
    position: absolute;
    display: block;
    width: 100%;
    background-color: #69f;
    bottom: 0;
    left: 0;
    height: 1px;
    opacity: 0.1;
    cursor: s-resize;
}
 
.wx-cropper-line-b::before{
  content: '';
  position: absolute;
  top: 50%;
  right: 0rpx;
  width: 100%;
  -webkit-transform: translate3d(0,-50%,0);
  transform: translate3d(0,-50%,0);
  bottom: 0;
  height: 41rpx;
  background: transparent;
  z-index: 11;
}
 
.wx-cropper-line-l{
    position: absolute;
    display: block;
    background-color: #69f;
    top: 0;
    left: 0;
    width: 1px;
    opacity: 0.1;
    height: 100%;
    cursor: w-resize;
}
.wx-cropper-line-l::before{
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 41rpx;
  -webkit-transform: translate3d(-50%,0,0);
  transform: translate3d(-50%,0,0);
  bottom: 0;
  height: 100%;
  background: transparent;
  z-index: 11;
}
 
.wx-cropper-point{
    width: 5px;
    height: 5px;
    background-color: #69f;
    opacity: .75;
    position: absolute;
    z-index: 3;
}
 
.point-t{
    top: -3px;
    left: 50%;
    margin-left: -3px;
    cursor: n-resize;
}
 
.point-tr{
    top: -3px;
    left: 100%;
    margin-left: -3px;
    cursor: n-resize;
}
 
.point-r{
    top: 50%;
    left:100%;
    margin-left: -3px;
    margin-top: -3px;
    cursor: n-resize;
}
 
.point-rb{
    left: 100%;
    top: 100%;
    -webkit-transform: translate3d(-50%,-50%,0);
    transform: translate3d(-50%,-50%,0);
    cursor: n-resize;
    width: 24rpx;
    height: 24rpx;
    background-color: #69f;
    position: absolute;
    z-index: 1112;
    opacity: 1;
}
 
.point-b{
    left:50%;
    top: 100%;
    margin-left: -3px;
    margin-top: -3px;
    cursor: n-resize;
}
 
.point-bl{
    left:0%;
    top: 100%;
    margin-left: -3px;
    margin-top: -3px;
    cursor: n-resize;
}
 
.point-l{
    left:0%;
    top: 50%;
    margin-left: -3px;
    margin-top: -3px;
    cursor: n-resize;
}
 
.point-lt{
    left:0%;
    top: 0%;
    margin-left: -3px;
    margin-top: -3px;
    cursor: n-resize;
}
 
/* 裁剪框预览内容 */
.wx-cropper-viewer{
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
 
.wx-cropper-viewer image{
  position: absolute;
  z-index: 2;
}

  支付宝小程序

<!--图片展示 -->
<view>
<view onTap='upEwm'>
  <view>头像</view>
  <image style='width:200rpx;height:200rpx;background-color:red' src='{{headImg}}'></image>
</view>
</view>

<!--裁剪图片浮层-->
<view class='fixed-upimg' a:if="{{imageFixed}}">
  <view class="wx-content-info">
    <view a:if="{{isShowImg}}" class="wx-corpper" style="width:{{cropperInitW}}rpx;height:{{cropperInitH}}rpx;background:#000">
      <view onTap='upLoad' class="wx-corpper-content" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx;left:{{cropperL}}rpx;top:{{cropperT}}rpx">
        <image src="{{imageSrc}}" style="width:{{cropperW}}rpx;height:{{cropperH}}rpx"></image>
        <view class="wx-corpper-crop-box" onTouchStart="contentStartMove" onTouchMove="contentMoveing" style="width:{{cutW}}rpx;height:{{cutH}}rpx;left:{{cutL}}rpx;top:{{cutT}}rpx">
          <view class="wx-cropper-view-box">
            <view class="wx-cropper-dashed-h"></view>
            <view class="wx-cropper-dashed-v"></view>
            <view class="wx-cropper-line-t" data-drag="top" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-line-r" data-drag="right" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-line-b" data-drag="bottom" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-line-l" data-drag="left" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-point point-t" data-drag="top" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-point point-tr" data-drag="topTight"></view>
            <view class="wx-cropper-point point-r" data-drag="right" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-point point-rb" data-drag="rightBottom" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-point point-b" data-drag="bottom" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-point point-bl" data-drag="bottomLeft"></view>
            <view class="wx-cropper-point point-l" data-drag="left" catchTouchStart="dragStart" catchTouchMove="dragMove"></view>
            <view class="wx-cropper-point point-lt" data-drag="leftTop"></view>
          </view>
        </view>
      </view>
    </view>
    <canvas id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}rpx;height:{{imageH}}rpx;top:-9999px;left:-9999px;"></canvas>
    <button type="primary" onTap="getImageInfo" style="position:fixed;bottom:120rpx;width:90%;left:50%;transform:translate3d(-50%,0,0)"> 确认提交 </button>

  </view>
</view>

js

var windowWRPX = 750
// 拖动时候的 pageX
var pageX = 0
// 拖动时候的 pageY
var pageY = 0

var pixelRatio = my.getSystemInfoSync().pixelRatio
console.log(pixelRatio)
// 调整大小时候的 pageX
var sizeConfPageX = 0
// 调整大小时候的 pageY
var sizeConfPageY = 0

var initDragCutW = 0
var initDragCutL = 0
var initDragCutH = 0
var initDragCutT = 0

// 移动时 手势位移与 实际元素位移的比
var dragScaleP = 2

Page({
  data: {
    imageNum: '', //上传的图片id
    headImg: '', //头像上传
    ewmImg: '', //二维码上传
    imageFixed: false, //裁剪浮层
    //imageSrc: 'http://topmdrt-static.oss-cn-shenzhen.aliyuncs.com/images/testimg2.jpeg',
    imageSrc: '', //要裁剪的图片
    returnImage: '',
    isShowImg: false,
    // 初始化的宽高
    cropperInitW: windowWRPX,
    cropperInitH: windowWRPX,
    // 动态的宽高
    cropperW: windowWRPX,
    cropperH: windowWRPX,
    // 动态的left top值
    cropperL: 0,
    cropperT: 0,

    // 图片缩放值
    scaleP: 0,
    imageW: 0,
    imageH: 0,

    // 裁剪框 宽高
    cutW: 400,
    cutH: 400,
    cutL: 0,
    cutT: 0,
  },
  onLoad: function () {
    var _this = this
    my.getImageInfo({
      src: _this.data.imageSrc,
      success: function success(res) {
        console.log(res)
        var innerAspectRadio = res.width / res.height;
        console.log(innerAspectRadio)
        // 根据图片的宽高显示不同的效果   保证图片可以正常显示
        if (innerAspectRadio >= 1) {
          _this.setData({
            cropperW: windowWRPX,
            cropperH: windowWRPX / innerAspectRadio,
            // 初始化left right
            cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),
            cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),
            // 裁剪框  宽高 
            // cutW: windowWRPX - 200,
            // cutH: windowWRPX / innerAspectRadio - 200,
            cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2),
            cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2),
            // 图片缩放值
            scaleP: res.width * pixelRatio / windowWRPX,
            // 图片原始宽度 rpx
            imageW: res.width * pixelRatio,
            imageH: res.height * pixelRatio
          })
        } else {
          _this.setData({
            cropperW: windowWRPX * innerAspectRadio,
            cropperH: windowWRPX,
            // 初始化left right
            cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),
            cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),
            // 裁剪框的宽高
            // cutW: windowWRPX * innerAspectRadio - 66,
            // cutH: 400,
            cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2),
            cutT: Math.ceil((windowWRPX - 340) / 2),
            // 图片缩放值
            scaleP: res.width * pixelRatio / windowWRPX,
            // 图片原始宽度 rpx
            imageW: res.width * pixelRatio,
            imageH: res.height * pixelRatio
          })
        }
        _this.setData({
          isShowImg: true
        })
        my.hideLoading()
      }
    })
  },
  // 拖动时候触发的touchStart事件
  contentStartMove(e) {
    pageX = e.touches[0].pageX
    pageY = e.touches[0].pageY
  },
  // 拖动时候触发的touchMove事件
  contentMoveing(e) {
    var _this = this
    // _this.data.cutL + (e.touches[0].pageX - pageX)
     console.log(e.touches[0].pageX)
    // console.log(e.touches[0].pageX - pageX)
    var dragLengthX = (pageX - e.touches[0].pageX) * dragScaleP
    var dragLengthY = (pageY - e.touches[0].pageY) * dragScaleP
    var minX = Math.max(_this.data.cutL - (dragLengthX), 0)
    var minY = Math.max(_this.data.cutT - (dragLengthY), 0)
    var maxX = _this.data.cropperW - _this.data.cutW
    var maxY = _this.data.cropperH - _this.data.cutH
    this.setData({
      cutL: Math.min(maxX, minX),
      cutT: Math.min(maxY, minY),
    })
    console.log(`${maxX} ----- ${minX}`)
    pageX = e.touches[0].pageX
    pageY = e.touches[0].pageY
  },
  // 获取图片
  getImageInfo() {
    var _this = this
    console.log('shengcheng:' + _this.data.imageSrc)
    my.showLoading({
      title: '图片生成中...',
    })

    // 将图片写入画布             
    const ctx = my.createCanvasContext('myCanvas')
    console.log(1)

    my.getImageInfo({
      src:_this.data.imageSrc,
      success:(res)=>{
        console.log(res)
      }
    })
    console.log(11,_this.data.cropperW,_this.data.cropperH)
    ctx.drawImage(_this.data.imageSrc,0,0,_this.data.imageW/pixelRatio,_this.data.imageH/pixelRatio)
        var canvasW = (_this.data.cutW / _this.data.cropperW) * (_this.data.imageW / pixelRatio)
    var canvasH = (_this.data.cutH / _this.data.cropperH) * (_this.data.imageH / pixelRatio)
    var canvasL = (_this.data.cutL / _this.data.cropperW) * (_this.data.imageW / pixelRatio)
    var canvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio)
    console.log(`canvasW:${canvasW} --- canvasH: ${canvasH} --- canvasL: ${canvasL} --- canvasT: ${canvasT} -------- _this.data.imageW: ${_this.data.imageW}  ------- _this.data.imageH: ${_this.data.imageH} ---- pixelRatio ${pixelRatio}`)
    console.log(2)
    ctx.draw(true, function () {
      console.log(3, true)
      ctx.toTempFilePath({
          x: canvasL,
           y: canvasT,
           width: canvasW,
           height: canvasH,
           destWidth: canvasW,
           destHeight: canvasH,
        success: function (res) {
          my.hideLoading()
          // 成功获得地址的地方
          console.log(4, res)
          console.log('end:' + res.apFilePath)
          // 判断时上传头像还是二维码
          _this.setData({
            imageFixed: false,
            headImg: res.apFilePath
          })
        }
      })
    })

    console.log(5)
    //   }
    /*
   
   
     
    , () => {
         // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题
       
        
        
       }
    */

    // })
  },
  // 设置大小的时候触发的touchStart事件
  dragStart(e) {
    var _this = this
    sizeConfPageX = e.touches[0].pageX
    sizeConfPageY = e.touches[0].pageY
    initDragCutW = _this.data.cutW
    initDragCutL = _this.data.cutL
    initDragCutT = _this.data.cutT
    initDragCutH = _this.data.cutH
  },
  // 设置大小的时候触发的touchMove事件
  dragMove(e) {
    var _this = this
    var dragType = e.target.dataset.drag
    switch (dragType) {
      case 'right':
        var dragLength = (sizeConfPageX - e.touches[0].pageX) * dragScaleP
        if (initDragCutW >= dragLength) {
          // 如果 移动小于0 说明是在往下啦  放大裁剪的高度  这样一来 图片的高度  最大 等于 图片的top值加 当前图片的高度  否则就说明超出界限
          if (dragLength < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) {
            this.setData({
              cutW: initDragCutW - dragLength
            })
          }
          // 如果是移动 大于0  说明在缩小  只需要缩小的距离小于原本裁剪的高度就ok
          if (dragLength > 0) {
            this.setData({
              cutW: initDragCutW - dragLength
            })
          }
          else {
            return
          }
        } else {
          return
        }
        break;
      case 'left':
        var dragLength = (dragLength = sizeConfPageX - e.touches[0].pageX) * dragScaleP
        console.log(dragLength)
        if (initDragCutW >= dragLength && initDragCutL > dragLength) {
          if (dragLength < 0 && Math.abs(dragLength) >= initDragCutW) return
          this.setData({
            cutL: initDragCutL - dragLength,
            cutW: initDragCutW + dragLength
          })
        } else {
          return;
        }
        break;
      case 'top':
        var dragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP
        if (initDragCutH >= dragLength && initDragCutT > dragLength) {
          if (dragLength < 0 && Math.abs(dragLength) >= initDragCutH) return
          this.setData({
            cutT: initDragCutT - dragLength,
            cutH: initDragCutH + dragLength
          })
        } else {
          return;
        }
        break;
      case 'bottom':
        var dragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP
        // console.log(_this.data.cropperH > _this.data.cutT + _this.data.cutH)
        console.log(dragLength)
        console.log(initDragCutH >= dragLength)
        console.log(_this.data.cropperH > initDragCutT + _this.data.cutH)
        // 必须是 dragLength 向上缩小的时候必须小于原本的高度
        if (initDragCutH >= dragLength) {
          // 如果 移动小于0 说明是在往下啦  放大裁剪的高度  这样一来 图片的高度  最大 等于 图片的top值加 当前图片的高度  否则就说明超出界限
          if (dragLength < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) {
            this.setData({
              cutH: initDragCutH - dragLength
            })
          }
          // 如果是移动 大于0  说明在缩小  只需要缩小的距离小于原本裁剪的高度就ok
          if (dragLength > 0) {
            this.setData({
              cutH: initDragCutH - dragLength
            })
          }
          else {
            return
          }
        } else {
          return
        }
        break;
      case 'rightBottom':
        var dragLengthX = (sizeConfPageX - e.touches[0].pageX) * dragScaleP
        var dragLengthY = (sizeConfPageY - e.touches[0].pageY) * dragScaleP
        if (initDragCutH >= dragLengthY && initDragCutW >= dragLengthX) {
          // bottom 方向的变化
          if ((dragLengthY < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) || (dragLengthY > 0)) {
            this.setData({
              cutH: initDragCutH - dragLengthY
            })
          }

          // right 方向的变化
          if ((dragLengthX < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) || (dragLengthX > 0)) {
            this.setData({
              cutW: initDragCutW - dragLengthX
            })
          }
          else {
            return
          }
        } else {
          return
        }
        break;
      default:
        break;
    }
  },
  onShow: {},
  upEwm: function () {
    var _this = this
    my.chooseImage({
      count: 1, // 默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        console.log(res)
        // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
        var tempFilePaths = res.apFilePaths[0];
        // var mode = parseFloat(e.currentTarget.dataset.current);
        console.log('shangchuan:' + tempFilePaths)

        _this.setData({
          imageFixed: true,
          imageSrc: tempFilePaths
        })
        // start
        my.getImageInfo({
          src: _this.data.imageSrc,
          success: function success(res) {
            console.log('getImageInfo',res)
            var innerAspectRadio = res.width / res.height;
            console.log('bili' + innerAspectRadio)
            // 根据图片的宽高显示不同的效果   保证图片可以正常显示


            if (innerAspectRadio == '1') {
              _this.setData({
                imageFixed: false,
                 headImg: tempFilePaths.join()
              })
            } else if (innerAspectRadio > 1) {
              console.log(res.width ,pixelRatio)
              _this.setData({
                cropperW: windowWRPX,
                cropperH: windowWRPX / innerAspectRadio,
                // 初始化left right
                cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),
                cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),
                // 裁剪框  宽高 
                // cutW: windowWRPX - 200,
                // cutH: windowWRPX / innerAspectRadio - 200,
                cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2),
                cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2),
                // 图片缩放值
                scaleP: res.width * pixelRatio / windowWRPX,
                // 图片原始宽度 rpx
                imageW: res.width * pixelRatio,
                imageH: res.height * pixelRatio
              })
            } else {
              _this.setData({
                cropperW: windowWRPX * innerAspectRadio,
                cropperH: windowWRPX,
                // 初始化left right
                cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),
                cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),
                // 裁剪框的宽高
                // cutW: windowWRPX * innerAspectRadio - 66,
                // cutH: 400,
                cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2),
                cutT: Math.ceil((windowWRPX - 340) / 2),
                // 图片缩放值
                scaleP: res.width * pixelRatio / windowWRPX,
                // 图片原始宽度 rpx
                imageW: res.width * pixelRatio,
                imageH: res.height * pixelRatio
              })
            }
            _this.setData({
              isShowImg: true
            })
            // my.hideLoading()
          }
        })
      }
    })
  },

})


/*Page({
  data: {
    src: '/imgs/timg.jpg',
    height: 375,
    width: 375,
    windowWidth: '',
    kuang:{
      left:0,
      top:100
    }
  },
  onLoad(query) {
    // 页面加载
    my.setCanPullDown({
      canPullDown: false
    })
    //  my.getSystemInfo({
    //     success:function(res){
    //      windowWidth: res.windowWidth
    //     }
    //   })
    // 页面显示

    // console.info(my.getSystemInfoSync().windowHeight);
  },

  onReady() {
    // 页面加载完成
  },
  onMovableViewChange(e) {
    console.log(1, e)
  },
  onMovableViewChangeEnd(e) {
    console.log(2, e)
  },
  onShow() {
    let _this = this;

  },
  qq1() {
    let _t = this;
    var ctx = my.createCanvasContext('canvasid');
     ctx.setFillStyle('#fff');
    let path = _t.data.src;
    ctx.drawImage(path, 0, 0, _t.data.width, _t.data.height);//我们要在canvas中画一张和放大之后的图片宽高一样的图片
  // ctx.save();
    // ctx.setStrokeStyle('blue');
    // ctx.rect(0, 0, 200,200);
    // ctx.stroke();
    ctx.draw();
  },
  move(e){
    console.log(e.touches[0])
    var that = this;
    var canvasW = 200;
    var canvasH = 200;
    let touches =e.touches[0];
    var x = touches.x;
    var y = touches.y;
    that.setData({
      ['kuang.left']:x,
      ['kuang.top']:y
    })
  },
  //上传图片
  qq(e) {
    console.log(e)
    let _this = this;

    my.chooseImage({
      count: 1,
      sizeType: ['original'],
      success: function (res) {
        console.log(res)
        _this.setData({
          src: res.apFilePaths[0]
        })
        _this.aa(res.apFilePaths[0])
      }
    })
  },
  aa(q) {
    let _this = this;

    my.getImageInfo({
      src: q,
      success: (res) => {
        console.log(1, res)
        var str = res.width / res.height;

        console.log('width', str)
        if (str > 1) {
          console.log(11111)
          _this.setData({
            height: 200,
            width: str * 200
          })
        } else if (str < 1) {//竖版图片
        console.log(22222)
          _this.setData({
            width: 200,
            height: str * 200
          })
        } else if (str == 1) {
            console.log(33333)
           _this.setData({
            width: 200,
            height:200
          })
        }
      }
    })
  },

















  generate: function () {
    var _this = this;
    const ctx_A = my.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();
    my.showToast({
      title: '截取中...',
      icon: 'loading',
      duration: 10000
    });//
    setTimeout(function () {//给延时是因为canvas画图需要时间
      ctx_A.toTempFilePath({//调用方法,开始截取
        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)

  },
  onHide() {
    // 页面隐藏
  },
  onUnload() {
    // 页面被关闭
  },
  onTitleClick() {
    // 标题被点击
  },
  onPullDownRefresh() {
    // 页面被下拉
  },
  onReachBottom() {
    // 页面被拉到底部
  },
  onShareAppMessage() {
    // 返回自定义分享信息
    return {
      title: 'My App',
      desc: 'My App description',
      path: 'pages/index/index',
    };
  },
});
*/

猜你喜欢

转载自www.cnblogs.com/caoruichun/p/10505586.html