亲宝软件园·资讯

展开

微信小程序裁剪头像插件

想吃番茄的西红柿 人气:0

用户上传头像,需要裁剪成正方形,结合在网上找到裁剪图片方法,封装为微信小程序组件。调用很方便。

参数介绍:

wxml调用:

<cutImage imageUrl="{{image_url}}" bind:returnImageUrl="returnImageUrl"  wx:if="{{showCutImage}}" >
</cutImage>

js调用:

returnImageUrl: function (e) {
    //e.detail.imageUrl,e.detail.showCutImage  
}

wxml代码:

<view class='fixed-upimg'>
  <view class="wx-content-info" >
    <view class="iamge-box" style="width:100%;height:{{imageBoxHeight}}px;">
      <image style="height:{{imageHeight}}px;width:{{imageWidth}}px;" src="{{imageUrl}}"></image>
      <view class="wx-corpper-crop-box" bindtouchstart="contentStartMove" bindtouchmove="contentMoveing" style="width:{{cutW}}px;height:{{cutH}}px;left:{{cutL}}px;top:{{cutT}}px">
        <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>
    <canvas canvas-id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}px;height:{{imageH}}px;top:-9999px;left:-9999px;"></canvas>
    <view  class='button-tjtp' bindtap="getImageInfo" style="position:fixed;bottom:0rpx;"> 提交图片 </view>
  </view>
</view>

wxss代码:

.button-tjtp{
  width: 300rpx;
  height: 45px;
  border-radius: 50rpx;
  color: #151D37;
  background-color: #fff;
  margin: 20px 225rpx;
  font-size: 30rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}
.fixed-upimg{
    position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #000;
  z-index: 9999;
}
.wx-content-info{
  position: fixed;
  top: 0rpx;
  left: 0;
  right: 0;
  bottom: 0;
 
}
.iamge-box{
  display: flex;
  justify-content: center;
  align-items: center;
}


.wx-corpper-crop-box{
    position: absolute;
    width: 500rpx;
    height: 500rpx;
    background: rgba(255,255,255,0.3);
    z-index: 2;
}
.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;
}

js代码:

var pageX = 0
// 拖动时候的 pageY
var pageY = 0
// 移动时 手势位移与 实际元素位移的比
var dragScaleP = 2
var pixelRatio = wx.getSystemInfoSync().pixelRatio
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    imageUrl:{
      type:String,
      value:''
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    imageBoxHeight:0,
    windowWidth: 0,
    imageUrl:''
  },
  lifetimes: {
    // 生命周期函数,可以为函数,或一个在methods段中定义的方法名
    attached: function () {
      this.getSysInfo();
      this.getImageDetail();
    },
  },
  created: function () {
    this.getSysInfo();
  },
  /**
   * 组件的方法列表
   */
  methods: {
    // 获取设备信息
    getSysInfo () { 
      wx.getSystemInfo({
        success: (res) => {
          console.log(res)
          this.setData({
            imageBoxHeight: res.windowHeight - 85,
            windowWidth: res.windowWidth
          })
        },
      })
    },
    getImageDetail(){
      wx.getImageInfo({
        src: this.data.imageUrl,
        success: (res) => {
          this.setData({
            imageW: res.width / 2,
            imageH: res.height / 2
          })
          if (res.width >= res.height) {
            var h = (res.height * this.data.windowWidth) / res.width;
            this.setData({
              imageWidth: this.data.windowWidth,
              imageHeight: h,
              cutW: h,
              cutH: h,
              cutL: (this.data.windowWidth - h) / 2,
              cutT: (this.data.imageBoxHeight - h) / 2
            })
          } else {
            var w = (this.data.imageBoxHeight * res.width) / res.height;
            this.setData({
              imageWidth: w,
              imageHeight: this.data.imageBoxHeight,
              cutW: w,
              cutH: w,
              cutL: (this.data.windowWidth - w) / 2,
              cutT: (this.data.imageBoxHeight - w) / 2
            })
          }
        }
      })
    },
    // 拖动时候触发的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)
      var dragLengthY = (pageY - e.touches[0].pageY)
      var minX = Math.max(_this.data.cutL - (dragLengthX), 0)
      var minY = Math.max(_this.data.cutT - (dragLengthY), 0)
      var maxX = _this.data.imageWidth - _this.data.cutW
      var maxY = _this.data.imageHeight - _this.data.cutH
      if (_this.data.imageWidth == _this.data.cutW) {
        this.setData({
          cutT: Math.min(maxY, minY),
        })
      } else if (_this.data.imageHeight == _this.data.cutH) {
        this.setData({
          cutL: Math.min(maxX, minX)
        })
      }
      console.log(`${maxX} ----- ${minX}`)
      pageX = e.touches[0].pageX
      pageY = e.touches[0].pageY
    },
    // 拖动时候触发的touchStart事件
    contentStartMove(e) {
      pageX = e.touches[0].pageX
      pageY = e.touches[0].pageY
    },
    // 裁剪图片
    getImageInfo() {
      var _this = this
      console.log('shengcheng:' + _this.data.imageUrl)
      wx.showLoading({
        title: '图片生成中...',
      })
      // wx.downloadFile({
      //   url:_this.data.imageSrc, //仅为示例,并非真实的资源     
      //   success: function (res) {
      // 将图片写入画布             
      const ctx = wx.createCanvasContext('myCanvas', _this)
      // ctx.drawImage(res.tempFilePath)
      ctx.drawImage(_this.data.imageUrl, 0, 0, _this.data.imageW, _this.data.imageH)

      ctx.draw(true, () => {
        // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题
        var canvasW = (_this.data.cutW / _this.data.imageWidth) * (_this.data.imageW)
        var canvasH = (_this.data.cutH / _this.data.imageHeight) * (_this.data.imageH)
        var canvasL, canvasT;
        if (_this.data.imageHeight == _this.data.imageBoxHeight) {
          canvasL = (0 / _this.data.imageWidth) * (_this.data.imageW)
        } else {
          canvasL = (_this.data.cutL / _this.data.imageWidth) * (_this.data.imageW)
        }
        if (_this.data.imageWidth == _this.data.windowWidth) {
          canvasT = (0 / _this.data.imageHeight) * (_this.data.imageH)
        } else {
          canvasT = (_this.data.cutT / _this.data.imageHeight) * (_this.data.imageH)
        }
        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) {
            // 成功获得地址的地方
            var tempFilePath = res.tempFilePath;
            wx.hideLoading()
            _this.returnImageUrl(tempFilePath)
            

          },
          fail: function (res) {
            console.log(res)
            wx.hideLoading()
            wx.showModal({
              content: '抱歉,图片上传失败!图片过大可能导致图片上传失败!',
              showCancel: false,
              confirmText: '我知道了',
              confirmColor: "#151D37",
              success: function (res) {
                if (res.confirm) {
                  _this.setData({
                    imageFixed: false,
                    tempFilePath: res.tempFilePath
                  })
                }
              }
            })
          }
        }, _this)
      })
    },
    returnImageUrl: function (url) {
      this.triggerEvent('returnImageUrl', {
        imageUrl: url,
        showCutImage:false
      })
    }
  }
})

加载全部内容

相关教程
猜你喜欢
用户评论