该文件主要执行分享前的裁剪
微信后台的download安全域名别忘记设置,否则上线后不能剪切
小程序内是图片是HTTP的要想办法换成https
一.介绍使用
1.基本使用
以商品详情为例:
template view class="container" !-- n个布局 -- view wx:if="{{cutData.imageInfor}}" canvas style="width:{{cutData.imageInfor.width}}px;height:{{cutData.imageInfor.height}}px;display:{{cutData.showCanvas ? 'block':'none'}};" canvas-id="cropper"/canvas !-- 为了看裁剪效果,实际可以没有此元素 -- !-- image src="{{cutData.savedFilePath}}"/image -- /view /view/templatescriptimport cut from '../../utils/cut';export default class ProductDetail extends wepy.page { // 分享事件,暂时没有做回调事件 onShareAppMessage() { let info = wx.getStorageSync(USER_INFO); return { title: this.product.baseInfo.name, imageUrl: this.cutData.savedFilePath, path: "/pages/mine/white_page?pid=" + this.product.baseInfo.productId + "&source=" + info.userId, success: function(res) { // 转发成功 console.log('转发成功'); }, fail: function(res) { // 转发失败 console.log('转发失败'); } }; } config = { navigationBarTitleText: "商品详情" }; data = { product: {}, cutData:{ // 分享剪切处理 imageInfor:null, savedFilePath:'', showCanvas:true, // 初始显示canvas,若初始不显示canvas会裁剪报错 } }; methods = { // 分享事件,显示分享按钮 handleShare() { console.log(1111); wx.showShareMenu({ withShareTicket: true }); }, }; // 页面加载事件 onLoad(option) { // 前面n个操作 this.getData(); } async getData(pid , shop) { // 前面n个操作 let res = await getProductDetail(params); if (res.data.code == 200) { this.product = res.data.data; this.isError = false; // 执行裁剪 this._myCut(); } else if(res.data.code == 500) { // ... } else { this.isError = true; } this.$apply(); } // 参见方法,每次onload都运行 _myCut() { if (!this.product.headPics) { return ; } cut.cut(this.product.headPics[0].imgUrl,'cropper' ,imageInfor = { // 得到待分享图片的信息 this.cutData.imageInfor = imageInfor; this.$apply(); } ,savedFilePath = { // 获取保存到本地的图片信息 this.cutData.savedFilePath = savedFilePath; // 将canvas隐藏,不影响页面布局 this.cutData.showCanvas = false; this.$apply(); // 清除本地存储的文件列表,但是不包含本次生成的文件 cut.clearSavedFileList(this.cutData.savedFilePath); } ); };}/scriptstyle lang="less"/style2.注意
- 在_myCut函数中,得到本地保存路径后的回调内应将canvas隐藏,防止被用户看到
- 放canvas的view应该放在页面最底部,防止初始出现的时候被用户看到
- 在得到本地保存路径后的回调内应将微信内保存的其他savedFileList删除,这里如果自己存放了其他资源,可以选择修改cut.js的clearSavedFileList方法.
- 之所以不在onShareAppMessage方法内之间裁剪(也就是用户点击了分享或者转发才裁剪),是因为onShareAppMessage方法要求返回一个对象,cut.js采用回调实现,cut中的cut方法中回调的值不能被onShareAppMessage拿到,所以放在了getData方法中
二.介绍实现
1.实现
cut.js
export default { // 裁剪方法 cut(url,canvasId,imageInforCB,savedFilePathCB) { let that = this; const ctx = wx.createCanvasContext('cropper'); that._getImageInfor(url,ctx,canvasId,imageInforCB,savedFilePathCB); }, // 删除本地存储数据 clearSavedFileList(currSavedFilePath) { wx.getSavedFileList({ success: function(res) { for (let i=0;ires.fileList.length;i++) { if (currSavedFilePath !== res.fileList[i].filePath) { wx.removeSavedFile({ filePath: res.fileList[i].filePath, complete: function(res) { console.log('本地图片删除结束',res); } }); } } } }); }, // 获取图片信息 _getImageInfor(url,ctx,canvasId,imageInforCB,savedFilePathCB) { let that = this; wx.getImageInfo({ src: url, success: function (imageInfor) { console.log('getImageInfo2',imageInfor); imageInforCB(imageInfor); // 将图画到canvas上 that._drawImage(ctx,imageInfor,()={ that._getTempFilePath(canvasId,imageInfor,savedFilePathCB); }); }, fail: function(res) { console.log('getImageInfo fail',res); }, complete:function(res) { console.log('getImageInfo complete',res); } }); }, // 在canvas上画图 _drawImage(ctx,imageInfor,cb) { ctx.drawImage(imageInfor.path,0,0,imageInfor.width,imageInfor.height); ctx.draw(false,()={ console.log('绘制完成'); cb(); }); }, // 使用canvas剪裁,后获取临时本地路径, _getTempFilePath(canvasId,imageInfor,savedFilePathCB) { let that = this; let cutData = that._computedCutData(imageInfor); console.log('cutData',cutData); wx.canvasToTempFilePath({ x: cutData.x, y: cutData.y, width: imageInfor.width, height: imageInfor.height, destWidth: cutData.destWidth, destHeight: cutData.destHeight, canvasId: canvasId, success: function(res) { console.log('canvasToTempFilePath res',res); that._saveImage(res.tempFilePath,savedFilePathCB); }, fail: function(res) { console.log('canvasToTempFilePath fail',res); }, complete:function(res) { console.log('canvasToTempFilePath complete',res); } }); }, // 将_getTempFilePath得到的临时路径保存到本地 _saveImage(tempFilePath,savedFilePathCB) { wx.saveFile({ tempFilePath: tempFilePath, success: function (res) { let savedFilePath = res.savedFilePath; console.log('savedFilePath',res); savedFilePathCB(savedFilePath); }, fail:function() { console.log('saveFile,fail'); }, complete:function() { console.log('saveFile,complete'); } }); }, // 计算裁剪数据,目前由长宽1:1裁成长宽比5:4的图片,裁剪公式 (h-(w/5*4))/2 _computedCutData(imageInfor) { let cutData = { x:0, // canvas剪切左上角x坐标 y:0, // canvas剪切左上角y坐标 destWidth:0, // 图片裁剪宽度 destHeight:0 // 图片裁剪高度 }; let cutY = (imageInfor.height-(imageInfor.width/5*4))/2; cutData.y = cutY; cutData.x = 0; cutData.destWidth = imageInfor.width; cutData.destHeight = imageInfor.height - cutY*2; return cutData; }}2.注意
1.剪裁前要讲图片画到canvas上,因为调用了canvas的canvasToTempFilePath方法
2.注意cut.js中clearSavedFileList方法是清除除了本次生成的图片之外的所有微信小程序savedFileList,如不希望,可以修改此方法
3._computedCutData是计算裁剪数据,图片将按照得到的结果裁剪,
4.本cut.js的_computedCutData裁剪尺寸是图片宽度不变,高度上下各裁剪掉宽度的十分之一
5.wx.canvasToTempFilePath方法要在draw的回调函数中运行才会正确得到结果
5.canvas的display:none;会触发wx.canvasToTempFilePath失败,因此应该首先canvas的display:block,当本地保存路径得到后再display:none即可
三.补充(2018/5/25)
上线之后发现图片剪裁出现问题,当图片宽高都超出2000的时候,不知道为何,小程序闪退,所以这里做了修改,添加了如下方法:
此方法在_getImageInfor方法中调用,保证图片在1000以下
// 重新设定图片宽高比例,因为小程序一裁剪宽高2000左右的就闪退,这里限制到1000以下 _resetImageSize(imageInfor) { let result = imageInfor; while(result.width 1000 && result.height 1000) { result.width = result.width / 2; result.height = result.height / 2; } return result; }小程序













