本人大四实习新入职,在入职一个星期后接触到了第一个项目。
因为是新手,在整个开发过程中遇到了较多的难点:主要是canvas绘图过程中,因为商品图片和二维码来自于后台,绘制完成后发现只能在微信开发工具上显示,在真机(本人手机)上只能显示文本,图片为空白。多次测试后发现网络图片都无法在真机上绘制出来。
首先看下设计图,知道具体做的是什么样的: ——–
——
具体就是在微信小程序商品详情页上添加一个分享按钮,点击按钮后将商品图片、描述、价格以及二维码绘制成一张图显示出来(项目中是详情页和首页两种图片)。利用微信小程序自带功能,长按可以将图片保存、分享、收藏、识别二维码。
接下来上代码,代码不齐全,主要是本人开发过程中用到的代码。(因为公司开发所用的是wepy小程序框架,所以代码写法上与原生小程序代码略有不同。需要的朋友请自行转行,重在理解这个过程。)
1.这个是wxml部分的代码。样式代码这里就不上了。
<view class="share" @tap="share"> 分享</view> //点击分享按钮,调用事件“share”<canvas canvas-id=’share’ style=’width:750px;height:920px;’ hidden=’{{canvasHidden}}’><canvas>
分享按钮点击的时候触发“share”方法,随后“share”方法里的getGoodEwm方式执行。
注意:
1.canvas-id 一定要设置,后面要用的上。
2.style里的宽高要用上,不设置宽高画板会失效。
3.canvasHidden是控制画板显示隐藏的参数,画板直接设置display none,会导致失效。
2.script部分。
Data{//画布 canvasHidden:true, //设置画板的显示与隐藏,画板不隐藏会影响页面正常显示 shareImgPath: '' //用于储存canvas生成的图片}
自定义方法:
这里是getGoodEwm方法。需要注意的是因为二维码和商品图片都是后台获取的网络图片,所以一定要先获取二维码图片地址,在通过“wx.getImageInfo”方法获取图片信息,接着是商品图片的的信息获取(因为商品图片的api地址获取写在其他方法里,这里就不显示了,原理与二维码获取相同)只有在两张图片都获取到以后才能开始绘图,否则绘制不出图片。
注意代码后的注释
//二维码获取 async getGoodEwm() { let that = this; let storeId = wepy.getStorageSync(STORE_ID) || {}; let storeSkuSn = that.detail.storeSkuSn; const json = await api.getGoodEwm({ query: { storeId : storeId, storeSkuSn : storeSkuSn } }); //以上代码是后台获取二维码的方法,不是本问的重点。实际实验中可以把二维码图片地址用网络图片地址代替,也能实验效果 console.log(json.data) if (json.data.code == 'success') { //这句表示如果二维码图片内容获取成功 wx.showLoading({ //因为整个图片获取过程需要一定时间,所以添加一个提示框提醒用户 title: '努力生成中...' }) wx.getImageInfo({ //获取二维码图片信息 src: json.data.data, success:function(res){ console.log("------------- succ -----------") console.log(res) wx.getImageInfo({ //二维码图片信息获取成功后,获取商品图片信息 src: that.detail.imgList[0], //因为后台中商品图片有多张,数据是一个数组,所以这里只获取第一张。也可以用网络图片地址代替。 success:function(e){ console.log("------------- succ -----------") console.log(e) console.log(res) that.drawImg(e,res) //两张图片都获取成功后,调用绘图方法,注意传递过去的参数区别,不要混淆 }, fail:function(e){ console.log("------------- fail -----------") console.log(e) }, complete:function(e) { console.log("------------- complete -----------") console.log(e) } }); }, fail:function(res){ console.log("------------- fail -----------") console.log(res) }, complete:function(res) { console.log("------------- complete -----------") console.log(res) } }); } else { tip.error(json.data.errorMsg) console.log('失败') } that.$apply();}
//绘图 drawImg(e,res) { let that=this; that.canvasHidden=false //设置画板显示,才能开始绘图 var img=e.path //商品图片保存地址 var img1=res.path //二维码图片保存地址 var name=this.detail.name //图片描述,描述和下面的价格都是从后台获取的内容,可以随意换成其他文本内容,这里不是重点所以就不讲内容的获取方法了 var price=this.detail.price //图片价格 let context = wx.createCanvasContext('share') //这里的“share”是“canvas-id” context.setFillStyle('#fff') //这里是绘制白底,让图片有白色的背景 context.fillRect(0, 0, 750, 920) context.drawImage(img, 30, 30, 690, 690) //绘制商品图片 context.setFontSize(28) context.setFillStyle("#393939") context.fillText(name, 30, 796) //绘制描述 context.setFontSize(32) context.setFillStyle("#f31115") context.fillText('¥'+price, 30, 870) //绘制价格 context.drawImage(img1, 576, 750, 144, 144) //绘制二维码图片 //把画板内容绘制成图片,并回调画板图片路径 context.draw(false, function () { wx.canvasToTempFilePath({ x: 0, y: 0, width: 750, height: 920, destWidth: 750, destHeight: 920, canvasId: 'share', success:a=>{ that.shareImgPath=a.tempFilePath, //将绘制的图片地址保存在shareImgPath 中 that.canvasHidden=true //设置画板隐藏,否则影响界面显示 that.$apply(); //更改data的值 等同于小程序原生代码的setData console.log(that.data.shareImgPath) wx.previewImage({ //将图片预览出来 urls: [that.data.shareImgPath] }) wx.hideLoading() //图片已经绘制出来,隐藏提示框 }, fail:e=>{console.log('失败')} }) }) }
Methods={//分享事件 share() { this.getGoodEwm(); }}
解释下代码:
分享按钮点击的时候触发“share”方法,随后“share”方法里的getGoodEwm方式执行。需要注意的是因为二维码和商品图片都是后台获取的网络图片,所以一定要先获取二维码图片地址,在通过“wx.getImageInfo”方法获取图片信息,接着是商品图片的的信息获取(因为商品图片的api地址获取写在其他方法里,这里就不显示了,原理与二维码获取相同)只有在两张图片都获取到以后才能开始绘图,否则绘制不出图片。
Canvas绘图的方法可以去看小程序官方文档,对着代码看一次就能够理解了。图片绘制出来后将地址保存在data的“shareImgPath”中,之后调用“wx.previewImage”方法将图片预览出来。长按图片就会自动调用微信小程序原生功能:保存、收藏等。
其实整个项目的重点在于怎么把网络图片绘制出来,如果是本地图片的话其实会少很多步骤,但是网络图片就一定要先采用wx.getImageInfo()方法将图片保存下来,在调用绘制。项目中因为图片是后台获取的,所以多了调用api获取后台图片。