近期使用微信小程序制作海报,为了减少各位同学们少走弯路,记录一下吧。
首先我们需要了解一个知识点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()
}
},
})
}
})