微信小程序图片裁剪
// pages/wx-cropper/index.js// 手机的宽度var windowWRPX = 750// 拖动时候的 pageXvar pageX = 0// 拖动时候的 pageYvar pageY = 0var pixelRatio = wx.getSystemInfoSync().pixelRatio// 调整大小时候的 pageXvar sizeConfPageX = 0// 调整大小时候的 pageYvar sizeConfPageY = 0var initDragCutW = 0var initDragCutL = 0var initDragCutH = 0var initDragCutT = 0var qualityWidth = 1080var innerAspectRadio = 1// 移动时 手势位移与 实际元素位移的比var dragScaleP = 2Page({ /** * 页面的初始数据 */ data: { // imageSrc: 'https://lpd.hi-finance.com.cn/20170918001.jpg', // 'https://lpd.hi-finance.com.cn/9019013.png' imageSrc: 'https://lpd.hi-finance.com.cn/20170918001.jpg', returnImage: '', isShowImg: false, // 初始化的宽高 cropperInitW: windowWRPX, cropperInitH: windowWRPX, // 动态的宽高 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 }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { // this.loadImage(); }, 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) { innerAspectRadio = res.width / res.height; // 根据图片的宽高显示不同的效果 保证图片可以正常显示 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 200) / 2), cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 200)) / 2), // 图片缩放值 scaleP: res.width * pixelRatio / windowWRPX, // 图片原始宽度 rpx imageW: res.width * pixelRatio, imageH: res.height * pixelRatio, innerAspectRadio: innerAspectRadio }) } 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 - 50, cutH: 200, cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 50)) / 2), cutT: Math.ceil((windowWRPX - 200) / 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) wx.previewImage({ current: '', // 当前显示图片的http链接 urls: [res.tempFilePath] // 需要预览的图片http链接列表 }) } }) }) }, // 设置大小的时候触发的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: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { }})