本人大四实习新入职,在入职一个星期后接触到了第一个项目。
因为是新手,在整个开发过程中遇到了较多的难点:主要是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获取后台图片。