对于小程序开发者来说,为用户提供一种方便、高效的分享图片功能具有重要意义。使用Canvas元素,我们可以为小程序生成并处理分享图片,满足用户的个性化需求。本文将详细介绍如何使用Canvas生成分享图片。
使用插件: montage.js
安装
npm i montage.js
使用
生成的图片基本由 图片/文字 组成,在使用此插件的时候只需定义好图片/文字节点,即可生成分享图片
关于节点配置项可查看相关说明:npm
代码示例
- 创建画布
<canvas id='share'></canvas>
- 初始化
// 引入
import Flowfrom 'montage.js'
// 初始化节点
let shareDom = document.getElementById('share');
let transform = 2; // 定义缩放比例,用来防止导出后图片失真,第四步会用到
let width = 370; // 画布宽度
let height = 570; // 画布高度
let draw = new Flow({
width: width * transform, // 传入画布宽高
height: height * transform,
}, shareDom);
- 定义节点数组
用于定义文字、图片的 位置/宽高
const shareNodes = [{
type: 'rect', // 白色背景(不然导出的图片背景是透明的)
x: 0,
y: 0,
width: 370,
height: 570,
fillColor: 'white',
fillType: 'fill',
level: 0
}, {
type: 'rect', // 自定义节点
x: 0,
y: 0,
width: 370,
height: 60,
fillColor: 'rgba(0, 0, 0, 0)',
textInfo: {
text: 'TITLE',
fontSize: 20,
}
}, {
type: 'image', // 图片节点
x: 35,
y: 60,
width: 300,
height: 380,
fillColor: 'rgb(214, 213, 213)',
lineWidth: 1,
textInfo: {
text: 'picture',
fontSize: 23,
},
src: 'pic url'
}, {
type: 'rect',
x: 35,
y: 455,
width: 200,
height: 100,
fillColor: 'rgba(0, 0, 0, 0)',
textInfo: {
text: '文字说明/n文字说明 文字说明 ... ...', // 使用 /n 进行换行
fontSize: 11,
}
}, {
type: "image",
x: 235,
y: 455,
width: 100,
height: 100,
textInfo: {
text: 'picture',
fontSize: 23,
},
src: 'pic url'
}]
- 渲染节点
注意:当我们直接将节点以原比例导出时,导出后的图片会很模糊,为了防止导出后的图片失真,应首先在渲染时固定画布宽高,再将节点原本的宽高都放大一个特定的倍数后进行渲染
例如:当我们在一块 10 * 10 的画布中导出一张 10 * 10 的图片,为了防止模糊,导出时应将图片宽高 * 2,这样导出后的图片会有很好的清晰度
以下给出了两种方式去实现节点的渲染,建议使用第二种
// ****** 第一种方式:直接导出,此时导出后的图片清晰度会很低 ******
for (let i of shareNodes) {
share.addNode(i); // 调用 addNode 方法添加节点至画布
}
// ****** 第二种方式:将画布dom宽高固定,将元素宽高放大 *******
// 相比于第一种,相当于在 10 * 10 的画布中放入了一张 20 * 20 的画布,此时导出的图片不会模糊
// 固定画布dom宽高
shareDom.style.width = width + "px";
shareDom.style.height = height + "px";
for (let i of shareNodes) {
// 自动将宽/高/字体等属性放大
setProp(i)
share.addNode(i);
}
const setProp = (obj) => {
Object.keys(obj).forEach((prop) => {
if (typeof obj[prop] === "number") {
obj[prop] = obj[prop] * transform;
} else if (typeof obj[prop] === "object") {
setProp(obj[prop]);
}
});
};
- 导出
// 创建一个a标签,并点击
let download = document.createElement("a");
document.body.appendChild(a);
download.href = document.getElementById("share").toDataURL();
download.download = "share.png";
download.click();
document.body.removeChild(download);
导出后的图片效果
实际可根据 UI 去设置每个节点的大小/位置,以及显示的图片/文字等信息
关于节点配置项可查看相关说明:npm
更多示例可见:gitee仓库(如果对你有帮助能否帮我点颗星星✨,在此谢过各位~)