微信小程序
canvas
生成海报
带参数小程序码
canvas基本绘图其实是很简单的。不少人写海报的插件,写的一大堆,感觉好厉害的样子。实际没必要,几行代码就可以搞定的事情。
效果

保存海报后,可通过微信识别图中小程序。因为小程序不能分享到朋友圈,所以只能通过生成海报,才能发表在朋友圈。
主要过程:通过cavas把2张网络图片(绘图)合成为一张图片。本地图片没试过,可能也行。海报背景图片是固定不变的,所以地址可以写死。小程序码图片,是后台根据用户id生成的,是带参数的小程序码!所以每个用户生成的小程序码(图片)是不同的。当别人打开你分享的海报之后,可以识别出你是谁,进而统计分享人信息。
不太清除canvas是否可以展示在页面上,从网上看别人写的是通过坐标把canvas移出屏幕外;但canvas似乎不占用文档流的空间。我是直接用image来显示绘制好的图片,有兴趣的同学可以试试用canvas看看能不能直接显示。
代码里的wx.showLoading等提示性功能已经去掉,为了对用户更友好,需自己在合适的位置添加。
.js
data: {
bgImageUrl: 'https://...47F258D2BA.jpg', //海报背景图片,固定地址的网络图片
qrCodeUrl: "",
imagePath_bg: undefined, //wx.getImageInfo转化的图片地址;cavas不能直接用网络地址。
imagePath_qrcode: undefined, ////wx.getImageInfo转化的图片地址 ;网络动态请求,小程序码网络图片
tempSavedImageURL: '', //cavas绘制图片临时保存路径
//注意,背景图片时固定大小600x1067,所以canvasStyle宽高比例必须也一致!否则画出来的图片会有多余的一片空白。
canvasStyle: 'width: 600px;height:1067px;position: fixed;top: -10000px;',
},
onLoad: function (options) {
this.ctx = wx.createCanvasContext('myCanvas', this);
//创建ctx耗时较长,延时500毫秒再请求url
setTimeout(res => {
this.requestMyIQRCodeUrl()
}, 500)
},
获取2张图片url,并通过 wx.getImageInfo转化为本地路径。
//获取小程序码url
requestMyIQRCodeUrl: function() {
let that = this;
......
that.data.qrCodeUrl = urlStr;
that.draw_try()
}
draw_try: function (e) {
let urlStr = this.data.qrCodeUrl;
if (urlStr == '' || urlStr == undefined) {
return;
}
let that = this;
// 背景图片
wx.getImageInfo({
src: that.data.bgImageUrl,
success: function (sres) {
that.data.imagePath_bg = sres.path;
that.drawCanvasCxt_try()
},
fail: function (err) {
},
})
// 小程序码图片
wx.getImageInfo({
src: urlStr,
success: function (sres) {
that.data.imagePath_qrcode = sres.path;
that.drawCanvasCxt_try()
},
fail: function (err) {
},
})
},
drawCanvasCxt_try: function () {
//异步调2次此方法;需获取到2张图片特殊路径canvas才能开始绘图
if (this.data.imagePath_bg != undefined && this.data.imagePath_qrcode != undefined) {
this.drawCanvasCxt(this.data.imagePath_bg, this.data.imagePath_qrcode)
}
},
canvas开始绘图
drawCanvasCxt: function (imagePath_bg, imagePath_qrcode) {
const res = wx.getSystemInfoSync();
const platform = res.platform;
let time = 0;
if (platform === 'android') {
// 在安卓平台,经测试发现如果海报过于复杂在转换时需要做延时,要不然样式会错乱
time = 300;
}
//绘制背景图片,大小跟cavas一致。单位是px。如果是本地图片,不要搞太高清,毕竟小程序限制打包后<2M。
this.ctx.drawImage(imagePath_bg, 0, 0, 600, 1067)
//算出小程序码相对于背景海报的坐标。可以写个大概再根据效果慢慢调整
this.ctx.drawImage(imagePath_qrcode, 377, 796, 180, 180)
let that = this;
//开始渲染
this.ctx.draw(false, () => {
setTimeout(() => {
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success: function (res) {
let url = res.tempFilePath
console.log('url=' + url)
that.setData({//绘制完毕,显示到image对象上。
tempSavedImageURL: url // 返回的图片地址保存到一个全局变量里
})
},
fail: function (失败) {
},
complete: function () {
}
});
}, time);
});
},
点击按钮,保存图片到手机相册
saveImage_try: function () {
let urlStr = this.data.tempSavedImageURL;
if (urlStr == '' || urlStr == undefined) {
return;
}
let that = this;
wx.getSetting({
success(res) {
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
that.saveImage_do();
},
fail(err) {
//用户拒绝了授权,无法弹出,
wx.navigateTo({
url: './instrument/instrumentPage', //授权说明,提示页面。让用户去授权。
})
}
})
}else {
that.saveImage_do();
}
}
})
},
saveImage_do: function (e) {
let urlStr = this.data.tempSavedImageURL;
if (urlStr == '' || urlStr == undefined) {
return;
}
wx.saveImageToPhotosAlbum({
filePath: urlStr,
success: function (fres) {
},
fail: function (err) {
},
})
},
.wxml
<canvas canvas-id="myCanvas" style="{{canvasStyle}}"></canvas>
<view class='whiteContent'>
<image src='{{tempSavedImageURL}}' mode='aspectFit' style='height:100%;width:100%'></image>
</view>
<view class='bottom'>
<view style='width:100%;height:2rpx;background-color:#aaaaaa'></view>
<view class='saveBtn_ugly' bindtap='savBtnClick'>
<image class='icon' src='/img/personalCenter/iv_icon_download.png'></image>
<text>保存至手机</text>
</view>
</view>
附注:
因为识别小程序码,打开的小程序必然是线上正式版本!!所以无法真机测试这一识别过程!所以只能在开发环境里面去测试(如下菜单,通过二维码编译;选择保存的电脑中的海报(带小程序码)。)

在识别小程序码(或二维码),打开小程序在第一个页面,拿到附带的参数(参数由后台定):
onLoad: function (options) {
var scene = decodeURIComponent(options.scene)//识别用户分享的带参数的二维码,会得到用户端 customerId
console.log('-----------------------scene:' + scene)//如果不是用户分享的带参数的二维码,为undefined
}
网友评论