记录一下微信小程序使用canvas绘制名片功能,绘制海报、分享页等也可以使用
这里使用的是旧版canvas的方法,这里生成的时候,使用pc客户端看着生成的图片是没有问题的,但是真机上生成的是有白边的(如下图左侧跟下方都是透明的边
),苹果手机没有看到,另外一个文章用新版的canvas绘制了一个,是没有这个问题的
wxml
canvasToTempFilePath是显示canvas转换后的临时图片地址
<canvas canvas-id="myCanvas" style="height: 364rpx;width:640rpx;position: fixed;top: -10000px;"></canvas>
<image style="height: 364rpx;width:640rpx;margin: 0 auto;" src="{{canvasToTempFilePath}}"></image>
<button bindtap="saveImg">下载</button>
js
var ctx = null, // 创建canvas对象
canvasToTempFilePath = null, // canvas转换后的临时图片地址
openStatus = true; // 声明一个全局变量判断是否授权保存到相册
Page({
/**
* 页面的初始数据
*/
data: {
colorIndex: 0,
userInfo: {
name: "",
phone: "13333333333",
wx: "18888888888",
email: "88888888@qq.com",
company: "发个广告",
position: "公司老总",
userPhoto: "xxxxx",
wxCodeImg: "xxxxxxx",
},
},
// 生成海报
async createCanvasImage() {
let { userInfo } = this.data;
let that = this;
// 点击生成海报数据埋点
if (!ctx) {
// wx.showLoading({
// title: '海报生成中,请稍等...'
// })
let bg = new Promise(function (resolve) {
wx.getImageInfo({
src: `xxxxxxxxxx`,
success: function (res) {
resolve(res.path);
},
fail: function (err) {
console.log(err);
wx.showToast({
title: "网络错误请重试",
icon: "loading",
});
},
});
});
let headImg = new Promise(function (resolve) {
wx.getImageInfo({
src: userInfo.userPhoto,
success: function (res) {
resolve(res.path);
},
fail: function (err) {
console.log(err);
wx.showToast({
title: "网络错误请重试",
icon: "loading",
});
},
});
});
let wxCodeImg = new Promise(function (resolve) {
wx.getImageInfo({
src: userInfo.wxCodeImg,
success: function (res) {
resolve(res.path);
},
fail: function (err) {
console.log(err);
wx.showToast({
title: "网络错误请重试",
icon: "loading",
});
},
});
});
// 使用Promise请求图片地址,响应成功后再去绘制图片,图片加载有延迟,会导致绘制完文字再去绘制图片,这样就盖住文字了
Promise.all([bg, headImg, wxCodeImg]).then(function (result) {
const ctx = wx.createCanvasContext("myCanvas");
console.log(ctx, "ctx");
let headImg_width = 107, //绘制的头像宽度
headImg_heigth = 107, //绘制的头像高度
headImg_x = 28, //绘制的头像在画布上的位置
headImg_y = 48; //绘制的头像在画布上的位置
// ctx.drawImage(result[0], 0, 0, 640, 364);
// ctx.drawImage('图片文件', 'x轴位置', 'y轴位置', '宽度', '高度')
ctx.drawImage(result[0], 0, 0, 320, 182);
ctx.drawImage(result[2], 260, 10, 50, 50);
ctx.save(); // 先保存状态 已便于画完圆再用
ctx.beginPath(); //开始绘制
//先画个圆,前两个参数确定了圆心 (x,y) 坐标 第三个参数是圆的半径 四参数是绘图方向 默认是false,即顺时针
ctx.arc(
headImg_width / 2 + headImg_x,
headImg_heigth / 2 + headImg_y,
headImg_width / 2,
0,
Math.PI * 2,
false
);
ctx.clip(); //画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
ctx.drawImage(
result[1],
headImg_x,
headImg_y,
headImg_width,
headImg_heigth
); // 推进去图片
ctx.restore(); //恢复之前保存的绘图上下文状态 可以继续绘制
ctx.setFillStyle("#fff"); // 文字颜色
ctx.setFontSize(15); // 文字字号
ctx.fillText(userInfo.name, 183, 74); // 绘制文字
ctx.setFillStyle("#fff"); // 文字颜色
ctx.setFontSize(10); // 文字字号
ctx.fillText(userInfo.position, 183, 90); // 绘制文字
ctx.setFillStyle("#fff"); // 文字颜色
ctx.setFontSize(8); // 文字字号
ctx.fillText(userInfo.company, 183, 111); // 绘制文字
ctx.setFillStyle("#fff"); // 文字颜色
ctx.setFontSize(8); // 文字字号
ctx.fillText(userInfo.phone, 183, 128); // 绘制文字
ctx.setFillStyle("#fff"); // 文字颜色
ctx.setFontSize(8); // 文字字号
ctx.fillText(userInfo.wx, 183, 146); // 绘制文字
ctx.setFillStyle("#fff"); // 文字颜色
ctx.setFontSize(8); // 文字字号
ctx.fillText(userInfo.email, 183, 161); // 绘制文字
ctx.setFillStyle("#fff"); // 文字颜色
ctx.setFontSize(8); // 文字字号
ctx.fillText("截图扫码", 270, 70); // 绘制文字
ctx.draw(false, function () {
// canvas画布转成图片并返回图片地址
wx.canvasToTempFilePath({
canvasId: "myCanvas",
success: function (res) {
console.log(res, 123456);
canvasToTempFilePath = res.tempFilePath;
that.setData({
showShareImg: true,
canvasToTempFilePath,
});
console.log(res.tempFilePath, "canvasToTempFilePath");
wx.showToast({
title: "绘制成功",
});
},
fail: function () {
wx.showToast({
title: "绘制失败",
});
},
complete: function () {
// wx.hideLoading()
wx.hideToast();
},
});
});
});
}
},
// 保存到系统相册
saveImg: function () {
let that = this;
// 获取用户是否开启用户授权相册
if (!openStatus) {
wx.openSetting({
success: (result) => {
if (result) {
if (result.authSetting["scope.writePhotosAlbum"] === true) {
openStatus = true;
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
that.setData({
showShareImg: false,
});
wx.showToast({
title: "图片保存成功",
icon: "none",
duration: 2000,
});
},
fail() {
wx.showToast({
title: "保存失败",
icon: "none",
});
},
});
}
}
},
fail: () => {},
complete: () => {},
});
} else {
wx.getSetting({
success(res) {
// 如果没有则获取授权
if (!res.authSetting["scope.writePhotosAlbum"]) {
wx.authorize({
scope: "scope.writePhotosAlbum",
success() {
openStatus = true;
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
that.setData({
showShareImg: false,
});
wx.showToast({
title: "图片保存成功",
icon: "none",
duration: 2000,
});
},
fail() {
wx.showToast({
title: "保存失败",
icon: "none",
});
},
});
},
fail() {
// 如果用户拒绝过或没有授权,则再次打开授权窗口
openStatus = false;
console.log("请设置允许访问相册");
wx.showToast({
title: "请设置允许访问相册",
icon: "none",
});
},
});
} else {
// 有则直接保存
openStatus = true;
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
that.setData({
showShareImg: false,
});
wx.showToast({
title: "图片保存成功",
icon: "none",
duration: 2000,
});
},
fail() {
wx.showToast({
title: "保存失败",
icon: "none",
});
},
});
}
},
fail(err) {
console.log(err);
},
});
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.createCanvasImage();
},
});