近期使用微信小程序制作海报,为了减少各位同学们少走弯路,记录一下吧。
首先我们需要了解一个知识点canvas,另一个知识点,在使用网络图片绘制海报的时候,canvas是不能显示的,这个时候我们就需要使用小程序的API了,
两种方式,第一:wx.getImageInfo获取图片信息,根据临时的path进行绘制,第二种就是通过wx.downloadFile先下载再进行绘制,这里我选第一种方式。
我们在绘制的时候会遇到兼容性问题,这个时候我们就要使用微信小程序的另一个方法wx.getSystemInfo获取手机的基本信息,根据不同分辨率的手机
计算出不同的尺寸比例,然后再绘制图片文字所有海报的信息,最后我们使用wx.canvasToTempFilePath和wx.saveImageToPhotosAlbum将canvas
转化成图片保存在本地。
废话不多说,直接上代码
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
bgImage: 'https://******/*.img',
cardImage: '',
userImage: '',
codeImage: '',
name: '示例员工',
job: '员工',
company: '公司名称',
remark: 'TT·全球版',
sub: '长按识别二维码',
type: 'user',
title: '',
card_id: ''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log('oooo', options);
wx.showLoading({
title: '海报生成中',
mask: true,
});
if (options.type == 'case' || options.type == 'product') {
this.setData({
remark: options.name.length > 6 ? options.name.substring(0, 6)+'...' : options.name
})
}
let cardInfo = app.data.card_info;
console.log(cardInfo);
this.data.name = cardInfo.card_name;
this.data.job = cardInfo.job;
this.data.company = cardInfo.company;
this.data.userImage = cardInfo.circular_avatar;
this.data.type = options.type;
this.data.card_id = cardInfo.id;
this.data.title = options.title;
if (options.type) {
this.data.cardImage = options.img;
} else {
this.data.cardImage = cardInfo.card_image;
}
this.bgImg();
},
async bgImg() {
await this.getImage(this.data.bgImage).then(rs => {
this.data.bgImage = rs.path;
});
await this.getImage(this.data.cardImage).then(rs => {
this.data.cardImage = rs.path;
});
await this.getImage(this.data.userImage).then(rs => {
this.data.userImage = rs.path;
});
await this.getCodeImage().then(rs => {
if (rs.code === 200) {
this.getImage(rs.data).then(rs => {
this.data.codeImage = rs.path;
this.drawImag();
});
} else {
app.my_showToast(rs.msg);
console.log(5)
}
});
},
getImage(url) { //获取图片
return new Promise((resolve) => {
wx.getImageInfo({
src: url,
success: function (res) {
resolve(res);
}
})
})
},
getCodeImage() { //获取二维码
return new Promise((resolve) => {
app.ajax({
url: '/***/***/getCode',
data: {
cardId: this.data.card_id,
page: 'pages/business_card/business_card'
},
method: 'POST'
}).then(rs => {
resolve(rs);
})
})
},
drawImag() {
const ctx = wx.createCanvasContext('canvas');
wx.getSystemInfo({
success: (result) => {
let rateW = result.windowWidth / 375;
ctx.drawImage(this.data.bgImage, 0, 0, result.screenWidth, result.screenHeight * 0.9);
ctx.drawImage(this.data.userImage, 145 * rateW, 10 * rateW, 90 * rateW, 90 * rateW);
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
if (!this.data.type) {
ctx.setFillStyle('#687dc7');
ctx.setFontSize(14);
ctx.fillText('这是我的名片,请您收下,谢谢!', 200 * rateW, 180 * rateW);
ctx.drawImage(this.data.cardImage, 45 * rateW, 200 * rateW, 290 * rateW, 180 * rateW);
ctx.drawImage(this.data.codeImage, 220 * rateW, 390 * rateW, 100 * rateW, 100 * rateW);
} else if (this.data.type == "company") {
ctx.fillStyle = "#f4f4f4";
ctx.fillRect(85 * rateW, 170 * rateW, 200 * rateW, 200 * rateW);
ctx.setFillStyle('#5b5b5b');
let title = this.data.title;
title = title > 10 ? `${title.substring(0,9)}...` : title;
ctx.setFontSize(16);
ctx.fillText(title, 190 * rateW, 355 * rateW);
ctx.drawImage(this.data.cardImage, 95 * rateW, 180 * rateW, 180 * rateW, 160 * rateW);
ctx.drawImage(this.data.codeImage, 140 * rateW, 380 * rateW, 100 * rateW, 100 * rateW);
ctx.setFontSize(16);
ctx.fillText('长按识别二维码', 190 * rateW, 500 * rateW);
} else {
ctx.drawImage(this.data.cardImage, 45 * rateW, 180 * rateW, 290 * rateW, 180 * rateW);
ctx.drawImage(this.data.codeImage, 220 * rateW, 390 * rateW, 100 * rateW, 100 * rateW);
}
ctx.setFontSize(16);
ctx.setFillStyle('#4462bd');
ctx.fillText(this.data.name, 180 * rateW, 120 * rateW)
ctx.setFontSize(12);
ctx.setFillStyle('#666');
ctx.fillText(this.data.job, 240 * rateW, 120 * rateW)
ctx.setFillStyle('#666');
ctx.fillText(this.data.company, 200 * rateW, 140 * rateW);
if (this.data.type == "product" || this.data.type == "case") {
ctx.setFillStyle('#333');
ctx.setFontSize(16)
ctx.fillText(this.data.remark, 100 * rateW, 420 * rateW)
ctx.setFontSize(14)
ctx.setFillStyle('#b1b1b1');
ctx.fillText(this.data.sub, 110 * rateW, 450 * rateW)
} else if (this.data.type == "company") {
} else {
ctx.setFillStyle('#333');
ctx.setFontSize(16)
this.data.remark = "长按或";
this.data.sub = "扫一扫了解TA"
ctx.fillText(this.data.remark, 85 * rateW, 420 * rateW)
ctx.fillText(this.data.sub, 110 * rateW, 450 * rateW)
}
ctx.stroke();
ctx.draw();
wx.hideLoading();
},
});
},
saveImage() {
wx.canvasToTempFilePath({
canvasId: 'canvas',
success: function (res) {
if (res.errMsg === "canvasToTempFilePath:ok") {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success() {
wx.hideLoading();
wx.showToast({
title: '保存成功',
icon: 'success'
})
wx.previewImage({
current: '',
urls: [res.tempFilePath]
})
},
fail(err) {
wx.hideLoading();
wx.showToast({
title: '保存失败',
icon: 'none'
})
}
})
} else {
wx.showToast({
title: '保存失败',
icon: 'none'
})
}
},
fail: function (res) {
wx.showToast({
title: '保存失败',
icon: 'none'
})
}
});
},
//检查授权
saveImageToPhotosAlbum() {
const that = this;
wx.getSetting({
success(res) {
//第一次点击保存,是进入下载逻辑,会自动弹框确认
if (res.authSetting['scope.writePhotosAlbum'] || typeof res.authSetting['scope.writePhotosAlbum'] === 'undefined') {
//执行下载
that.saveImage()
} else {
//如果点击过取消,之后就进入设置页面
//打开检查权限
wx.openSetting()
}
},
})
}
})