小程序的canvas绘图绝对是整个小程序开发中坑最多的了 。
先上效果图:
实现步骤就是点击生成图片 在canvas画布中画出一张海报 然后保存在本地 在imags标签中展示,此处尽可能的把canvas组件隐藏 但是不能用wx:if。 用hidden或者display属性
<button bindtap='gotoSubmit'>生成图片</button>
<!-- 弹框 -->
<view class='tankuang2' wx:if="{{showhaibao}}">
<view class='container1' bindtap="previewImg">
<image style="width:100%;height:80%" src="{{imagePath}}" ></image>
</view>
</view>
<canvas style="width:{{windowW}}px;height:{{windowH}}px;display:{{maskHidden?'none':''}}" canvas-id="mycanvas" />
css不做说明直接上代码
button{
width: 100%;
position: fixed;
z-index: 1;
bottom:0;
}
.tankuang2{
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.6);
z-index: 999999;
position: absolute;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
}
.tankuang2 .container1{
height: 90%;
width: 90%;
background-color:#FFF;
}
第一大坑
我在js中注释的代码很重要,实际开发中绘制商品海报必然是用网络图片,但经过多次尝试网络图片是不可以直接绘制在canvas画布上的,就必须要把他缓存下来,弄一个本地路径,此处我用本地图片所以就注释了
第二大坑
经过多次测试发现当你第一次点击生成图片的时候,它会生成一张透明的图片,根本看不到,必须要点击两次,就是调用两次生成图片的方法才可以看到生成的图片,我这里为了只让他点击一次就生成图片,在小程序生命周期函数onReady先调用一次 初始化一下图片。
好了以下就是具体代码
Page({
data: {
showhaibao:false,//隐藏显示
maskHidden: true,//隐藏显示
},
onLoad: function(options) {
// 此处获取设备的宽高。canvas绘制的图片以次宽高为准
var _this = this;
wx.getSystemInfo({
success: function(res) {
console.log(res)
_this.setData({
windowW: res.windowWidth ,
windowH: res.screenHeight,
})
},
})
// wx.downloadFile({
// url: 网络图片地址必须要在小程序中配备合法域名,
// success: function (res1) {
// console.log(res1.tempFilePath)
// //缓存商品图片
// _this.setData({
// img1: res2.tempFilePath
// })
// }
// })
// wx.downloadFile({
// url: 网络图片地址必须要在小程序中配备合法域名,
// success: function (res1) {
// console.log(res1.tempFilePath)
// //缓存二维码图片
// _this.setData({
// img2: res2.tempFilePath
// })
// }
// })
},
onReady: function() {
// 页面渲染完成
this.createNewImg();
//创建初始化图片
},
//将金额绘制到canvas的固定
setMoney: function(context) {
var money ='¥29.9'
context.setFontSize(24);
context.setFillStyle("red");
context.fillText(money, 40, 360);
context.stroke();
},
//将说明绘制到canvas固定
setSuoming :function(context){
var Suoming="长按识别小程序码访问"
context.setFontSize(18);
context.setFillStyle("#484a3d");
context.fillText(Suoming, 15, 460);
context.stroke();
},
//将说明2绘制到canvas固定
setSuoming1: function (context) {
var Suoming = "子谦出品"
context.setFontSize(18);
context.setFillStyle("#484a3d");
context.fillText(Suoming, 50, 510);
context.stroke();
},
//将标题绘制到canvas的固定
setName: function(context) {
var name = "ONLY2018夏季新款蕾丝短袖连衣裙"
context.setFontSize(15);
context.setFillStyle("#67695b");
context.fillText(name, 40, 320);
context.stroke();
},
//将canvas转换为图片保存到本地,然后将图片路径传给image图片的src
createNewImg: function() {
var _this = this;
var context = wx.createCanvasContext("mycanvas");
context.setFillStyle('#FFF')
console.log(this.data.windowW, this.data.windowH)
context.fillRect(0, 0, this.data.windowW, this.data.windowH)
var path = "这里放你的本地图片路径,或者网络图片缓存在本地的路径"; //详细看onLoad函数注释部分
context.drawImage(path, 30, 20, 300, 250); //这里是商品图片
this.setSuoming(context);
this.setName(context);
this.setMoney(context);
this.setSuoming1(context);
context.drawImage(path, 205, 430, 150, 150);//这里是二维码图片
context.draw(_this.getImg())
},
//将生成好的图片保存到本地 下面这句注释是文档中的原话。
// tip: 在 draw 回调里调用canvasToTempFilePath方法才能保证图片导出成功。
getImg() {
var _this = this;
wx.canvasToTempFilePath({
canvasId: 'mycanvas',
success: function success(res) {
_this.setData({
imagePath: res.tempFilePath,
});
}
});
},
//点击图片进行预览,长按保存分享图片
previewImg: function(e) {
var img = this.data.imagePath
wx.previewImage({
current:img, // 当前显示图片的http链接
urls: [img] // 需要预览的图片http链接列表
})
},
gotoSubmit: function(e) {
var _this=this
this.setData({
maskHidden:false,
showhaibao:true
})
wx.showToast({
title: '图片生成中...',
icon: 'loading',
duration: 2000
});
setTimeout(function() {
wx.hideToast()
_this.createNewImg();
}, 2000)
}
})
以上就是canvas绘制商品海报的全部代码。希望能帮助到大家 ,有不懂的或者更好的方法,欢迎大家留言或者提问