越来越多的微信小程序 拥有了自己的个人中心,既然有了个人中心 那就要有 头像了, 有些人不想用微信的头像来当做小程序的头像,于是有了下面的问题 头像上传, 以及截取头像.
这种方法 是比较简单的一种 下面是主要的JS 在文章最后有源码下载地址 直接放在小程序的page 里面打开即可查看效果
// pages/wx-cropper/index.jsvar network = require("../../utils/api.js").default// 手机的宽度var windowWRPX = 750// 拖动时候的 pageXvar pageX = 0// 拖动时候的 pageYvar pageY = 0var pixelRatio = wx.getSystemInfoSync().pixelRatio
// 调整大小时候的 pageXvar sizeConfPageX = 0// 调整大小时候的 pageYvar sizeConfPageY = 0
var initDragCutW = 0var initDragCutL = 0var initDragCutH = 0var initDragCutT = 0var qualityWidth = 1080var innerAspectRadio = 1// 移动时 手势位移与 实际元素位移的比var dragScaleP = 2
Page({ /** * 页面的初始数据 */ data: { // imageSrc: 'https://lpd.hi-finance.com.cn/20170918001.jpg', // 'https://lpd.hi-finance.com.cn/9019013.png' imageSrc: '', returnImage: '', isShowImg:true, // 初始化的宽高 cropperInitW: windowWRPX, cropperInitH: 92, // 动态的宽高 cropperW: windowWRPX, cropperH: windowWRPX, // 动态的left top值 cropperL: 0, cropperT: 0,
// 图片缩放值 scaleP: 0, imageW: 0, imageH: 0,
// 裁剪框 宽高 cutW: 0, cutH: 0, cutL: 0, cutT: 0, qualityWidth: qualityWidth, innerAspectRadio: innerAspectRadio, //要上传的img img:'' },
/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { console.log(options.img); this.setData({ imageSrc: options.img, }) this.loadImage(); },
/** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, getImage: function () {
var _this = this wx.chooseImage({ success: function (res) { _this.setData({ imageSrc: res.tempFilePaths[0], }) _this.loadImage(); }, }) // wx.showToast({ // title: 'sss', // }) }, loadImage: function () { var _this = this wx.showLoading({ title: '加载中...', })
wx.getImageInfo({ src: _this.data.imageSrc, // src:src, success: function success(res) { console.log(res); innerAspectRadio = res.width / res.height; // 根据图片的宽高显示不同的效果 保证图片可以正常显示 if (innerAspectRadio >= 1) { // 宽型图片就让高当边框 var width = windowWRPX / innerAspectRadio > 500 ? 500 : windowWRPX / innerAspectRadio; _this.setData({ cropperW: windowWRPX, cropperH: windowWRPX / innerAspectRadio, // 初始化left right // cropperL: Math.ceil((windowWRPX - windowWRPX) / 2), // cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2), // 裁剪框 宽高 cutW: width, cutH: width, cutL: Math.ceil((windowWRPX - width) / 2), cutT: Math.ceil((windowWRPX - width) / 2), // 图片缩放值 scaleP: res.width * pixelRatio / windowWRPX, // 图片原始宽度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio,
innerAspectRadio: innerAspectRadio }) } else { // 窄型图片居然跟宽当大小 var width = windowWRPX * innerAspectRadio > 500 ? 500 : windowWRPX * innerAspectRadio; _this.setData({ cropperW: windowWRPX , cropperH: windowWRPX/innerAspectRadio, // 初始化left right // cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2), // cropperT: Math.ceil((windowWRPX - windowWRPX) / 2), // 裁剪框的宽高 cutW:width, cutH: width, cutL: Math.ceil((windowWRPX - width) / 2), cutT: Math.ceil((windowWRPX - width) / 2), // 图片缩放值 scaleP: res.width * pixelRatio / windowWRPX, // 图片原始宽度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio,
innerAspectRadio: innerAspectRadio }) } _this.setData({ isShowImg: true }) wx.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
wx.showLoading({ title: '图片生成中...', }) // 将图片写入画布 const ctx = wx.createCanvasContext('myCanvas') ctx.drawImage(_this.data.imageSrc, 0, 0, qualityWidth, qualityWidth / innerAspectRadio); ctx.draw(true, () => { // 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题 canvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio) var canvasW = (_this.data.cutW / _this.data.cropperW) * qualityWidth var canvasH = (_this.data.cutH / _this.data.cropperH) * qualityWidth / innerAspectRadio var canvasL = (_this.data.cutL / _this.data.cropperW) * qualityWidth var canvasT = (_this.data.cutT / _this.data.cropperH) * qualityWidth / innerAspectRadio 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, quality:0.5, canvasId: 'myCanvas', success: function (res) { wx.hideLoading() // 成功获得地址的地方 console.log(res.tempFilePath) _this.setData({ img: res.tempFilePath, }) _this.upimg(); } }) }) }, upimg(){ var _this=this; var aa = {} network.upload('users/updateUsersInfo', _this.data.img, aa, function(data) { console.log(data) wx.switchTab({ url: '../user/user' }) }) }, // 设置大小的时候触发的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; } },
})
最后附上源码
链接:https://pan.baidu.com/s/1o03VV8Cw4WIOx7igCrGEKg 密码:ol96













